From 98d3bb27f08135a49722ff8702dbf551b18267b5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 22 Jun 2023 21:35:59 +0000 Subject: [PATCH] gerrit_client: changes: support raw search queries The --param option does not support extended bool logic. It forces every search query to be AND-ed together. There is no way to do more OR joins or subclauses like "( X OR Y ) AND Z". Let's add a new --query option to let people type out the full string themselves rather than try and support this bool logic directly. Bug: b/282975918 Test: ./gerrit_client.py changes --host https://chromium-review.googlesource.com --query '( owner:vapier OR owner:briannorris ) is:open project:chromiumos/chromite' Change-Id: I792e4deec34797295824ec13da41f45eb85e65ae Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4638081 Reviewed-by: Greg Edelston Commit-Queue: Gavin Mak Reviewed-by: Gavin Mak Auto-Submit: Mike Frysinger --- gerrit_client.py | 13 +++++++--- tests/gerrit_client_test.py | 51 +++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/gerrit_client.py b/gerrit_client.py index cd7e139e4..9bda02556 100755 --- a/gerrit_client.py +++ b/gerrit_client.py @@ -203,8 +203,13 @@ def CMDheadinfo(parser, args): @subcommand.usage('[args ...]') def CMDchanges(parser, args): """Queries gerrit for matching changes.""" - parser.add_option('-p', '--param', dest='params', action='append', + parser.add_option('-p', + '--param', + dest='params', + action='append', + default=[], help='repeatable query parameter, format: -p key=value') + parser.add_option('--query', help='raw gerrit search query string') parser.add_option('-o', '--o-param', dest='o_params', action='append', help='gerrit output parameters, e.g. ALL_REVISIONS') parser.add_option('--limit', dest='limit', type=int, @@ -214,14 +219,16 @@ def CMDchanges(parser, args): '(starting with the most recent)') (opt, args) = parser.parse_args(args) + assert opt.params or opt.query, '--param or --query required' for p in opt.params: assert '=' in p, '--param is key=value, not "%s"' % p result = gerrit_util.QueryChanges( urlparse.urlparse(opt.host).netloc, list(tuple(p.split('=', 1)) for p in opt.params), - start=opt.start, # Default: None - limit=opt.limit, # Default: None + first_param=opt.query, + start=opt.start, # Default: None + limit=opt.limit, # Default: None o_params=opt.o_params, # Default: None ) logging.info('Change query returned %d changes.', len(result)) diff --git a/tests/gerrit_client_test.py b/tests/gerrit_client_test.py index 9cabc9c2b..4ad4a2b2e 100755 --- a/tests/gerrit_client_test.py +++ b/tests/gerrit_client_test.py @@ -50,11 +50,52 @@ class TestGerritClient(unittest.TestCase): 'changes', '--host', 'https://example.org/foo', '-p', 'foo=bar', '-p', 'baz=qux', '--limit', '10', '--start', '20', '-o', 'op1', '-o', 'op2' ]) - util_mock.assert_called_once_with( - 'example.org', [('foo', 'bar'), ('baz', 'qux')], - limit=10, - start=20, - o_params=['op1', 'op2']) + util_mock.assert_called_once_with('example.org', [('foo', 'bar'), + ('baz', 'qux')], + first_param=None, + limit=10, + start=20, + o_params=['op1', 'op2']) + + @mock.patch('gerrit_util.QueryChanges', return_value='') + def test_changes_query(self, util_mock): + gerrit_client.main([ + 'changes', + '--host', + 'https://example.org/foo', + '--query', + 'is:owner is:open', + '--limit', + '10', + '--start', + '20', + ]) + util_mock.assert_called_once_with('example.org', [], + first_param='is:owner is:open', + limit=10, + start=20, + o_params=None) + + @mock.patch('gerrit_util.QueryChanges', return_value='') + def test_changes_params_query(self, util_mock): + gerrit_client.main([ + 'changes', + '--host', + 'https://example.org/foo', + '--query', + 'is:owner is:open', + '-p', + 'foo=bar', + '--limit', + '10', + '--start', + '20', + ]) + util_mock.assert_called_once_with('example.org', [('foo', 'bar')], + first_param='is:owner is:open', + limit=10, + start=20, + o_params=None) @mock.patch('gerrit_util.GetRelatedChanges', return_value='') def test_relatedchanges(self, util_mock):