diff --git a/ecbundle/download.py b/ecbundle/download.py index b800422..cec42d2 100644 --- a/ecbundle/download.py +++ b/ecbundle/download.py @@ -7,6 +7,7 @@ # does it submit to any jurisdiction. import re +from hashlib import md5 from os import getcwd, makedirs, path from subprocess import check_call @@ -139,8 +140,7 @@ def download(self): skipped_optional_packages = list() class GitPackage: - def __init__(self, project): - self.remote = project.remote() + def __init__(self, project, src_dir=None): self.url = None self.name = project.name() self.version = str(project.version()) @@ -165,7 +165,25 @@ def __init__(self, project): elif self.url.startswith("~"): self.url = path.expanduser(self.url) - self.remote_str = self.remote + self._set_remote(project, src_dir=src_dir) + + def _set_remote(self, project, src_dir=None): + from .git import Git + + remote = project.remote(default=None) + if remote is None: + if src_dir is None or not path.exists(src_dir): + remote = "origin" + else: + # look for an existing remote with requested url + for remote_name, remote_url in Git.remotes(src_dir).items(): + if remote_url == self.url: + remote = remote_name + break + if remote is None: + # not found: use a bijective alias to url + remote = md5(self.url.encode("utf-8")).hexdigest() + self.remote_str = remote self.remote = self.remote_str.replace("~", "") def download_one_project(pkg): @@ -350,7 +368,8 @@ def download_data(data_packages, download_dir): if project.dir(): symlink_projects.append(project) else: - git_projects.append(GitPackage(project)) + src_dir = path.join(download_dir, project.name()) + git_projects.append(GitPackage(project, src_dir=src_dir)) for package in bundle.data(): data.append(Data(**package.config)) diff --git a/ecbundle/git.py b/ecbundle/git.py index 8f2afeb..2ac3ac5 100644 --- a/ecbundle/git.py +++ b/ecbundle/git.py @@ -254,6 +254,20 @@ def branch(cls, src_dir, dryrun): except CalledProcessError: return None + @staticmethod + def remotes(src_dir): + command = ["git", "remote", "-v"] + try: + remotes = ( + execute(command, cwd=src_dir, silent=True, capture_output=True) + .strip() + .split("\n") + ) + remotes = [line.split() for line in remotes] + return {line[0]: line[1] for line in remotes if line[2] == "(fetch)"} + except CalledProcessError: + raise RuntimeError() + @classmethod def is_remote(cls, src_dir, remote, dryrun): command = ["git", "ls-remote", remote] diff --git a/ecbundle/project.py b/ecbundle/project.py index 20c630f..dfe8fe5 100644 --- a/ecbundle/project.py +++ b/ecbundle/project.py @@ -39,8 +39,8 @@ def version(self): def git(self): return self.get("git") - def remote(self): - return self.get("remote", "origin") + def remote(self, default="origin"): + return self.get("remote", default) def submodules(self): return self.get("submodules", False)