Files
dolt/tools/roll.py
Ben Kalman cc13253c45 Add --subdir argument to roll.py (#2782)
If you want to roll just the go/ directory of noms, you can do:

$ roll.py https://github.com/attic-labs/noms --incl go

If you want to roll the AWS SDK without the tests, you can do:

$ roll.py https://github.com/aws/aws-sdk-go --excl awstesting

This works with nested directories too, for example --incl go/util

--excl is evaluated after --incl, so you could exclude the perf/
directory of go/ if you really wanted:

$ roll.py https://github.com/attic-labs/noms --incl go --excl go/perf
2016-11-11 15:53:16 -08:00

106 lines
3.4 KiB
Python
Executable File

#!/usr/bin/python
# Copyright 2016 Attic Labs, Inc. All rights reserved.
# Licensed under the Apache License, version 2.0:
# http://www.apache.org/licenses/LICENSE-2.0
import argparse, os, os.path, subprocess, sys, shutil, urlparse
def main():
parser = argparse.ArgumentParser(description='Dependency snapshotter')
parser.add_argument('url')
parser.add_argument('--path', help=(
'path to store the dependency at, defaults to vendor/[url without protocol]'))
parser.add_argument('--incl', help=(
'subdirectory of the dependency to check out, relative to the path. '
'Defaults to root. Evaluated before --excl.'))
parser.add_argument('--excl', help=(
'subdirectory of the dependency to delete after checking out, relative to the path. '
'Defaults to nothing. Evaluated after --incl.'))
parser.add_argument('--version', default='HEAD', help=(
'version of the dependency to snapshot, defaults to HEAD'))
args = parser.parse_args()
url = urlparse.urlparse(args.url)
if url.scheme == '':
print 'Invalid url: no scheme'
sys.exit(1)
def rel(subdir):
if subdir is not None and os.path.isabs(subdir):
print 'subdirectory %s must be a relative path' % subdir
sys.exit(1)
return subdir
incl = rel(args.incl)
excl = rel(args.excl)
if not os.path.isdir('.git'):
print '%s must be run from the root of a repository' % sys.argv[0]
sys.exit(1)
path = url.path
if path.startswith('/'):
path = path[1:]
depdir = args.path
if depdir is None:
depdir = os.path.join('vendor', url.netloc, path)
shutil.rmtree(depdir, True)
parent = os.path.dirname(depdir)
if not os.path.isdir(parent):
os.makedirs(parent)
os.chdir(parent)
# Kinda sucks to clone entire repo to get a particular version, but:
# http://stackoverflow.com/questions/3489173/how-to-clone-git-repository-with-specific-revision-changeset
subprocess.check_call(['git', 'clone', args.url])
os.chdir(os.path.basename(depdir))
subprocess.check_call(['git', 'reset', '--hard', args.version])
head = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
f = open('.version', 'w')
f.write('%s\n%s\n' % (args.url, head))
f.close()
shutil.rmtree('.git')
if os.path.isdir('vendor'):
deps = [dirName for dirName, _, files in os.walk('vendor') if files]
if deps:
print '\nWarning!'
print ' %s contains one or more dependencies which will need to be vendored as well:' % args.url
print ' -', '\n - '.join(deps)
shutil.rmtree('vendor')
if incl is not None:
if not os.path.isdir(incl):
print 'Warning: --incl directory %s does not exist, skipping.' % incl
else:
inclPath = os.path.abspath(incl)
inclParent, inclName = os.path.split(inclPath)
for (dirpath, dirnames, _) in os.walk(os.getcwd()):
if dirpath == inclParent:
# Don't descend into the included subdirectory.
dirnames.remove(inclName)
elif not inclPath.startswith(dirpath):
# Remove directories that aren't an ancestor of the included.
print 'rm subdirectory: %s' % dirpath
shutil.rmtree(dirpath)
if excl is not None:
if not os.path.isdir(excl):
print 'Warning: --excl directory %s does not exist, skipping.' % incl
else:
exclPath = os.path.abspath(excl)
print 'rm subdirectory: %s' % exclPath
shutil.rmtree(exclPath)
if __name__ == '__main__':
main()