Make waf fail if submodules are out of date.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 18 May 2015 20:00:30 +0000 (20:00 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 19 May 2015 17:28:19 +0000 (19:28 +0200)
Instead, suggest the user run 'git submodule update'.

This should prevent users from accidentally building Samba against
outdated or too new versions of the bundled third party libraries
after switching branches.

I've opted to make this an error rather than actually
running 'git submodule update' directly, as the latter could
cause unpredictable behaviour. If we find that manually updating
submodules is too cumbersome, we can always change this. The normal mode
of operation for developers should not involve any submodules at all,
but system versions of these libraries.

Signed-off-by: Jelmer Vernooij <jelmer@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
buildtools/wafsamba/samba_git.py
wscript

index a48ce129a98d75f8d1d787be9d15dc407720bf2b..d103aa8a60be96c247ea9770a4bbf61ce097367e 100644 (file)
@@ -1,4 +1,5 @@
 import os
+import subprocess
 
 def find_git(env=None):
     """Find the git binary."""
@@ -12,3 +13,36 @@ def find_git(env=None):
 
     return None
 
+
+def read_submodule_status(path, env=None):
+    """Check status of submodules.
+
+    :param path: Path to git directory
+    :param env: Optional waf environment
+    :return: Yields tuples with submodule relpath and status
+        (one of: 'out-of-date', 'not-checked-out', 'up-to-date')
+    :raise RuntimeError: raised when parsing of 'git submodule status' output
+        fails.
+    """
+    if not os.path.isfile(os.path.join(path, ".gitmodules")):
+        # No point in running git.
+        return
+    git = find_git(env)
+    if git is None:
+        return
+    p = subprocess.Popen([git, "submodule", "status"], stdout=subprocess.PIPE,
+        cwd=path)
+    (stdout, stderr) = p.communicate(None)
+    for l in stdout.splitlines():
+        l = l.rstrip()
+        status = l[0]
+        l = l[1:]
+        parts = l.split(" ")
+        if len(parts) > 2 and status in ("-", "+"):
+            yield (parts[1], "out-of-date")
+        elif len(parts) == 2 and status == "-":
+            yield (parts[1], "not-checked-out")
+        elif len(parts) > 2 and status == " ":
+            yield (parts[1], "up-to-date")
+        else:
+            raise RuntimeError("Unable to parse submodule status: %r, %r" % (status, parts))
diff --git a/wscript b/wscript
index 8cf22f86ac0b3b475de5997fcdb8d2f9426dcc66..7700c3219bb84483c80464453d0ce58121172b04 100644 (file)
--- a/wscript
+++ b/wscript
@@ -8,7 +8,7 @@ VERSION=None
 
 import sys, os, tempfile
 sys.path.insert(0, srcdir+"/buildtools/wafsamba")
-import wafsamba, Options, samba_dist, Scripting, Utils, samba_version
+import wafsamba, Options, samba_dist, samba_git, Scripting, Utils, samba_version
 
 
 samba_dist.DIST_DIRS('.')
@@ -225,6 +225,7 @@ def ctags(ctx):
     if os.WEXITSTATUS(status):
         raise Utils.WafError('ctags failed')
 
+
 # putting this here enabled build in the list
 # of commands in --help
 def build(bld):
@@ -320,6 +321,7 @@ def wildcard_cmd(cmd):
 
 def main():
     from samba_wildcard import wildcard_main
+
     wildcard_main(wildcard_cmd)
 Scripting.main = main
 
@@ -327,3 +329,10 @@ def reconfigure(ctx):
     '''reconfigure if config scripts have changed'''
     import samba_utils
     samba_utils.reconfigure(ctx)
+
+
+if os.path.isdir(os.path.join(srcdir, ".git")):
+    # Check if there are submodules that are checked out but out of date.
+    for submodule, status in samba_git.read_submodule_status(srcdir):
+        if status == "out-of-date":
+            raise Utils.WafError("some submodules are out of date. Please run 'git submodule update'")