From 89e34eb68d5a01eb11c09974391b83348850338a Mon Sep 17 00:00:00 2001 From: mprahl Date: Nov 08 2018 13:19:59 +0000 Subject: Add the ability to pass in buildrequire and require overrides on a module build Signed-off-by: mprahl --- diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py index 7615e42..6877e80 100644 --- a/pyrpkg/__init__.py +++ b/pyrpkg/__init__.py @@ -3478,9 +3478,9 @@ class Commands(object): return resp def module_submit_build(self, scm_url, branch, auth_method, - optional=None, oidc_id_provider=None, - oidc_client_id=None, oidc_client_secret=None, - oidc_scopes=None): + buildrequires=None, requires=None, optional=None, + oidc_id_provider=None, oidc_client_id=None, + oidc_client_secret=None, oidc_scopes=None): """ Submit a module build to the MBS @@ -3488,6 +3488,10 @@ class Commands(object): :param branch: a string of the module's branch :param str auth_method: a string of the authentication method used by the MBS. + :param list buildrequires: a list of buildrequires in the format of + 'name:stream' to override. + :param list requires: a list of requires in the format of 'name:stream' + to override. :param optional: an optional list of "key=value" to be passed in with the MBS build submission. :type optional: list[str] @@ -3514,10 +3518,22 @@ class Commands(object): raise rpkgError( 'Optional arguments are not in the proper "key=value" format') + for dep_type, overrides in (('buildrequires', buildrequires), + ('requires', requires)): + for override in overrides or []: + dep_name, dep_stream = override + # Get the override key that MBS accepts (e.g. + # buildrequire_overrides) + key = '{0}_overrides'.format(dep_type[:-1]) + body.setdefault(key, {}) + body[key].setdefault(dep_name, []) + body[key][dep_name].append(dep_stream) + conflicting_keys = set(body.keys()) & set(optional_dict.keys()) if conflicting_keys: raise rpkgError('The following optional arguments conflict with other arguments: {0}' .format(', '.join(conflicting_keys))) + body.update(optional_dict) url = self.module_get_url(build_id=None, action='POST') resp = self.module_send_authorized_request( diff --git a/pyrpkg/cli.py b/pyrpkg/cli.py index b0553d6..fb22b94 100644 --- a/pyrpkg/cli.py +++ b/pyrpkg/cli.py @@ -1082,6 +1082,14 @@ defined, packages will be built sequentially.""" % {'name': self.name}) '--watch', '-w', help='Watch the module build', action='store_true') self.module_build_parser.add_argument( + '--buildrequires', action='append', metavar='name:stream', + dest='buildrequires', type=utils.validate_module_dep_override, + help='Buildrequires to override in the form of "name:stream"') + self.module_build_parser.add_argument( + '--requires', action='append', metavar='name:stream', + dest='requires', type=utils.validate_module_dep_override, + help='Requires to override in the form of "name:stream"') + self.module_build_parser.add_argument( '--optional', action='append', metavar='KEY=VALUE', dest='optional', help='MBS optional arguments in the form of "key=value"') @@ -1972,8 +1980,9 @@ see API KEY section of copr-cli(1) man page. if not self.args.q: print('Submitting the module build...') build_ids = self._cmd.module_submit_build( - scm_url, branch, auth_method, self.args.optional, - oidc_id_provider, oidc_client_id, oidc_client_secret, oidc_scopes) + scm_url, branch, auth_method, self.args.buildrequires, + self.args.requires, self.args.optional, oidc_id_provider, + oidc_client_id, oidc_client_secret, oidc_scopes) if self.args.watch: self.module_watch_build(build_ids) elif not self.args.q: diff --git a/pyrpkg/utils.py b/pyrpkg/utils.py index 2ce469f..aa96254 100644 --- a/pyrpkg/utils.py +++ b/pyrpkg/utils.py @@ -105,3 +105,11 @@ def find_me(): cmd += ['--config', args.config] return cmd + + +def validate_module_dep_override(dep): + """Validate the passed-in module dependency override.""" + try: + return dep.split(':', 1) + except (ValueError, AttributeError): + raise argparse.ArgumentTypeError('This option must be in the format of "name:stream"') diff --git a/tests/test_cli.py b/tests/test_cli.py index 8ffd040..2e638cf 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2073,6 +2073,39 @@ class TestModulesCli(CliTestCase): self.assertEqual(output, expected_output) @patch('requests.get') + @patch('openidc_client.OpenIDCClient.send_request') + def test_module_build_dep_overrides(self, mock_oidc_req, mock_get): + """ + Test a module build with buildrequire and require overrides + """ + cli_cmd = [ + 'rpkg', + '--path', self.cloned_repo_path, + 'module-build', + 'git://pkgs.fedoraproject.org/modules/testmodule?#79d87a5a', + 'master', + '--buildrequires', 'platform:f28', + '--buildrequires', 'platform:f29', + '--requires', 'platform:f29' + ] + mock_get.return_value.ok = True + mock_get.return_value.json.return_value = { + 'auth_method': 'oidc', + 'api_version': 2 + } + mock_oidc_req.return_value.json.return_value = [ + {'id': 1094}, {'id': 1095}, {'id': 1096}] + + with patch('sys.argv', new=cli_cmd): + cli = self.new_cli() + cli.module_build() + + brs = mock_oidc_req.call_args[1]['json']['buildrequire_overrides'] + assert set(brs['platform']) == set(['f28', 'f29']) + reqs = mock_oidc_req.call_args[1]['json']['require_overrides'] + assert reqs['platform'] == ['f29'] + + @patch('requests.get') def test_module_build_conflicting_keys(self, mock_get): """ Test a module build with optional arguments the conflict with other arguments