aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/wrap/wrap.py
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2017-03-25 04:03:03 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2017-03-25 06:47:04 +0530
commita60d688973e8903015f6e4b157332c5c98562f55 (patch)
tree1fdc8b108bc5af9944d81571f0b8dc8dd053f571 /mesonbuild/wrap/wrap.py
parentfb809e79e55160e519be6bafc222c6ba00573793 (diff)
downloadmeson-a60d688973e8903015f6e4b157332c5c98562f55.zip
meson-a60d688973e8903015f6e4b157332c5c98562f55.tar.gz
meson-a60d688973e8903015f6e4b157332c5c98562f55.tar.bz2
wrap: Initialize subprojects that are git submodules
This will benefit projects such as GNOME Recipes that prefer using submodules over wraps because it's easier to maintain since git is aware of it, and because it integrates with their existing workflow. Without this, these projects have to manually initialize the submodules which is completely unnecessary. Closes https://github.com/mesonbuild/meson/issues/1449
Diffstat (limited to 'mesonbuild/wrap/wrap.py')
-rw-r--r--mesonbuild/wrap/wrap.py50
1 files changed, 43 insertions, 7 deletions
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index 05d255d..ad2e3e4 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -37,6 +37,13 @@ def build_ssl_context():
ctx.load_default_certs()
return ctx
+def quiet_git(cmd):
+ pc = subprocess.Popen(['git'] + cmd, stdout=subprocess.PIPE)
+ out, err = pc.communicate()
+ if pc.returncode != 0:
+ return False, err
+ return True, out
+
def open_wrapdburl(urlstring):
global ssl_warning_printed
if has_ssl:
@@ -94,24 +101,31 @@ class Resolver:
def resolve(self, packagename):
# Check if the directory is already resolved
dirname = Path(os.path.join(self.subdir_root, packagename))
+ subprojdir = os.path.join(*dirname.parts[-2:])
if dirname.is_dir():
if (dirname / 'meson.build').is_file():
# The directory is there and has meson.build? Great, use it.
return packagename
- # Is the dir not empty and also not a git submodule dir that is
- # not checkout properly? Can't do anything, exception!
+ # Is the dir not empty and also not a git submodule dir that is
+ # not checkout properly? Can't do anything, exception!
elif next(dirname.iterdir(), None) and not (dirname / '.git').is_file():
m = '{!r} is not empty and has no meson.build files'
- raise RuntimeError(m.format(dirname))
+ raise RuntimeError(m.format(subprojdir))
elif dirname.exists():
- m = '{!r} is not a directory, can not use as subproject'
- raise RuntimeError(m.format(dirname))
+ m = '{!r} already exists and is not a dir; cannot use as subproject'
+ raise RuntimeError(m.format(subprojdir))
+
+ dirname = str(dirname)
+ # Check if the subproject is a git submodule
+ if self.resolve_git_submodule(dirname):
+ return packagename
# Check if there's a .wrap file for this subproject
fname = os.path.join(self.subdir_root, packagename + '.wrap')
if not os.path.isfile(fname):
# No wrap file with this name? Give up.
- return None
+ m = 'No {}.wrap found for {!r}'
+ raise RuntimeError(m.format(packagename, subprojdir))
p = PackageDefinition(fname)
if p.type == 'file':
if not os.path.isdir(self.cachedir):
@@ -123,9 +137,31 @@ class Resolver:
elif p.type == "hg":
self.get_hg(p)
else:
- raise RuntimeError('Unreachable code.')
+ raise AssertionError('Unreachable code.')
return p.get('directory')
+ def resolve_git_submodule(self, dirname):
+ # Are we in a git repository?
+ ret, out = quiet_git(['rev-parse'])
+ if not ret:
+ return False
+ # Is `dirname` a submodule?
+ ret, out = quiet_git(['submodule', 'status', dirname])
+ if not ret:
+ return False
+ # Submodule has not been added, add it
+ if out.startswith(b'-'):
+ if subprocess.call(['git', 'submodule', 'update', dirname]) != 0:
+ return False
+ # Submodule was added already, but it wasn't populated. Do a checkout.
+ elif out.startswith(b' '):
+ if subprocess.call(['git', 'checkout', '.'], cwd=dirname):
+ return True
+ else:
+ m = 'Unknown git submodule output: {!r}'
+ raise AssertionError(m.format(out))
+ return True
+
def get_git(self, p):
checkoutdir = os.path.join(self.subdir_root, p.get('directory'))
revno = p.get('revision')