Skip to content

Commit

Permalink
Merge pull request #104 from projectsyn/feature/override-git-url
Browse files Browse the repository at this point in the history
Allow overriding of component URL in inventory
  • Loading branch information
Simon Rüegg authored May 27, 2020
2 parents c0e5be0 + 6cef654 commit 24d96ca
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 32 deletions.
2 changes: 1 addition & 1 deletion commodore/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def _pretty_print_component_commit(name, component):
repo = component.repo
sha = repo.head.commit.hexsha
short_sha = repo.git.rev_parse(sha, short=6)
return f" * {name}:{component.version} ({short_sha})"
return f" * {name}: {component.version} ({short_sha})"


def _pretty_print_config_commit(name, repo):
Expand Down
4 changes: 2 additions & 2 deletions commodore/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .dependency_mgmt import (
fetch_components,
fetch_jsonnet_libs,
set_component_versions
set_component_overrides
)
from .helpers import (
ApiError,
Expand Down Expand Up @@ -137,7 +137,7 @@ def compile(config, cluster_id):
kapitan_inventory = inventory_reclass('inventory')['nodes'][target_name]
versions = kapitan_inventory['parameters'].get('component_versions', None)
if versions and not config.local:
set_component_versions(config, versions)
set_component_overrides(config, versions)
update_target(config, cluster)

jsonnet_libs = kapitan_inventory['parameters'].get(
Expand Down
18 changes: 16 additions & 2 deletions commodore/config.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from collections import namedtuple
from typing import NamedTuple
from pathlib import Path as P

from git import Repo


class Component(NamedTuple):
name: str
repo: Repo
repo_url: str
version: str = 'master'

class Component(namedtuple('Component', ['name', 'repo', 'version', 'repo_url'])):
@property
def target_directory(self):
return P('dependencies') / self.name
Expand Down Expand Up @@ -61,6 +68,13 @@ def set_component_version(self, component_name, version):
c = self._components[component_name]
c = c._replace(version=version)
self._components[component_name] = c
return c

def set_repo_url(self, component_name, repo_url):
c = self._components[component_name]
c = c._replace(repo_url=repo_url)
self._components[component_name] = c
return c

def get_component_repo(self, component_name):
return self._components[component_name].repo
Expand Down
45 changes: 27 additions & 18 deletions commodore/dependency_mgmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,29 +119,38 @@ def fetch_components(cfg):
create_component_symlinks(cfg, c)


def _set_component_version(cfg, component: Component, version):
click.echo(f" > {component}: {version}")
try:
git.checkout_version(component.repo, version)
except git.RefError as e:
click.secho(f" unable to set version: {e}", fg='yellow')
# Create symlinks again with correctly checked out components
create_component_symlinks(cfg, component)
cfg.set_component_version(component.name, version)


def set_component_versions(cfg, versions):
def set_component_overrides(cfg, versions):
"""
Set component versions according to versions provided in versions dict.
The dict is assumed to contain component names as keys, and dicts as
Set component overrides according to versions and URLs provided in versions dict.
The dict is assumed to contain the component names as keys, and dicts as
values. The value dicts are assumed to contain a key 'version' which
indicates the version as a Git tree-ish.
indicates the version as a Git tree-ish. Additionally the key 'url' can
specify the URL of the Git repo.
"""

click.secho('Setting component versions...', bold=True)
for component_name, c in versions.items():
click.secho('Setting component overrides...', bold=True)
for component_name, overrides in versions.items():
component = cfg.get_components()[component_name]
_set_component_version(cfg, component, c['version'])
needs_checkout = False
if 'url' in overrides:
url = overrides['url']
if cfg.debug:
click.echo(f" > Set URL for {component.name}: {url}")
needs_checkout = git.update_remote(component.repo, url)
component = cfg.set_repo_url(component_name, url)
if 'version' in overrides:
version = overrides['version']
if cfg.debug:
click.echo(f" > Set version for {component.name}: {version}")
needs_checkout = True
component = cfg.set_component_version(component_name, version)
if needs_checkout:
try:
git.checkout_version(component.repo, component.version)
except git.RefError as e:
raise click.ClickException(f"While setting component override: {e}") from e
# Create symlinks again with correctly checked out components
create_component_symlinks(cfg, component)


def fetch_jsonnet_libs(config, libs):
Expand Down
18 changes: 15 additions & 3 deletions commodore/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@


class RefError(ValueError):
def __init__(self, message):
super().__init__()
self.message = message
pass


def _normalize_git_ssh(url):
Expand Down Expand Up @@ -72,6 +70,20 @@ def clone_repository(repository_url, directory):
return repo


def update_remote(repo: Repo, remote_url):
origin = repo.remotes.origin
if origin.url != remote_url:
with origin.config_writer as cw:
cw.set("url", remote_url)
try:
origin.pull(prune=True)
return True
except Exception as e:
raise click.ClickException(
f"While fetching git repository: {e}") from e
return False


def init_repository(path):
return Repo(path)

Expand Down
20 changes: 14 additions & 6 deletions tests/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,27 @@
import pytest

from commodore import git
from git import Repo
from pathlib import Path


def test_create_repository(tmp_path: Path):
repo_path = tmp_path / 'test-repo'
repo_path.mkdir()
repo = git.create_repository(repo_path)
def test_create_repository(tmpdir: Path):
repo = git.create_repository(tmpdir)
output = git.stage_all(repo)
assert output != ""


def test_clone_error(tmp_path: Path):
def test_clone_error(tmpdir: Path):
inexistent_url = 'ssh://[email protected]/some/repo.git'
with pytest.raises(click.ClickException) as excinfo:
git.clone_repository(inexistent_url, tmp_path)
git.clone_repository(inexistent_url, tmpdir)
assert inexistent_url in str(excinfo.value)


def test_update_remote(tmpdir: Path):
new_url = 'ssh://[email protected]/some/repo.git'
repo = Repo.init(tmpdir)
repo.create_remote('origin', url='ssh://')
with pytest.raises(click.ClickException):
git.update_remote(repo, new_url)
assert repo.remotes.origin.url == new_url

0 comments on commit 24d96ca

Please sign in to comment.