From 9c328538a23f3b9b9d4dad76e8df87d47493d462 Mon Sep 17 00:00:00 2001 From: Charlie Liu Date: Tue, 13 Nov 2018 00:06:30 -0500 Subject: [PATCH] Add gitshelf as a format and fetch certain repos This adds support for gitshelf as a format for a list of repositories. This also adds support for fetching only repos that are listed in a list of repositories, as specified by --import-repos and --format. Closes https://github.com/ksdme/org-status/issues/6 and https://github.com/ksdme/org-status/issues/29 --- org_status/decoders/__init__.py | 15 +++++++++++++ org_status/decoders/gitman.py | 20 ++++++++++++++++++ org_status/decoders/gitshelf.py | 20 ++++++++++++++++++ org_status/encoders/__init__.py | 2 ++ org_status/encoders/gitshelf.py | 19 +++++++++++++++++ org_status/org_status.py | 37 ++++++++++++++++++++++++++++++--- 6 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 org_status/decoders/__init__.py create mode 100644 org_status/decoders/gitman.py create mode 100644 org_status/decoders/gitshelf.py create mode 100644 org_status/encoders/gitshelf.py diff --git a/org_status/decoders/__init__.py b/org_status/decoders/__init__.py new file mode 100644 index 0000000..1d99499 --- /dev/null +++ b/org_status/decoders/__init__.py @@ -0,0 +1,15 @@ +class RepoListDecoder: + NAME = None + + def convert_format_to_repo_list(self, file_name): + raise NotImplementedError() + + +def get_all_supported_decoders(): + from org_status.decoders.gitman import GitManDecoder + from org_status.decoders.gitshelf import GitShelfDecoder + + return ( + GitManDecoder, + GitShelfDecoder, + ) diff --git a/org_status/decoders/gitman.py b/org_status/decoders/gitman.py new file mode 100644 index 0000000..8bd5bdb --- /dev/null +++ b/org_status/decoders/gitman.py @@ -0,0 +1,20 @@ +import yaml + +from org_status.decoders import RepoListDecoder + + +class GitManDecoder(RepoListDecoder): + NAME = 'gitman' + + def convert_format_to_repo_list(self, file_name): + repos = [] + + try: + with open(file_name, 'r') as file: + yml_data = yaml.load(file) + + for repo in yml_data['sources']: + repos.append(repo['name']) + return repos + except FileNotFoundError: + print(f'unable to find file {file_name}') diff --git a/org_status/decoders/gitshelf.py b/org_status/decoders/gitshelf.py new file mode 100644 index 0000000..ac35f77 --- /dev/null +++ b/org_status/decoders/gitshelf.py @@ -0,0 +1,20 @@ +import yaml + +from org_status.decoders import RepoListDecoder + + +class GitShelfDecoder(RepoListDecoder): + NAME = 'gitshelf' + + def convert_format_to_repo_list(self, file_name): + repos = [] + + try: + with open(file_name, 'r') as file: + yml_data = yaml.load(file) + + for repo in yml_data['books']: + repos.append(repo['book']) + return repos + except FileNotFoundError: + print(f'unable to find file {file_name}') diff --git a/org_status/encoders/__init__.py b/org_status/encoders/__init__.py index 1879851..57e1687 100644 --- a/org_status/encoders/__init__.py +++ b/org_status/encoders/__init__.py @@ -7,7 +7,9 @@ def convert_repo_list_to_format(self, repos): def get_all_supported_encoders(): from org_status.encoders.gitman import GitManEncoder + from org_status.encoders.gitshelf import GitShelfEncoder return ( GitManEncoder, + GitShelfEncoder, ) diff --git a/org_status/encoders/gitshelf.py b/org_status/encoders/gitshelf.py new file mode 100644 index 0000000..92a7da2 --- /dev/null +++ b/org_status/encoders/gitshelf.py @@ -0,0 +1,19 @@ +import yaml +from giturlparse import parse + +from encoders import RepoListEncoder + + +class GitShelfEncoder(RepoListEncoder): + NAME = 'gitshelf' + + def convert_repo_list_to_format(self, repos): + yml_data = {'books': []} + + for repo in repos: + name = parse(repo.web_url).repo + yml_data['books'].append({'book': name, + 'git': repo.web_url, + 'branch': 'master'}) + + return yaml.dump(yml_data, default_flow_style=False) diff --git a/org_status/org_status.py b/org_status/org_status.py index a9e6f52..b6d2c13 100644 --- a/org_status/org_status.py +++ b/org_status/org_status.py @@ -7,6 +7,7 @@ from org_status.status_providers import Status, get_supported_status_providers from org_status.org_hosts import get_all_supported_hosts from org_status.encoders import get_all_supported_encoders +from org_status.decoders import get_all_supported_decoders def get_host_token(host_name): @@ -84,6 +85,7 @@ def get_argument_parser(): parser.add_argument('--verbose', '-v', action='store_true') parser.add_argument('--hosts-only', '-o', action='store_true') parser.add_argument('--skip-host-checks', action='store_true') + parser.add_argument('--import-repos', type=str) parser.add_argument('--export-repos', type=str) parser.add_argument('--format', type=str, default='gitman') parser.add_argument('--check-providers-only', action='store_true') @@ -100,14 +102,31 @@ def encode_repo_list(repo_data, encoder_name, styled): try: encoded_repo_list = encoder().convert_repo_list_to_format( repo_data) + return encoded_repo_list except NotImplementedError: print(styled( f'{encoder_name} does not support exporting results', 'red')) - else: - print(styled(f'unknown export format {encoder_name}', 'red')) - return encoded_repo_list + print(styled(f'unknown export format {encoder_name}', 'red')) + + +def decode_repo_list(file_name, decoder_name, styled): + decoders = get_all_supported_decoders() + decoded_repo_list = None + + for decoder in decoders: + if decoder.NAME == decoder_name: + try: + decoded_repo_list = decoder().convert_format_to_repo_list( + file_name) + return decoded_repo_list + except NotImplementedError: + print(styled( + f'{decoder_name} does not support exporting results', + 'red')) + + print(styled(f'unknown export format {decoder_name}', 'red')) def write_data_to_file(encoded_data, filename, styled, verbose): @@ -195,6 +214,18 @@ def main(): all_repositories += org_host.repositories continue + if args.import_repos: + repos = decode_repo_list(args.import_repos, args.format, styled) + repos_to_remove = [] + + for repo in org_host.repositories: + repo_name = repo.full_name.split('/')[-1] + if repo_name not in repos: + repos_to_remove.append(repo) + + for repo in repos_to_remove: + org_host.repositories.remove(repo) + org_status = aggregate_org_status(org_host, threads=args.threads) present_status(org_status, args.no_color)