supermario/bin/deepen

86 lines
3.0 KiB
Plaintext
Raw Normal View History

2019-04-02 16:12:47 +00:00
#!/usr/bin/env python3
import argparse
from os import path, makedirs, walk, listdir, remove, stat, chmod
2019-04-02 16:12:47 +00:00
from shutil import copy, rmtree
from subprocess import run
from shlex import quote
2019-04-02 16:12:47 +00:00
from folder import folder
2019-04-02 16:12:47 +00:00
def make_executable(path): # thanks to Jonathon Reinhart on SO
mode = stat(path).st_mode
mode |= (mode & 0o444) >> 2 # copy R bits to X
chmod(path, mode)
def relpath(dest, src):
return path.relpath(path.abspath(dest), path.abspath(src))
def path_to_script(script_name, from_worktree):
script_path = path.join(path.dirname(__file__), script_name)
return relpath(script_path, from_worktree)
2019-04-02 16:12:47 +00:00
parser = argparse.ArgumentParser(description='''
Expand a patchset into a git repository (based on git-am)
''')
parser.add_argument('patchset', metavar='PATCHSET', action='store', type=lambda x: folder('patchset', x), help='Patchset (assumed in ../patchset/)')
parser.add_argument('worktree', metavar='WORKTREE', action='store', type=lambda x: folder('worktree', x), help='Destination worktree (assumed in ../worktree/)')
group = parser.add_mutually_exclusive_group()
group.add_argument('--base', metavar='SRC', action='store', default='SuperMarioProj.1994-02-09', type=lambda x: folder('base', x), help='Base source tree (default=SuperMarioProj.1994-02-09, assumed in ../base/)')
args = parser.parse_args()
assert path.exists(args.patchset)
assert not path.exists(path.join(args.patchset, '.git')) # protect against argument swap
horst = ['-c', 'user.name=Horst Beepmanh', '-c', 'user.email=<>']
def git(*gitargs):
run(['git', *horst, *gitargs], cwd=args.worktree, check=True)
2019-04-02 16:12:47 +00:00
try:
rmtree(args.worktree)
except FileNotFoundError:
pass
makedirs(args.worktree)
2019-04-02 16:12:47 +00:00
with open(path.join(args.worktree, '.gitignore'), 'a') as f:
f.write('.*\n*.dmg\nBuild*/\n')
2019-04-02 16:12:47 +00:00
with open(path.join(args.worktree, '.build'), 'w') as f:
print('#!/bin/sh', file=f)
print('exec ' + quote(path_to_script('build', args.worktree)) + ' . "$@"', file=f)
make_executable(f.name)
with open(path.join(args.worktree, '.flatten'), 'w') as f:
print('#!/bin/sh', file=f)
print('exec ' + quote(path_to_script('flatten', args.worktree)) + ' . ' + relpath(args.patchset, args.worktree) + ' "$@"', file=f)
make_executable(f.name)
git('init')
git('add', '-f', '.gitignore', '.build', '.flatten')
git('commit', '-m', 'Useful non-source things')
2019-04-02 16:12:47 +00:00
for walk_base, walk_dirs, walk_files in walk(args.base):
walk_dirs[:] = [x for x in walk_dirs if not x.startswith('.')]
walk_files[:] = [x for x in walk_files if not x.startswith('.')]
2019-04-02 16:12:47 +00:00
other_dir = path.join(args.worktree, path.relpath(walk_base, args.base))
2019-04-02 16:12:47 +00:00
makedirs(other_dir, exist_ok=True)
2019-04-02 16:12:47 +00:00
for this_file in walk_files:
copy(path.join(walk_base, this_file), other_dir)
git('add', '.')
git('commit', '-m', path.basename(args.base))
git('tag', 'patchset-base')
2019-04-02 16:12:47 +00:00
patchfiles = [path.join(args.patchset, x) for x in sorted(listdir(args.patchset)) if path.splitext(x)[1].lower() == '.patch']
git('am', *patchfiles)