diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2013-04-02 21:08:35 +0200 |
---|---|---|
committer | Johannes Berg <johannes@sipsolutions.net> | 2013-04-02 21:09:33 +0200 |
commit | a9d49afaac48dc2e7f9b7c695cc3907826bf6c25 (patch) | |
tree | d3d90062241a3e40bb143105d4fc6b38704047c9 | |
parent | 615208f7215e478d5eaea0ee985ab886be980551 (diff) |
add ability to read source files from git
Instead of having to have a checked-out kernel tree the
script can now read the files from a git revision when
passed the --git-revision <rev> argument. In this case
the kerneldir is taken as the git tree to use.
This helps when generating for multiple different trees.
Note that due to the need to invoke git many times this
is considerably slower than copying from a checkout. If
taking into account the time to create the checkout it's
still faster though.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
-rwxr-xr-x | gentree.py | 39 | ||||
-rw-r--r-- | lib/git.py | 24 |
2 files changed, 54 insertions, 9 deletions
@@ -12,7 +12,7 @@ source_dir = os.path.abspath(os.path.dirname(sys.argv[0])) sys.path.append(os.path.join(source_dir, 'lib')) import kconfig, git, patch, make -def read_copy_list(kerneldir, copyfile): +def read_copy_list(copyfile): ret = [] for item in copyfile: # remove leading/trailing whitespace @@ -28,7 +28,7 @@ def read_copy_list(kerneldir, copyfile): raise Exception("Cannot copy file/dir to dir/file") else: srcitem = dstitem = item - ret.append((kerneldir, srcitem, dstitem)) + ret.append((srcitem, dstitem)) return ret def read_dependencies(depfilename): @@ -93,8 +93,8 @@ def copytree(src, dst, symlinks=False, ignore=None): if errors: raise shutil.Error(errors) -def copy_files(copy_list, outdir): - for srcpath, srcitem, tgtitem in copy_list: +def copy_files(srcpath, copy_list, outdir): + for srcitem, tgtitem in copy_list: if tgtitem == '': copytree(srcpath, outdir, ignore=shutil.ignore_patterns('*~')) elif tgtitem[-1] == '/': @@ -120,6 +120,19 @@ def copy_files(copy_list, outdir): shutil.copy(os.path.join(srcpath, srcitem), os.path.join(outdir, tgtitem)) +def copy_git_files(srcpath, copy_list, rev, outdir): + for srcitem, tgtitem in copy_list: + for m, t, h, f in git.ls_tree(rev=rev, files=(srcitem,), tree=srcpath): + assert t == 'blob' + f = os.path.join(outdir, f) + d = os.path.dirname(f) + if not os.path.exists(d): + os.makedirs(d) + outf = open(f, 'w') + git.get_blob(h, outf, tree=srcpath) + outf.close() + os.chmod(f, int(m, 8)) + def git_debug_init(args): if not args.gitdebug: return @@ -141,6 +154,10 @@ def main(): parser.add_argument('--copy-list', metavar='<listfile>', type=argparse.FileType('r'), default='copy-list', help='File containing list of files/directories to copy, default "copy-list"') + parser.add_argument('--git-revision', metavar='<revision>', type=str, + help='git commit revision (see gitrevisions(7)) to take objects from.' + + 'If this is specified, the kernel tree is used as git object storage ' + + 'and we use git ls-tree to get the files.') parser.add_argument('--clean', const=True, default=False, action="store_const", help='Clean output directory instead of erroring if it isn\'t empty') parser.add_argument('--refresh', const=True, default=False, action="store_const", @@ -154,10 +171,8 @@ def main(): help='Print more verbose information') args = parser.parse_args() - # first thing to copy is our own plumbing -- we start from that - copy_list = [(os.path.join(source_dir, 'backport'), '', '')] # then add stuff from the copy list file - copy_list.extend(read_copy_list(args.kerneldir, args.copy_list)) + copy_list = read_copy_list(args.copy_list) deplist = read_dependencies(os.path.join(source_dir, 'dependencies')) @@ -165,8 +180,14 @@ def main(): check_output_dir(args.outdir, args.clean) # do the copy - print 'Copy original source files ...' - copy_files(copy_list, args.outdir) + if not args.git_revision: + print 'Copy original source files ...' + copy_files(os.path.join(source_dir, 'backport'), [('', '')], args.outdir) + copy_files(args.kerneldir, copy_list, args.outdir) + else: + print 'Get original source files from git ...' + copy_files(os.path.join(source_dir, 'backport'), [('', '')], args.outdir) + copy_git_files(args.kerneldir, copy_list, args.git_revision, args.outdir) git_debug_init(args) @@ -61,3 +61,27 @@ def commit_all(message, tree=None): stdout = process.communicate()[0] process.wait() _check(process) + +def ls_tree(rev, files, tree=None): + process = subprocess.Popen(['git', 'ls-tree', '-z', '-r', rev, '--', ] + list(files), + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + close_fds=True, universal_newlines=True, cwd=tree) + stdout = process.communicate()[0] + files = stdout.split('\0') + ret = [] + for f in files: + if not f: + continue + meta, f = f.split('\t', 1) + meta = meta.split() + meta.append(f) + ret.append(meta) + process.wait() + _check(process) + return ret + +def get_blob(blob, outf, tree=None): + process = subprocess.Popen(['git', 'show', blob], + stdout=outf, close_fds=True, cwd=tree) + process.wait() + _check(process) |