#!/usr/bin/python3 import io import os import os.path import re import subprocess import sys def main(repo, range='torvalds/master..dhowells/efi-lock-down'): patch_dir = 'debian/patches' lockdown_patch_dir = 'features/all/lockdown' series_name = 'series' # Only replace patches in this subdirectory and starting with a digit # - the others are presumably Debian-specific for now lockdown_patch_name_re = re.compile( r'^' + re.escape(lockdown_patch_dir) + r'/\d') series_before = [] series_after = [] old_series = set() new_series = set() try: with open(os.path.join(patch_dir, series_name), 'r') as series_fh: for line in series_fh: name = line.strip() if lockdown_patch_name_re.match(name): old_series.add(name) elif len(old_series) == 0: series_before.append(line) else: series_after.append(line) except FileNotFoundError: pass with open(os.path.join(patch_dir, series_name), 'w') as series_fh: for line in series_before: series_fh.write(line) # Add directory prefix to all filenames. # Add Origin to all patch headers. def add_patch(name, source_patch, origin): name = os.path.join(lockdown_patch_dir, name) path = os.path.join(patch_dir, name) try: os.unlink(path) except FileNotFoundError: pass with open(path, 'w') as patch: in_header = True for line in source_patch: if in_header and re.match(r'^(\n|[^\w\s]|Index:)', line): patch.write('Origin: %s\n' % origin) if line != '\n': patch.write('\n') in_header = False patch.write(line) series_fh.write(name) series_fh.write('\n') new_series.add(name) # XXX No signature to verify env = os.environ.copy() env['GIT_DIR'] = os.path.join(repo, '.git') args = ['git', 'format-patch', '--subject-prefix=', range] format_proc = subprocess.Popen(args, cwd=os.path.join(patch_dir, lockdown_patch_dir), env=env, stdout=subprocess.PIPE) with io.open(format_proc.stdout.fileno(), encoding='utf-8') as pipe: for line in pipe: name = line.strip('\n') with open(os.path.join(patch_dir, lockdown_patch_dir, name)) \ as source_patch: patch_from = source_patch.readline() match = re.match(r'From ([0-9a-f]{40}) ', patch_from) assert match origin = ('https://git.kernel.org/pub/scm/linux/kernel/' 'git/dhowells/linux-fs.git/commit?id=%s' % match.group(1)) add_patch(name, source_patch, origin) for line in series_after: series_fh.write(line) for name in new_series: if name in old_series: old_series.remove(name) else: print('Added patch', os.path.join(patch_dir, name)) for name in old_series: print('Obsoleted patch', os.path.join(patch_dir, name)) if __name__ == '__main__': if not (2 <= len(sys.argv) <= 3): sys.stderr.write('''\ Usage: %s REPO [REVISION-RANGE] REPO is a git repo containing the REVISION-RANGE. The default range is torvalds/master..dhowells/efi-lock-down. ''' % sys.argv[0]) print('BASE is the base branch (default: torvalds/master).') sys.exit(2) main(*sys.argv[1:])