Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 157 lines (118 sloc) 5.81 KB
#!/usr/bin/env python
import argparse
import os
import xml.etree.ElementTree as ET
from collections import OrderedDict
class ExternalSubtree:
def __init__(self, name, internal_path, external_url, default_external_ref):
self.name = name
self.internal_path = internal_path
self.external_url = external_url
self.default_external_ref = default_external_ref
SCRIPT_DIR=os.path.dirname(os.path.realpath(__file__))
DEFAULT_CONFIG=os.path.join(SCRIPT_DIR, 'subtree_config.xml')
def parse_args():
parser = argparse.ArgumentParser(description="VTR uses external tools/libraries which are developed outside of the VTR source tree. Some of these are included in the VTR source tree using git's subtree feature. This script is used to update git-subtrees in a consistent manner. It must be run from the root of the VTR source tree.")
parser.add_argument("components",
nargs="*",
metavar='COMPONENT',
help="External components to upgrade (See list of components with --list)")
parser.add_argument("--external_ref",
default=None,
help="Specifies the external reference (revision/branch). If unspecified uses the subtree default (usually master).")
exclusive_group = parser.add_mutually_exclusive_group()
exclusive_group.add_argument("--list",
action="store_true",
default=False,
help="List known components")
exclusive_group.add_argument("--update",
action="store_true",
default=False,
help="Update components subtrees")
parser.add_argument("-n", "--dry_run",
action="store_true",
default=False,
help="Show the commands which would be executed, but do not actually perform them.")
parser.add_argument("--subtree_config",
default=DEFAULT_CONFIG,
help="Path to subtree config file (Default: %(default)s)")
args = parser.parse_args()
return args
def main():
args = parse_args()
config = load_subtree_config(args.subtree_config)
if args.list and len(args.components) == 0:
args.components = config.keys()
for component in args.components:
update_component(args, config[component])
def load_subtree_config(config_path):
config = OrderedDict()
tree = ET.parse(config_path)
root = tree.getroot()
assert root.tag == 'subtrees', "Expected root tag to be 'subtrees'"
for child in root:
assert child.tag == 'subtree', "Expected children to be 'subtree'"
name = None
internal_path = None
external_url = None
default_external_ref = None
for attrib, value in child.attrib.iteritems():
if attrib == 'name':
name = value
elif attrib == 'internal_path':
internal_path = value
elif attrib == 'external_url':
external_url = value
elif attrib == 'default_external_ref':
default_external_ref = value
else:
assert False, "Unrecognized subtree attribute {}".format(attrib)
assert name != None, "Missing subtree name"
assert internal_path != None, "Missing subtree internal path"
assert external_url != None, "Missing subtree external url"
assert default_external_ref != None, "Missing subtree default external ref"
assert name not in config, "Duplicate subtree name '{}'".format(name)
config[name] = ExternalSubtree(name, internal_path, external_url, default_external_ref)
return config
def update_component(args, subtree_info):
external_ref = None
if not args.external_ref:
external_ref = subtree_info.default_external_ref
print "Component: {:<15} Path: {:<30} URL: {:<45} URL_Ref: {}".format(subtree_info.name, subtree_info.internal_path, subtree_info.external_url, external_ref)
if args.list:
return #List only
else:
assert args.update
assert external_ref != None
action = None
message = None
if not os.path.exists(subtree_info.internal_path):
#Create
action = 'add'
message = "{name}: Adding '{path}/' as an external git subtree from {url} {rev}".format(
name=subtree_info.name,
path=subtree_info.internal_path,
url=subtree_info.external_url,
rev=external_ref)
else:
#Pull
action = 'pull'
message = "{name}: Updating '{path}/' (external git subtree from {url} {rev})".format(
name=subtree_info.name,
path=subtree_info.internal_path,
url=subtree_info.external_url,
rev=external_ref)
assert action != None
assert message != None
cmd = "git subtree {action} --prefix {internal_path} {external_url} {external_branch} --squash --message '{message}'".format(
action=action,
internal_path=subtree_info.internal_path,
external_url=subtree_info.external_url,
external_branch=external_ref,
message=message)
if args.dry_run:
print cmd
else:
os.system(cmd)
if __name__ == "__main__":
main()
You can’t perform that action at this time.