From 10db30e920024724e6d7409dc505b7306025e259 Mon Sep 17 00:00:00 2001 From: Dai Boruta Date: Wed, 1 Jul 2020 12:35:14 +0200 Subject: [PATCH 1/2] Allow overriding Git user info for catalog commits This commit introduces new arguments for `commodore catalog compile` for overriding local Git user information when pushing commits to a cluster catalog. By default Commodore will use the local Git user information for catalog commits. To improve compatibility with existing Git configurations, the arguments are named `--git-author-name` and `--git-author-email` to pick up the familiar `GIT_AUTHOR_NAME` and `GIT_AUTHOR_EMAIL` environment variables without any further configuration. Please note: Commodore does not allow you to override commit author and committer separately, and will use the provided author name and email, if any, as both commit author and committer. The commit also updates docker-compose.yaml to map `~/.gitconfig` into the container to propagate the global Git config into the container. This simplifies reusing the Git author configuration on the host system when running Commodore locally using docker-compose. Resolves #63 --- README.md | 4 ++++ commodore/catalog.py | 4 ++-- commodore/cli.py | 9 ++++++++- commodore/compile.py | 6 ++++-- commodore/component/template.py | 2 +- commodore/config.py | 6 +++++- commodore/dependency_mgmt.py | 6 ++++-- commodore/git.py | 15 +++++++++++---- docker-compose.yaml | 1 + tests/test_git.py | 2 +- 10 files changed, 41 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9c0cf97a..dc01f54e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,10 @@ using `helm template`. COMMODORE_GLOBAL_GIT_BASE=ssh://git@github.com/projectsyn # Your local user ID to be used in the container (optional, defaults to root) USER_ID= + # Your username to be used in the commits (optional, defaults to your local git config) + COMMODORE_USERNAME= + # Your user email to be used in the commits (optional, defaults to your local git config) + COMMODORE_USERMAIL= ``` For Commodore to work, you need to run an instance of the diff --git a/commodore/catalog.py b/commodore/catalog.py index ff388c54..e12fdd3e 100644 --- a/commodore/catalog.py +++ b/commodore/catalog.py @@ -10,7 +10,7 @@ def fetch_customer_catalog(config, repoinfo): click.secho('Updating cluster catalog...', bold=True) if config.debug: click.echo(f" > Cloning cluster catalog {repoinfo['url']}") - return git.clone_repository(repoinfo['url'], 'catalog') + return git.clone_repository(repoinfo['url'], 'catalog', config) def _pretty_print_component_commit(name, component): @@ -86,7 +86,7 @@ def update_catalog(cfg, target_name, repo): if not cfg.local: if cfg.push: click.echo(' > Commiting changes...') - git.commit(repo, commit_message) + git.commit(repo, commit_message, cfg) click.echo(' > Pushing catalog to remote...') repo.remotes.origin.push() else: diff --git a/commodore/cli.py b/commodore/cli.py index 140a0e6e..6c93d048 100644 --- a/commodore/cli.py +++ b/commodore/cli.py @@ -61,16 +61,23 @@ def clean(config: Config, verbose): 'the Lieutenant API or fetch/push Git repositories.')) @click.option('--push', is_flag=True, default=False, help='Push catalog to remote repository.') +@click.option('--git-author-name', envvar='GIT_AUTHOR_NAME', metavar='USERNAME', help='Name of catalog commit author') +@click.option('--git-author-email', envvar='GIT_AUTHOR_EMAIL', metavar='EMAIL', + help='E-mail address of catalog commit author') @verbosity @pass_config # pylint: disable=too-many-arguments -def compile_catalog(config: Config, cluster, api_url, api_token, global_git_base, local, push, verbose): +def compile_catalog(config: Config, cluster, api_url, api_token, + global_git_base, local, push, verbose, git_author_name, + git_author_email): config.update_verbosity(verbose) config.api_url = api_url config.api_token = api_token config.global_git_base = global_git_base config.local = local config.push = push + config.username = git_author_name + config.usermail = git_author_email _compile(config, cluster) diff --git a/commodore/compile.py b/commodore/compile.py index 96022050..6face42e 100644 --- a/commodore/compile.py +++ b/commodore/compile.py @@ -36,7 +36,7 @@ def _fetch_global_config(cfg, cluster): click.secho('Updating global config...', bold=True) repo = git.clone_repository( f"{cfg.global_git_base}/{config}.git", - 'inventory/classes/global') + 'inventory/classes/global', cfg) cfg.register_config('global', repo) @@ -51,7 +51,9 @@ def _fetch_customer_config(cfg, customer_id): f" > API did not return a repository URL for customer '{customer_id}'") if cfg.debug: click.echo(f" > Cloning customer config {repopath}") - repo = git.clone_repository(repopath, P('inventory/classes') / customer_id) + repo = git.clone_repository(repopath, + P('inventory/classes') / customer_id, + cfg) cfg.register_config('customer', repo) diff --git a/commodore/component/template.py b/commodore/component/template.py index d26ee8fe..810a027a 100644 --- a/commodore/component/template.py +++ b/commodore/component/template.py @@ -73,7 +73,7 @@ def create(self): index.add('*') index.add('.github') index.add('.*.yml') - git.commit(repo, 'Initial commit') + git.commit(repo, 'Initial commit', self.config) click.echo(' > Installing component') create_component_symlinks(self.config, component) diff --git a/commodore/config.py b/commodore/config.py index 3e1613e4..b45983fd 100644 --- a/commodore/config.py +++ b/commodore/config.py @@ -15,9 +15,10 @@ def target_directory(self): return P('dependencies') / self.name +# pylint: disable=too-many-instance-attributes class Config: # pylint: disable=too-many-arguments - def __init__(self, api_url=None, api_token=None, global_git=None, verbose=False): + def __init__(self, api_url=None, api_token=None, global_git=None, verbose=False, username=None, usermail=None): self.api_url = api_url self.api_token = None if api_token is not None: @@ -35,6 +36,9 @@ def __init__(self, api_url=None, api_token=None, global_git=None, verbose=False) self._config_repos = {} self._verbose = verbose + self.username = username + self.usermail = usermail + @property def verbose(self): return self._verbose diff --git a/commodore/dependency_mgmt.py b/commodore/dependency_mgmt.py index 214d0fbe..5de8de22 100644 --- a/commodore/dependency_mgmt.py +++ b/commodore/dependency_mgmt.py @@ -97,7 +97,7 @@ def fetch_components(cfg): for c in components: if cfg.debug: click.echo(f" > Fetching component {c.name}...") - repo = git.clone_repository(c.repo_url, c.target_directory) + repo = git.clone_repository(c.repo_url, c.target_directory, cfg) c = c._replace(repo=repo) cfg.register_component(c) create_component_symlinks(cfg, c) @@ -160,7 +160,9 @@ def fetch_jsonnet_libs(config, libs): filestext = ' '.join([f['targetfile'] for f in lib['files']]) if config.debug: click.echo(f" > {libname}: {filestext}") - repo = git.clone_repository(lib['repository'], P('dependencies/libs') / libname) + repo = git.clone_repository(lib['repository'], + P('dependencies/libs') / libname, + config) for file in lib['files']: relsymlink(repo.working_tree_dir, file['libfile'], 'dependencies/lib', destname=file['targetfile']) diff --git a/commodore/git.py b/commodore/git.py index 99a9e23d..a014d4ed 100644 --- a/commodore/git.py +++ b/commodore/git.py @@ -56,7 +56,7 @@ def checkout_version(repo, ref): raise RefError(f"Revision '{ref}' not found in repository") from e -def clone_repository(repository_url, directory): +def clone_repository(repository_url, directory, cfg): try: repo = Repo.clone_from(_normalize_git_ssh(repository_url), directory) except Exception as e: @@ -66,7 +66,7 @@ def clone_repository(repository_url, directory): _ = repo.head.commit except ValueError as e: click.echo(f" > {e}, creating initial commit for {directory}") - commit(repo, "Initial commit") + commit(repo, "Initial commit", cfg) return repo @@ -185,8 +185,15 @@ def stage_all(repo): return '\n'.join(difftext), changed -def commit(repo, commit_message): - author = Actor("Commodore", "commodore@vshn.net") +def commit(repo, commit_message, cfg): + if cfg.username and cfg.usermail: + author = Actor(cfg.username, cfg.usermail) + else: + author = Actor.committer(repo.config_reader()) + + if cfg.trace: + click.echo(f' > Using "{author.name} <{author.email}>" as commit author') + repo.index.commit(commit_message, author=author, committer=author) diff --git a/docker-compose.yaml b/docker-compose.yaml index 3ddf98cc..df2bb0d1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,3 +10,4 @@ services: - ./dependencies/:/app/dependencies/ - ./inventory/:/app/inventory/ - ~/.ssh/:/app/.ssh/:ro + - ~/.gitconfig:/app/.gitconfig:ro diff --git a/tests/test_git.py b/tests/test_git.py index f2786498..afd25c1f 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -19,7 +19,7 @@ def test_create_repository(tmp_path: Path): def test_clone_error(tmp_path: Path): inexistent_url = 'ssh://git@git.example.com/some/repo.git' with pytest.raises(click.ClickException) as excinfo: - git.clone_repository(inexistent_url, tmp_path) + git.clone_repository(inexistent_url, tmp_path, None) assert inexistent_url in str(excinfo.value) From fa26f10adaba1dc07428e371a666f372d83717cf Mon Sep 17 00:00:00 2001 From: Simon Gerber Date: Mon, 20 Jul 2020 17:56:52 +0200 Subject: [PATCH 2/2] Update CHANGELOG --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7efa2587..3ba216f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Option to explicitly set a component's display name ([#133]) * labels to issue templates ([#134]) * Vale Makefile target in component template ([#137]) +* Allow overriding Git user info for catalog commits ([#140]) * Refactor tests to work with new setup-python ([#143]) ### Changed @@ -113,4 +114,5 @@ Initial implementation [#134]: https://github.com/projectsyn/commodore/pull/134 [#136]: https://github.com/projectsyn/commodore/issues/136 [#137]: https://github.com/projectsyn/commodore/pull/137 -[#137]: https://github.com/projectsyn/commodore/pull/143 +[#140]: https://github.com/projectsyn/commodore/pull/140 +[#143]: https://github.com/projectsyn/commodore/pull/143