diff options
| author | Egor Tensin <egor@tensin.name> | 2026-05-17 20:49:38 +0200 |
|---|---|---|
| committer | Egor Tensin <egor@tensin.name> | 2026-05-17 20:49:38 +0200 |
| commit | 8e4823763e8e25f1be9d8d6cd21b3cf2ac56a00e (patch) | |
| tree | a33f781a4476bb7c5c7bc157ea4ea75eb5eeb6b7 | |
| parent | workflows: add Python black linting job (diff) | |
| download | cgitize-8e4823763e8e25f1be9d8d6cd21b3cf2ac56a00e.tar.gz cgitize-8e4823763e8e25f1be9d8d6cd21b3cf2ac56a00e.zip | |
reformat everything for fun
| -rw-r--r-- | cgitize/bitbucket.py | 4 | ||||
| -rw-r--r-- | cgitize/cgit.py | 28 | ||||
| -rw-r--r-- | cgitize/config.py | 16 | ||||
| -rw-r--r-- | cgitize/git.py | 25 | ||||
| -rw-r--r-- | cgitize/main.py | 39 | ||||
| -rw-r--r-- | cgitize/repo.py | 58 | ||||
| -rw-r--r-- | cgitize/utils.py | 8 | ||||
| -rwxr-xr-x | docker/get_output_dir.py | 3 | ||||
| -rw-r--r-- | test/unit/test_bitbucket.py | 32 | ||||
| -rw-r--r-- | test/unit/test_gitlab.py | 12 |
10 files changed, 165 insertions, 60 deletions
diff --git a/cgitize/bitbucket.py b/cgitize/bitbucket.py index 5c55a2a..f3cc4d4 100644 --- a/cgitize/bitbucket.py +++ b/cgitize/bitbucket.py @@ -19,7 +19,9 @@ class Bitbucket: try: parts = repo.id.split('/') if len(parts) != 2: - raise ValueError(f'repository ID must be in the USER/NAME format: {repo.id}') + raise ValueError( + f'repository ID must be in the USER/NAME format: {repo.id}' + ) user, name = parts return self._impl.repositories.get(user, name) except HTTPError: diff --git a/cgitize/cgit.py b/cgitize/cgit.py index 8c8a8ca..7691c61 100644 --- a/cgitize/cgit.py +++ b/cgitize/cgit.py @@ -70,9 +70,17 @@ class AgeFile: # Except I think that the committer date, not author date better # represents activity. with chdir(repo_dir): - success, output = Git.capture('for-each-ref', '--sort=-committerdate', '--count=1', '--format=%(committerdate:iso8601)') + success, output = Git.capture( + 'for-each-ref', + '--sort=-committerdate', + '--count=1', + '--format=%(committerdate:iso8601)', + ) if not success: - logging.error("Couldn't get the timestamp of the newest commit in repository: %s", repo_dir) + logging.error( + "Couldn't get the timestamp of the newest commit in repository: %s", + repo_dir, + ) return None return output @@ -118,7 +126,10 @@ class CGitRepositories: success, output = Git.capture('rev-parse', '--is-inside-work-tree') if not success: # Overwrite the existing directory if it's not a Git repository. - logging.warning('Local directory is not a repository, going to overwrite it: %s', repo_dir) + logging.warning( + 'Local directory is not a repository, going to overwrite it: %s', + repo_dir, + ) return self._mirror(repo) success, output = Git.capture('config', '--get', 'remote.origin.url') @@ -126,14 +137,21 @@ class CGitRepositories: # Every repository managed by this script should have the # 'origin' remote. If it doesn't, it's trash. Overwrite the # existing directory, mirroring the repository in it. - logging.warning("Local repository doesn't have remote 'origin', going to overwrite it: %s", repo_dir) + logging.warning( + "Local repository doesn't have remote 'origin', going to overwrite it: %s", + repo_dir, + ) return self._mirror(repo) if f'{repo.clone_url}\n' != output: # Jeez, there's a proper local repository in the target # directory already with a different upstream; something's # wrong, fix it manually. - logging.warning("Existing repository '%s' doesn't match the specified clone URL: %s", repo.name, repo.clone_url) + logging.warning( + "Existing repository '%s' doesn't match the specified clone URL: %s", + repo.name, + repo.clone_url, + ) if self.force: # Unless --force was specified, in which case we overwrite # the repository. diff --git a/cgitize/config.py b/cgitize/config.py index 4de7701..0e5fe6e 100644 --- a/cgitize/config.py +++ b/cgitize/config.py @@ -41,7 +41,9 @@ class MainSection(Section): @property def output_dir(self): - return self._get_config_path('output_dir', default=MainSection.DEFAULT_OUTPUT_DIR) + return self._get_config_path( + 'output_dir', default=MainSection.DEFAULT_OUTPUT_DIR + ) @property def error_header_path(self): @@ -126,7 +128,9 @@ class GitHubSection(ServiceSection): username = self.username token = self.token if (username is None) != (token is None): - raise RuntimeError('please set either both the GitHub username & token, or neither') + raise RuntimeError( + 'please set either both the GitHub username & token, or neither' + ) return GitHub(username, token) @@ -153,7 +157,9 @@ class BitbucketSection(ServiceSection): username = self.username token = self.token if (username is None) != (token is None): - raise RuntimeError('please set either both the Bitbucket username & token, or neither') + raise RuntimeError( + 'please set either both the Bitbucket username & token, or neither' + ) return Bitbucket(username, token) @@ -174,7 +180,9 @@ class GitLabSection(ServiceSection): username = self.username token = self.token if (username is None) != (token is None): - raise RuntimeError('please set either both the GitLab username & token, or neither') + raise RuntimeError( + 'please set either both the GitLab username & token, or neither' + ) return GitLab(token) diff --git a/cgitize/git.py b/cgitize/git.py index 5ee3177..aba1f2b 100644 --- a/cgitize/git.py +++ b/cgitize/git.py @@ -8,9 +8,10 @@ import os from cgitize import utils - GIT_ENV = os.environ.copy() -GIT_ENV['GIT_SSH_COMMAND'] = 'ssh -oBatchMode=yes -oLogLevel=QUIET -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null' +GIT_ENV['GIT_SSH_COMMAND'] = ( + 'ssh -oBatchMode=yes -oLogLevel=QUIET -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null' +) class Config: @@ -55,7 +56,9 @@ class Config: for c in name: if c.isalnum() or c == '-' or c == '.': continue - raise RuntimeError(f'section names must only contain alphanumeric characters, . or -: {name}') + raise RuntimeError( + f'section names must only contain alphanumeric characters, . or -: {name}' + ) @staticmethod def format_name(name): @@ -89,7 +92,9 @@ class Config: return f'"{name}"' def format(self): - result = f'[{Config.Section.format_name(self.section)} {self.format_name()}]\n' + result = ( + f'[{Config.Section.format_name(self.section)} {self.format_name()}]\n' + ) result += ''.join((var.format() for var in self.variables)) return result @@ -107,9 +112,13 @@ class Config: for c in name: if c.isalnum() or c == '-': continue - raise RuntimeError(f'variable name can only contain alphanumeric characters or -: {name}') + raise RuntimeError( + f'variable name can only contain alphanumeric characters or -: {name}' + ) if not name[0].isalnum(): - raise RuntimeError(f'variable name must start with an alphanumeric character: {name}') + raise RuntimeError( + f'variable name must start with an alphanumeric character: {name}' + ) @staticmethod def validate_value(value): @@ -161,7 +170,9 @@ class Git: with utils.protected_file(config.path): with config.backup() as old_contents: variables = [Config.Variable('insteadOf', repo.clone_url)] - subsection = Config.Subsection('url', repo.clone_url_with_auth, variables) + subsection = Config.Subsection( + 'url', repo.clone_url_with_auth, variables + ) new_contents = f'{old_contents}\n{subsection.format()}' config.write(new_contents) yield diff --git a/cgitize/main.py b/cgitize/main.py index 8e1f638..1d7245a 100644 --- a/cgitize/main.py +++ b/cgitize/main.py @@ -17,18 +17,25 @@ def parse_args(argv=None): if argv is None: argv = sys.argv[1:] parser = ArgumentParser() - parser.add_argument('--config', '-c', metavar='PATH', - default=Config.DEFAULT_PATH, - help='config file path') - parser.add_argument('--repo', metavar='REPO_ID', - nargs='*', dest='repos', - help='repos to pull') - parser.add_argument('--force', '-f', action='store_true', - help='overwrite existing repositories') - parser.add_argument('--verbose', '-v', action='store_true', - help='verbose log output') - parser.add_argument('--version', '-V', action='version', - version=f'%(prog)s {__version__}') + parser.add_argument( + '--config', + '-c', + metavar='PATH', + default=Config.DEFAULT_PATH, + help='config file path', + ) + parser.add_argument( + '--repo', metavar='REPO_ID', nargs='*', dest='repos', help='repos to pull' + ) + parser.add_argument( + '--force', '-f', action='store_true', help='overwrite existing repositories' + ) + parser.add_argument( + '--verbose', '-v', action='store_true', help='verbose log output' + ) + parser.add_argument( + '--version', '-V', action='version', version=f'%(prog)s {__version__}' + ) return parser.parse_args(argv) @@ -36,7 +43,9 @@ def setup_error_header_file(error_header_path, success, error=None): with open(error_header_path, 'w') as file: contents = '' if not success: - contents = '''<p style="text-align: center; color: red; font-weight: bold;">''' + contents = ( + '''<p style="text-align: center; color: red; font-weight: bold;">''' + ) contents += '''Some repositories couldn't be updated, please check application logs for details.''' if error is not None: contents += f'''<br>{type(error).__name__}: {error}''' @@ -53,7 +62,9 @@ def main(argv=None): try: cgit_server = CGitServer(config.main.clone_url) - output = CGitRepositories(config.main.output_dir, cgit_server, force=args.force) + output = CGitRepositories( + config.main.output_dir, cgit_server, force=args.force + ) for repo in config.parse_repositories(): if args.repos is None or repo.name in args.repos: success = success and output.update(repo) diff --git a/cgitize/repo.py b/cgitize/repo.py index 23a2b31..cabc7ba 100644 --- a/cgitize/repo.py +++ b/cgitize/repo.py @@ -21,8 +21,9 @@ class Repo: raise ValueError("every repository must have 'clone_url'") clone_url = src['clone_url'] subdir = src.get('dir') - return Repo(name, clone_url, owner=owner, desc=desc, homepage=homepage, - subdir=subdir) + return Repo( + name, clone_url, owner=owner, desc=desc, homepage=homepage, subdir=subdir + ) @staticmethod def from_github(src, config, subdir=None): @@ -36,8 +37,15 @@ class Repo: clone_url = ssh_url if config.main.clone_via_ssh else https_url url_auth = None if config.main.clone_via_ssh else config.github.url_auth - return Repo(name, clone_url, owner=owner, desc=desc, homepage=homepage, - url_auth=url_auth, subdir=subdir) + return Repo( + name, + clone_url, + owner=owner, + desc=desc, + homepage=homepage, + url_auth=url_auth, + subdir=subdir, + ) @staticmethod def from_bitbucket(src, config, subdir=None): @@ -46,13 +54,17 @@ class Repo: homepage = src.get_link('html') owner = src.data['owner']['display_name'] - https_urls = [link for link in src.data['links']['clone'] if link['name'] == 'https'] + https_urls = [ + link for link in src.data['links']['clone'] if link['name'] == 'https' + ] if len(https_urls) != 1: raise RuntimeError(f"no https:// clone URL for repository '{name}'?!") # Bitbucket leaves the username in the URL... Sigh. https_url = url_remove_auth(https_urls[0]['href']) - ssh_urls = [link for link in src.data['links']['clone'] if link ['name'] == 'ssh'] + ssh_urls = [ + link for link in src.data['links']['clone'] if link['name'] == 'ssh' + ] if len(ssh_urls) != 1: raise RuntimeError(f"no ssh:// clone URL for repository '{name}'?!") ssh_url = ssh_urls[0]['href'] @@ -60,8 +72,15 @@ class Repo: clone_url = ssh_url if config.main.clone_via_ssh else https_url url_auth = None if config.main.clone_via_ssh else config.bitbucket.url_auth - return Repo(name, clone_url, owner=owner, desc=desc, homepage=homepage, - url_auth=url_auth, subdir=subdir) + return Repo( + name, + clone_url, + owner=owner, + desc=desc, + homepage=homepage, + url_auth=url_auth, + subdir=subdir, + ) @staticmethod def from_gitlab(src, config, subdir=None): @@ -75,11 +94,26 @@ class Repo: clone_url = ssh_url if config.main.clone_via_ssh else https_url url_auth = None if config.main.clone_via_ssh else config.gitlab.url_auth - return Repo(name, clone_url, owner=owner, desc=desc, homepage=homepage, - url_auth=url_auth, subdir=subdir) + return Repo( + name, + clone_url, + owner=owner, + desc=desc, + homepage=homepage, + url_auth=url_auth, + subdir=subdir, + ) - def __init__(self, name, clone_url, owner=None, desc=None, homepage=None, - url_auth=None, subdir=None): + def __init__( + self, + name, + clone_url, + owner=None, + desc=None, + homepage=None, + url_auth=None, + subdir=None, + ): self._name = name self._desc = desc self._homepage = homepage diff --git a/cgitize/utils.py b/cgitize/utils.py index c3a4fff..dd27f14 100644 --- a/cgitize/utils.py +++ b/cgitize/utils.py @@ -21,7 +21,8 @@ def setup_logging(verbose=False): format='%(asctime)s | %(levelname)s | %(message)s', # Log to stdout, because that's where subprocess's output goes (so that # the don't get interleaved). - stream=sys.stdout) + stream=sys.stdout, + ) try: yield except Exception as e: @@ -37,8 +38,9 @@ def run(*args, capture_output=False, **kwargs): stderr = subprocess.STDOUT logging.debug('%s', args) - result = subprocess.run(args, check=True, stdout=stdout, stderr=stderr, - encoding='utf-8', **kwargs) + result = subprocess.run( + args, check=True, stdout=stdout, stderr=stderr, encoding='utf-8', **kwargs + ) if result.stdout is not None: logging.debug('\n%s', result.stdout) diff --git a/docker/get_output_dir.py b/docker/get_output_dir.py index 5ca0055..ff0d35a 100755 --- a/docker/get_output_dir.py +++ b/docker/get_output_dir.py @@ -10,8 +10,7 @@ def parse_args(argv=None): if argv is None: argv = sys.argv[1:] parser = ArgumentParser() - parser.add_argument('config', metavar='PATH', - help='config file path') + parser.add_argument('config', metavar='PATH', help='config file path') return parser.parse_args(argv) diff --git a/test/unit/test_bitbucket.py b/test/unit/test_bitbucket.py index efb325d..221fa79 100644 --- a/test/unit/test_bitbucket.py +++ b/test/unit/test_bitbucket.py @@ -15,7 +15,8 @@ class BitbucketTests(unittest.TestCase): self.bitbucket = Cloud( username=os.environ.get('CGITIZE_BITBUCKET_USERNAME'), password=os.environ.get('CGITIZE_BITBUCKET_TOKEN'), - cloud=True) + cloud=True, + ) def test_nonexistent_repo(self): with self.assertRaises(HTTPError): @@ -29,15 +30,24 @@ class BitbucketTests(unittest.TestCase): self.assertEqual(r.data['workspace']['name'], 'Test cgitize workspace') self.assertEqual(r.data['workspace']['slug'], 'cgitize-test-workspace') - self.assertEqual(r.get_link('html'), 'https://bitbucket.org/cgitize-test-workspace/public') + self.assertEqual( + r.get_link('html'), 'https://bitbucket.org/cgitize-test-workspace/public' + ) - clone_urls = [link for link in r.data['links']['clone'] if link['name'] == 'https'] + clone_urls = [ + link for link in r.data['links']['clone'] if link['name'] == 'https' + ] self.assertEqual(len(clone_urls), 1) - self.assertEqual(clone_urls[0]['href'], 'https://cgitize-test@bitbucket.org/cgitize-test-workspace/public.git') + self.assertEqual( + clone_urls[0]['href'], + 'https://cgitize-test@bitbucket.org/cgitize-test-workspace/public.git', + ) ssh_urls = [link for link in r.data['links']['clone'] if link['name'] == 'ssh'] self.assertEqual(len(ssh_urls), 1) - self.assertEqual(ssh_urls[0]['href'], 'git@bitbucket.org:cgitize-test-workspace/public.git') + self.assertEqual( + ssh_urls[0]['href'], 'git@bitbucket.org:cgitize-test-workspace/public.git' + ) def test_private_repo(self): r = self.bitbucket.repositories.get('cgitize-test-workspace', 'private') @@ -47,12 +57,18 @@ class BitbucketTests(unittest.TestCase): self.assertEqual(r.data['workspace']['name'], 'Test cgitize workspace') self.assertEqual(r.data['workspace']['slug'], 'cgitize-test-workspace') - self.assertEqual(r.get_link('html'), 'https://bitbucket.org/cgitize-test-workspace/private') + self.assertEqual( + r.get_link('html'), 'https://bitbucket.org/cgitize-test-workspace/private' + ) def test_user(self): w = self.bitbucket.workspaces.get('cgitize-test-workspace') - self.assertEqual(len([r for r in w.repositories.each() if r.name == 'public']), 1) - self.assertEqual(len([r for r in w.repositories.each() if r.name == 'private']), 1) + self.assertEqual( + len([r for r in w.repositories.each() if r.name == 'public']), 1 + ) + self.assertEqual( + len([r for r in w.repositories.each() if r.name == 'private']), 1 + ) class BitbucketTestPrivateRepo(unittest.TestCase): diff --git a/test/unit/test_gitlab.py b/test/unit/test_gitlab.py index 7243dbd..08eb808 100644 --- a/test/unit/test_gitlab.py +++ b/test/unit/test_gitlab.py @@ -13,8 +13,8 @@ from gitlab.exceptions import GitlabGetError class GitLabTests(unittest.TestCase): def setUp(self): self.gitlab = Gitlab( - 'https://gitlab.com', - private_token=os.environ.get('CGITIZE_GITLAB_TOKEN')) + 'https://gitlab.com', private_token=os.environ.get('CGITIZE_GITLAB_TOKEN') + ) def test_nonexistent_repo(self): with self.assertRaises(GitlabGetError): @@ -27,7 +27,9 @@ class GitLabTests(unittest.TestCase): self.assertEqual(r.namespace['name'], 'Test cgitize user') self.assertEqual(r.namespace['path'], 'cgitize-test') self.assertEqual(r.web_url, 'https://gitlab.com/cgitize-test/public') - self.assertEqual(r.http_url_to_repo, 'https://gitlab.com/cgitize-test/public.git') + self.assertEqual( + r.http_url_to_repo, 'https://gitlab.com/cgitize-test/public.git' + ) self.assertEqual(r.ssh_url_to_repo, 'git@gitlab.com:cgitize-test/public.git') def test_private_repo(self): @@ -37,7 +39,9 @@ class GitLabTests(unittest.TestCase): self.assertEqual(r.namespace['name'], 'Test cgitize user') self.assertEqual(r.namespace['path'], 'cgitize-test') self.assertEqual(r.web_url, 'https://gitlab.com/cgitize-test/private') - self.assertEqual(r.http_url_to_repo, 'https://gitlab.com/cgitize-test/private.git') + self.assertEqual( + r.http_url_to_repo, 'https://gitlab.com/cgitize-test/private.git' + ) self.assertEqual(r.ssh_url_to_repo, 'git@gitlab.com:cgitize-test/private.git') def test_user(self): |
