From 4a3ea628b0fe796de87156d7e5630a77c82cfdb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@mi.fu-berlin.de>
Date: Wed, 9 Dec 2020 23:55:55 +0000
Subject: [PATCH] [python] Add support for --module=mod to bin/setup-dunepy.py

This adds an optional parameter `--module=mod` to `setup-dunepy.py`.
If this parameter is passed, only `mod` and its dependencies are
used as dependencies of the newly created dune-py module. This allows
to do
```
dunecontrol --opts=my.opts --module=foo all
setup-dunepy.py --opts=my.opts --module=foo install
```
which would otherwise fail if `setup-dunepy.py` tries to process
found modules that have not been build by `dunecontrol`. If the
option is not passed all found modules are used as dependencies
as before.
---
 bin/setup-dunepy.py          | 32 ++++++++++++++++++++++++--------
 python/dune/common/module.py | 11 +++++++----
 2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/bin/setup-dunepy.py b/bin/setup-dunepy.py
index dfb5bc6f7..9a3455a72 100755
--- a/bin/setup-dunepy.py
+++ b/bin/setup-dunepy.py
@@ -10,14 +10,14 @@ import logging
 logger = logging.getLogger(__name__)
 
 try:
-    from dune.common.module import build_dune_py_module, get_dune_py_dir, make_dune_py_module, select_modules
+    from dune.common.module import build_dune_py_module, get_dune_py_dir, make_dune_py_module, select_modules, resolve_dependencies
 except ImportError:
     import os
     here = os.path.dirname(os.path.abspath(__file__))
     mods = os.path.join(os.path.dirname(here), "python", "dune", "common")
     if os.path.exists(os.path.join(mods, "module.py")):
         sys.path.append(mods)
-        from module import build_dune_py_module, get_dune_py_dir, make_dune_py_module, select_modules
+        from module import build_dune_py_module, get_dune_py_dir, make_dune_py_module, select_modules, resolve_dependencies
     else:
         raise
 
@@ -32,13 +32,14 @@ def toBuildDir(builddir, moddir, module):
 
 def main(argv):
     try:
-        opts, args = getopt.getopt(argv,"ho",["opts=","builddir="])
+        opts, args = getopt.getopt(argv,"ho",["opts=","builddir=","module="])
     except getopt.GetoptError:
-        print('usage: setup-dunepy.py [-o config.opts | --opts=config.opts | --builddir] [install]')
+        print('usage: setup-dunepy.py [-o config.opts | --opts=config.opts | --builddir] [--module=mod] [install]')
         sys.exit(2)
 
     optsfile = None
     builddir = None
+    masterModule = None
     for opt, arg in opts:
         if opt == '-h':
             print('usage: setup-dunepy.py [-o config.opts | --opts=config.opts] [install]')
@@ -47,6 +48,8 @@ def main(argv):
             optsfile = arg
         elif opt in ("--builddir"):
             builddir = arg
+        elif opt in ("--module"):
+            masterModule = arg
     if len(args) > 0:
         execute = args[0]
     else:
@@ -85,7 +88,20 @@ def main(argv):
 
     if os.path.exists(dunepy):
         shutil.rmtree(dunepy)
-    foundModule = make_dune_py_module(dunepy)
+
+    # Generate list of all modules
+    duneModules = select_modules()
+
+    # Generate list of dependencies for dune-py. If --module=mod is passed,
+    # use mod and all its dependencies only. Otherwise use all found modules
+    # as dependencies.
+    if masterModule is None:
+        deps = [m[0] for m in duneModules[0].items()]
+    else:
+        deps = resolve_dependencies(duneModules[0], masterModule)
+        deps.add(masterModule)
+
+    foundModule = make_dune_py_module(dunepy, deps)
 
     output = build_dune_py_module(dunepy, definitions, None, builddir)
 
@@ -98,9 +114,9 @@ def main(argv):
     f.close()
 
     if execute == "install":
-        duneModules = select_modules()
-        # moddir = duneModules[1]["dune-python"]
-        for m,depends in duneModules[0].items():
+        if deps is None:
+            deps = duneModules[0].items()
+        for m in deps:
             moddir = duneModules[1][m]
             pythonModule = toBuildDir(builddir,moddir,m)
             print("calling install_python in",moddir)
diff --git a/python/dune/common/module.py b/python/dune/common/module.py
index daea5826a..1fbbda8ef 100644
--- a/python/dune/common/module.py
+++ b/python/dune/common/module.py
@@ -522,7 +522,7 @@ def get_cmake_definitions():
     return definitions
 
 
-def make_dune_py_module(dune_py_dir=None):
+def make_dune_py_module(dune_py_dir=None, deps=None):
     if dune_py_dir is None:
         dune_py_dir = get_dune_py_dir()
     os.makedirs(dune_py_dir, exist_ok=True)
@@ -550,9 +550,12 @@ def make_dune_py_module(dune_py_dir=None):
             file.write('#define USING_DUNE_PYTHON 1\n\n')
             file.write('\n#include "generated_module.hh"\n')
 
-        modules, _ = select_modules()
-        description = Description(module='dune-py', version=get_dune_py_version(),  maintainer='dune@lists.dune-project.org', depends=list(modules.values()))
-        logger.debug('dune-py will depend on ' + ' '.join([m + (' ' + str(c) if c else '') for m, c in description.depends]))
+        if deps is None:
+            modules, _ = select_modules()
+            deps = modules.values()
+
+        description = Description(module='dune-py', version=get_dune_py_version(),  maintainer='dune@lists.dune-project.org', depends=list(deps))
+        logger.debug('dune-py will depend on ' + ' '.join([m[0] + (' ' + str(c) if c else '') for m, c in description.depends]))
         project.make_project(dune_py_dir, description,
                 subdirs=[generated_dir_rel], is_dunepy=True)
     else:
-- 
GitLab