From b1109117c7d5e16dace23bbce7887eebf8d2506e Mon Sep 17 00:00:00 2001 From: Jose Luis Rivero Date: Mon, 1 Apr 2024 16:54:12 +0200 Subject: [PATCH] Implement the distribution requirement to repo installation Signed-off-by: Jose Luis Rivero --- plugins/config/_test_repository.yaml | 12 +++++-- plugins/repository.py | 53 +++++++++++++++++++++------- plugins/repository_TEST.py | 51 ++++++++++++++++++++++---- 3 files changed, 96 insertions(+), 20 deletions(-) diff --git a/plugins/config/_test_repository.yaml b/plugins/config/_test_repository.yaml index e168531..ea742f9 100644 --- a/plugins/config/_test_repository.yaml +++ b/plugins/config/_test_repository.yaml @@ -27,11 +27,19 @@ projects: - name: osrf type: stable - name: ignition-transport7 + distributions: + ubuntu: + - no-existing-distro repositories: - name: osrf - type: stable + type: broken + - name: ignition-transport7 + distributions: + ubuntu: + - jammy + repositories: - name: osrf - type: prerelease + type: stable - name: ignition-.* repositories: - name: osrf diff --git a/plugins/repository.py b/plugins/repository.py index 5164edb..5ba8837 100644 --- a/plugins/repository.py +++ b/plugins/repository.py @@ -68,18 +68,30 @@ def load_config_file(config_file_path='config/repository.yaml'): exit(-1) -def load_project(project, config): - ret = [] +def get_first_valid_project_config(project, config, linux_distro): + """Returns the project configuration from yaml that correspond + to the first match while searching starting from top to bottom + """ for p in config['projects']: pattern = re.compile(p['name']) + if pattern.search(project): - ret = p['repositories'] - break + # project name found, check that requirements are met + try: + # 1. If distribution requirement exists check it + if linux_distro in p['distributions'][distro.id()]: + return p + except KeyError as kerror: + # 2. No disitribution requirement set + if 'distributions' in str(kerror): + return p + assert f"Unexpected keyerror: #{str(kerror)}" - if not ret: - error('Unknown project: ' + project) + return None - return ret + +def get_repositories_config(project_config): + return project_config['repositories'] def get_linux_distro(): @@ -159,8 +171,8 @@ def run_apt_update(): _check_call(['apt-get', 'update']) -def install_repos(project_list, config, linux_distro, gpg_check): - for p in project_list: +def install_repos(repos_list, config, linux_distro, gpg_check): + for p in repos_list: install_repo(p['name'], p['type'], config, linux_distro, gpg_check) @@ -207,7 +219,7 @@ def normalize_args(args): if force_linux_distro: linux_distro = force_linux_distro else: - linux_distro = None + linux_distro = distro.codename() if '--keyserver' in args: warn('--keyserver option is deprecated. It is safe to remove it') return action, repo_name, repo_type, project, linux_distro, gpg_check @@ -220,14 +232,31 @@ def validate_input(args): error('Unknown action: ' + args.action) +def process_project_install(project, config, linux_distro, gpg_check, + dry_run=False): + project_config = get_first_valid_project_config(project, config, linux_distro) + if not project_config: + error('Unknown project: ' + project) + + if not dry_run: # useful for tests + install_repos(get_repositories_config(project_config), + config, + linux_distro, + gpg_check) + + def process_input(args, config): action, repo_name, repo_type, project, linux_distro, gpg_check = args if (action == 'enable'): if project: - project_list = load_project(project, config) - install_repos(project_list, config, linux_distro, gpg_check) + # project dependant installation + process_project_install(project, + config, + linux_distro, + gpg_check) else: + # generic repository installation install_repo(repo_name, repo_type, config, diff --git a/plugins/repository_TEST.py b/plugins/repository_TEST.py index 26bef76..1cf39d8 100644 --- a/plugins/repository_TEST.py +++ b/plugins/repository_TEST.py @@ -59,21 +59,60 @@ def test_no_type(self): class TestProjectNameResolution(TestBase): def test_direct_match(self): - projects = repository.load_project('ignition-math6', self.config) - for p in projects: + project_config = \ + repository.get_first_valid_project_config('ignition-math6', + self.config, + 'jammy') + for p in repository.get_repositories_config(project_config): self.assertEqual(p['name'], 'osrf') self.assertEqual(p['type'], 'stable') def test_non_exist(self): - with self.assertRaises(SystemExit): - repository.load_project('fooooo', self.config) + self.assertIsNone( + repository.get_first_valid_project_config('fooooo', + self.config, + 'jammy')) def test_regexp(self): - projects = repository.load_project('ignition-plugin', self.config) - for p in projects: + project_config = \ + repository.get_first_valid_project_config('ignition-plugin', + self.config, + 'jammy') + for p in repository.get_repositories_config(project_config): self.assertEqual(p['name'], 'osrf') self.assertEqual(p['type'], 'regexp') + def test_precedence(self): + project_config = \ + repository.get_first_valid_project_config('ignition-transport7', + self.config, + 'jammy') + for p in repository.get_repositories_config(project_config): + self.assertEqual(p['name'], 'osrf') + self.assertEqual(p['type'], 'stable') + + +class TestProjectInstall(TestBase): + + def test_no_distributions(self): + repository.process_project_install('ignition-math6', + self.config, + 'jammy', + dry_run=True) + + def test_distributions(self): + repository.process_project_install('ignition-transport7', + self.config, + 'jammy', + dry_run=True) + + def test_non_exist(self): + with self.assertRaises(SystemExit): + repository.process_project_install('fooooo', + self.config, + 'jammy', + dry_run=True) + if __name__ == '__main__': unittest.main()