From 8c7b8cf8d72b2dc15fad016f9b98fed8c68f282f Mon Sep 17 00:00:00 2001 From: Jerzy Drozdz Date: Thu, 29 Sep 2022 16:08:08 +0200 Subject: [PATCH] Added patched SubmoduleAwareBuilder --- .tito/custom/fixed_submodule_aware_builder.py | 115 ++++++++++++++++++ .tito/tito.props | 3 +- 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 .tito/custom/fixed_submodule_aware_builder.py diff --git a/.tito/custom/fixed_submodule_aware_builder.py b/.tito/custom/fixed_submodule_aware_builder.py new file mode 100644 index 0000000..9e5bea4 --- /dev/null +++ b/.tito/custom/fixed_submodule_aware_builder.py @@ -0,0 +1,115 @@ +import os + +from tito.builder import SubmoduleAwareBuilder as BuggySubmoduleAwareBuilder +from tito.common import ( + chdir, + debug, + run_command, + create_tgz, + get_commit_timestamp, +) +from tito.tar import TarFixer + + +class SubmoduleAwareBuilder(BuggySubmoduleAwareBuilder): + def run_git_archive(self, relative_git_dir, prefix, commit, dest_tar, subdir=None): + # command to generate a git-archive + git_archive_cmd = "git archive --format=tar --prefix=%s/ %s:%s --output=%s" % ( + prefix, + commit, + relative_git_dir, + dest_tar, + ) + + if subdir is None: + return run_command(git_archive_cmd) + + with chdir(subdir): + run_command(git_archive_cmd) + + # Run git-archive separately if --debug was specified. + # This allows us to detect failure early. + # On git < 1.7.4-rc0, `git archive ... commit:./` fails! + debug( + "git-archive fails if relative dir is not in git tree", + "%s > /dev/null" % git_archive_cmd, + ) + + def create_tgz(self, git_root, prefix, commit, relative_dir, dest_tgz): + """ + Create a .tar.gz from a projects source in git. + And include submodules + """ + + git_root_abspath = os.path.abspath(git_root) + gitmodules_path = os.path.join(git_root_abspath, ".gitmodules") + + # if .gitmodules does not exist, just call the existing create_tgz function + # as there is nothing to see here. + if not os.path.exists(gitmodules_path): + return create_tgz(git_root, prefix, commit, relative_dir, dest_tgz) + + os.chdir(git_root_abspath) + timestamp = get_commit_timestamp(commit) + + # Accommodate standalone projects with specfile in root of git repo: + relative_git_dir = "%s" % relative_dir + if relative_git_dir in ["/", "./"]: + relative_git_dir = "" + + basename = os.path.splitext(dest_tgz)[0] + initial_tar = "%s.initial" % basename + + # We need to tar up the following: + # 1. the current repo + self.run_git_archive(relative_git_dir, prefix, commit, initial_tar, None) + + # 2. all of the submodules + # then combine those into a single archive. + submodules_cmd = "git submodule--helper list" + submodules_output = run_command(submodules_cmd) + + # split submodules output on newline + # then on tab, and the directory is the last entry + submodules_list = [ + line.split("\t")[-1] for line in submodules_output.split("\n") + ] + + submodule_tar_files = [] + # We ignore the hash in the sub modules list as we'll have to get the correct one + # from the commit id in commit + for submodule in submodules_list: + # to find the submodule shars: + # git rev-parse :./ + rev_parse_cmd = "git rev-parse %s:./%s" % (commit, submodule) + submodule_commit = run_command(rev_parse_cmd) + submodule_tar_file = "%s.%s" % (initial_tar, submodule.replace("/", "_")) + # prefix should be / + submodule_prefix = "%s/%s" % (prefix, submodule) + + self.run_git_archive( + relative_git_dir, + submodule_prefix, + submodule_commit, + submodule_tar_file, + submodule, + ) + submodule_tar_files.append(submodule_tar_file) + + # we need to append all of the submodule tar files onto the initial + # Tar can concatenate only 2 archives at a time + for tar_file in submodule_tar_files: + run_command("tar -Af %s %s" % (initial_tar, tar_file)) + + fixed_tar = "%s.tar" % basename + fixed_tar_fh = open(fixed_tar, "wb") + try: + tarfixer = TarFixer( + open(initial_tar, "rb"), fixed_tar_fh, timestamp, commit + ) + tarfixer.fix() + finally: + fixed_tar_fh.close() + + # It's a pity we can't use Python's gzip, but it doesn't offer an equivalent of -n + return run_command("gzip -n -c < %s > %s" % (fixed_tar, dest_tgz)) diff --git a/.tito/tito.props b/.tito/tito.props index 4bf4ae5..39c84b0 100644 --- a/.tito/tito.props +++ b/.tito/tito.props @@ -1,5 +1,6 @@ [buildconfig] -builder = tito.builder.SubmoduleAwareBuilder +builder = fixed_submodule_aware_builder.SubmoduleAwareBuilder tagger = tito.tagger.VersionTagger changelog_do_not_remove_cherrypick = 0 changelog_format = %s (%ae) +lib_dir = .tito/custom