gitlab: add a script to clone a repository using manifest details

This commit is contained in:
Matthew Waters 2019-03-26 17:21:32 +11:00 committed by Jordan Petridis
parent 5fe97b9f1c
commit ab873b5e58

86
gitlab/clone_manifest_ref.py Executable file
View file

@ -0,0 +1,86 @@
#!/usr/bin/env python3
import argparse
import os
import subprocess
from collections import namedtuple
import xml.etree.ElementTree as ET
# Disallow git prompting for a username/password
os.environ['GIT_TERMINAL_PROMPT'] = '0'
def git(*args, repository_path='.'):
return subprocess.check_output(["git"] + list(args), cwd=repository_path).decode()
class Manifest(object):
'''
Parse and store the content of a manifest file
'''
remotes = {}
projects = {}
default_remote = 'origin'
default_revision = 'refs/heads/master'
def __init__(self, manifest_path):
self.manifest_path = manifest_path
def parse(self):
try:
tree = ET.parse(self.manifest_path)
except Exception as ex:
raise Exception("Error loading manifest %s in file %s" % (self.manifest_path, ex))
root = tree.getroot()
for child in root:
if child.tag == 'remote':
self.remotes[child.attrib['name']] = child.attrib['fetch']
if child.tag == 'default':
self.default_remote = child.attrib['remote'] or self.default_remote
self.default_revision = child.attrib['revision'] or self.default_revision
if child.tag == 'project':
project = namedtuple('Project', ['name', 'remote',
'revision', 'fetch_uri'])
project.name = child.attrib['name']
if project.name.endswith('.git'):
project.name = project.name[:-4]
project.remote = child.attrib.get('remote') or self.default_remote
project.revision = child.attrib.get('revision') or self.default_revision
project.fetch_uri = self.remotes[project.remote] + project.name + '.git'
self.projects[project.name] = project
def find_project(self, name):
try:
return self.projects[name]
except KeyError as ex:
raise Exception("Could not find project %s in manifest %s" % (name, self.manifest_path))
def get_fetch_uri(self, project, remote):
fetch = self.remotes[remote]
return fetch + project.name + '.git'
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--project", action="store", type=str)
parser.add_argument("--destination", action="store", type=str, default='.')
parser.add_argument("--manifest", action="store", type=str)
options = parser.parse_args()
if not options.project:
raise ValueError("--project argument not provided")
if not options.manifest:
raise ValueError("--manifest argument not provided")
manifest = Manifest(options.manifest)
manifest.parse()
project = manifest.find_project(options.project)
dest = options.destination
if dest == '.':
dest = os.path.join (os.getcwd(), project.name)
git('clone', project.fetch_uri, dest)
git('checkout', '--detach', project.revision, repository_path=dest)