Files
OpenNetworkLinux/tools/submodules.py
Andreas Rammhold a4cefaf8f5 tools: use /usr/bin/python2 instead of /usr/bin/python
python3 is starting to become the default on all major distributions.
Using `/usr/bin/python2` should be safe for the near future.
2017-06-30 11:40:29 +02:00

137 lines
4.3 KiB
Python
Executable File

#!/usr/bin/python2
############################################################
# <bsn.cl fy=2013 v=none>
#
# Copyright 2013, 2014 BigSwitch Networks, Inc.
#
#
#
# </bsn.cl>
############################################################
#
# Submodule management.
#
############################################################
import os
import sys
import subprocess
import shutil
import logging
logging.basicConfig()
logger = logging.getLogger("submodules")
logger.setLevel(logging.INFO)
def check_call(cmd, *args, **kwargs):
if type(cmd) == str:
logger.debug("+ " + cmd)
else:
logger.debug("+ " + " ".join(cmd))
return subprocess.check_call(cmd, *args, **kwargs)
def check_output(cmd, *args, **kwargs):
if type(cmd) == str:
logger.debug("+ " + cmd)
else:
logger.debug("+ " + " ".join(cmd))
return subprocess.check_output(cmd, *args, **kwargs)
class OnlSubmoduleError(Exception):
"""General Package Error Exception"""
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class OnlSubmoduleManager(object):
def __init__(self, root):
if not os.path.exists(os.path.join(root, ".git")):
raise OnlSubmoduleError("%s is not a git repository." % root)
if not os.path.exists(os.path.join(root, ".gitmodules")):
raise OnlSubmoduleError("The git repository %s does not contain any submodules." % root)
self.root = root
self.get_status()
def get_status(self):
self.status = {}
try:
for entry in check_output(['git', 'submodule', 'status'], cwd=self.root).split("\n"):
data = entry.split()
if len(data) >= 2:
self.status[data[1]] = data[0]
except subprocess.CalledProcessError:
raise OnlSubmoduleError("git command(s) failed")
def validate(self, path):
if not path in self.status:
raise OnlSubmoduleError("Submodule %s does not exist in repository %s" % (path, self.root))
def update(self, path, depth=None, recursive=False):
self.validate(path)
if depth:
logger.debug("shallow clone depth=%d", int(depth))
# Shallow clone first
url = check_output(['git', 'config', '-f', '.gitmodules', '--get',
'submodule.' + path + '.url' ], cwd=self.root)
url = url.rstrip('\n')
args = [ 'git', 'clone', '--depth', depth, url, path ]
try:
check_call(args, cwd=self.root)
except subprocess.CalledProcessError:
raise OnlSubmoduleError("git error cloning module %s" % path)
# full or partial update
args = [ 'git', 'submodule', 'update', '--init' ]
if recursive:
args.append("--recursive")
args.append(path)
try:
check_call(args, cwd=self.root)
except subprocess.CalledProcessError:
raise OnlSubmoduleError("git error updating module %s" % path)
#
# Run any repository-specific post-submodule-init scripts.
#
for script in os.getenv("ONL_SUBMODULE_UPDATED_SCRIPTS", "").split(':'):
if os.path.exists(script):
try:
print "Calling %s..." % script
check_call([script, path], cwd=self.root)
except subprocess.CalledProcessError:
raise OnlSubmoduleError("The repository post-init script %s failed." % script)
def require(self, path, depth=None, recursive=False):
self.get_status()
self.validate(path)
if self.status[path][0] == '-':
self.update(path, depth=depth, recursive=recursive)
if __name__ == '__main__':
import argparse
ap = argparse.ArgumentParser(description='Submodule Manager')
ap.add_argument("root", help="The root of the git repository in which to operate.")
ap.add_argument("path", help="The submodule path to initialize.")
ap.add_argument("--depth", help="Shallow submodule clone to given depth.")
ap.add_argument("--recursive", help="Recursive update.", action='store_true')
ops = ap.parse_args()
try:
sm = OnlSubmoduleManager(ops.root)
sm.require(ops.path)
except OnlSubmoduleError, e:
logger.error("%s" % e.value)