diff --git a/README.md b/README.md index 1bb6d4a..497ab26 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,16 @@ Track changes in a [repo](https://gerrit.googlesource.com/git-repo/+/master/#rep * `jobs`: *Optional.* number of jobs to run in parallel (default: 0; based on number of CPU cores) Reduce this if you observe network errors. +* `rewrite`: *Optional.* Any URL that starts with this value will be rewritten with the give value. + Similar to git url insteadOf option. + Example: rewrite http(s):// to git:// + + ```yaml + rewrite: + "http://": "git://" + "https://": "git://" + ``` + * `check_jobs`: for check step only: number of jobs to run in parallel (default: jobs\*2, 2 if jobs is undefined). diff --git a/repo_resource/check.py b/repo_resource/check.py index 65f2bfd..14e3ea8 100644 --- a/repo_resource/check.py +++ b/repo_resource/check.py @@ -48,9 +48,11 @@ def check(instream) -> list: config.revision, config.name, config.depth) - repo.init() - repo.update_manifest(jobs=check_jobs) - version = repo.currentVersion() + version = repo \ + .set_rewrite(config.rewrite) \ + .init() \ + .update_manifest(jobs=check_jobs) \ + .currentVersion() except Exception as e: raise e finally: diff --git a/repo_resource/common.py b/repo_resource/common.py index aa3cfd1..81c599c 100644 --- a/repo_resource/common.py +++ b/repo_resource/common.py @@ -129,6 +129,7 @@ class SourceConfiguration(NamedTuple): depth: int = -1 jobs: int = 0 check_jobs: int = DEFAULT_CHECK_JOBS + rewrite: str = None def source_config_from_payload(payload): @@ -253,6 +254,25 @@ def __get_remote_url(self, remote): def __get_remote_revision(self, remote): return self.__remote_revision[remote] + def set_rewrite(self, matrix: dict = None): + if matrix is None: + return self + + with redirect_stdout(sys.stderr), \ + tempfile.TemporaryDirectory() as tempdir: + gitrepo = git.Repo.init(tempdir) + print("Applying rewrite rules") + for from_url, to_url in matrix.items(): + print('{} -> {}'.format(from_url, to_url)) + gitrepo \ + .config_writer(config_level='global') \ + .set_value( + 'url "{}"'.format(to_url), + "insteadOf", from_url + ) \ + .release() + return self + def init(self): self.__change_to_workdir() try: @@ -276,6 +296,7 @@ def init(self): print('Downloading manifest from {}'.format(self.__url)) repo._Main(repo_cmd) print('repo has been initialized in {}'.format(self.__workdir)) + return self except Exception as e: raise (e) @@ -303,6 +324,7 @@ def sync(self, version: Version, jobs: int = 0): repo._Main(repo_cmd) if os.listdir(self.__workdir) == []: raise Exception('Sync failed. Is manifest correct?') + return self except Exception as e: raise (e) finally: @@ -320,6 +342,7 @@ def save_manifest(self, filename): full_path = self.__workdir / filename print('Saving manifest to {}'.format(full_path)) self.__version.to_file(full_path) + return self def currentVersion(self) -> Version: return self.__version @@ -424,6 +447,7 @@ def update_manifest(self, jobs): strip_text=True ) ) + return self except FileNotFoundError as e: with redirect_stdout(sys.stderr): diff --git a/repo_resource/in_.py b/repo_resource/in_.py index 8aafe21..6787e36 100644 --- a/repo_resource/in_.py +++ b/repo_resource/in_.py @@ -46,9 +46,10 @@ def in_(instream, dest_dir='.'): try: repo = common.Repo(config.url, config.revision, config.name, config.depth, workdir=Path(dest_dir)) - repo.init() - repo.sync(requested_version, config.jobs) - repo.update_version() + repo.set_rewrite(config.rewrite) \ + .init() \ + .sync(requested_version, config.jobs) \ + .update_version() except Exception as e: raise e finally: diff --git a/repo_resource/test_check.py b/repo_resource/test_check.py index 04e0284..34b6182 100644 --- a/repo_resource/test_check.py +++ b/repo_resource/test_check.py @@ -32,6 +32,18 @@ def setUp(self): 'name': 'aosp_device_fixed.xml' } } + self.demo_manifests_to_rewrite_source = { + 'source': { + 'url': + 'https://unreachable-github.com/makohoek/demo-manifests.git', + 'revision': 'main', + 'name': 'aosp_device_fixed.xml', + 'rewrite': { + 'https://unreachable-github.com': + 'https://github.com' + }, + }, + } self.demo_manifests_source_norev = { 'source': { 'url': 'https://github.com/makohoek/demo-manifests.git', @@ -99,6 +111,11 @@ def test_unreachable_manifest(self): with self.assertRaises(repo.error.GitError): check.check(instream) + def test_rewrite_manifest(self): + rewrite_url_data = self.demo_manifests_to_rewrite_source + instream = StringIO(json.dumps(rewrite_url_data)) + check.check(instream) + def test_unknown_revision(self): unknown_revision_data = self.aosp_platform_source unknown_revision_data['source']['revision'] = 'unknown'