aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-12-26 13:24:30 +0200
committerGitHub <noreply@github.com>2017-12-26 13:24:30 +0200
commitac8d6087bfe1a2dacbd13d6cc9c4c526fc997fb5 (patch)
treefb443ccd4bdfa44670cc78a6b14b386cdf625a7a /mesonbuild
parent1806aac37669fe5b4a50175b7b8298f119248be3 (diff)
parenta5507404ab24c307b1ca5127b59e73759790746a (diff)
downloadmeson-ac8d6087bfe1a2dacbd13d6cc9c4c526fc997fb5.zip
meson-ac8d6087bfe1a2dacbd13d6cc9c4c526fc997fb5.tar.gz
meson-ac8d6087bfe1a2dacbd13d6cc9c4c526fc997fb5.tar.bz2
Merge pull request #2334 from mesonbuild/promotedep
Add functionality to promote nested dependencies to top level.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/interpreter.py23
-rw-r--r--mesonbuild/mesonlib.py25
-rw-r--r--mesonbuild/wrap/wraptool.py37
3 files changed, 85 insertions, 0 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 7e29b7c..444a6ee 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2224,6 +2224,7 @@ to directly access options of other subprojects.''')
# we won't actually read all the build files.
return fallback_dep
if not dep:
+ self.print_nested_info(name)
assert(exception is not None)
raise exception
@@ -2237,6 +2238,28 @@ to directly access options of other subprojects.''')
def func_disabler(self, node, args, kwargs):
return Disabler()
+ def print_nested_info(self, dependency_name):
+ message_templ = '''\nDependency %s not found but it is available in a sub-subproject.
+To use it in the current project, promote it by going in the project source
+root and issuing %s.
+
+'''
+ sprojs = mesonlib.detect_subprojects('subprojects', self.source_root)
+ if dependency_name not in sprojs:
+ return
+ found = sprojs[dependency_name]
+ if len(found) > 1:
+ suffix = 'one of the following commands'
+ else:
+ suffix = 'the following command'
+ message = message_templ % (dependency_name, suffix)
+ cmds = []
+ command_templ = 'meson wrap promote '
+ for l in found:
+ cmds.append(command_templ + l[len(self.source_root)+1:])
+ final_message = message + '\n'.join(cmds)
+ print(final_message)
+
def get_subproject_infos(self, kwargs):
fbinfo = kwargs['fallback']
check_stringlist(fbinfo)
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 9ad0668..6bf31db 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -881,6 +881,31 @@ def windows_proof_rmtree(f):
# Try one last time and throw if it fails.
shutil.rmtree(f)
+
+def detect_subprojects(spdir_name, current_dir='', result=None):
+ if result is None:
+ result = {}
+ spdir = os.path.join(current_dir, spdir_name)
+ if not os.path.exists(spdir):
+ return result
+ for trial in glob(os.path.join(spdir, '*')):
+ basename = os.path.split(trial)[1]
+ if trial == 'packagecache':
+ continue
+ append_this = True
+ if os.path.isdir(trial):
+ detect_subprojects(spdir_name, trial, result)
+ elif trial.endswith('.wrap') and os.path.isfile(trial):
+ basename = os.path.splitext(basename)[0]
+ else:
+ append_this = False
+ if append_this:
+ if basename in result:
+ result[basename].append(trial)
+ else:
+ result[basename] = [trial]
+ return result
+
class OrderedSet(collections.MutableSet):
"""A set that preserves the order in which items are added, by first
insertion.
diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py
index 79b00e0..00115cb 100644
--- a/mesonbuild/wrap/wraptool.py
+++ b/mesonbuild/wrap/wraptool.py
@@ -21,6 +21,8 @@ from glob import glob
from .wrap import API_ROOT, open_wrapdburl
+from .. import mesonlib
+
help_templ = '''This program allows you to manage your Wrap dependencies
using the online wrap database http://wrapdb.mesonbuild.com.
@@ -142,6 +144,36 @@ def info(name):
for v in versions:
print(' ', v['branch'], v['revision'])
+def do_promotion(from_path, spdir_name):
+ if os.path.isfile(from_path):
+ assert(from_path.endswith('.wrap'))
+ shutil.copy(from_path, spdir_name)
+ elif os.path.isdir(from_path):
+ sproj_name = os.path.split(from_path)[1]
+ outputdir = os.path.join(spdir_name, sproj_name)
+ if os.path.exists(outputdir):
+ sys.exit('Output dir %s already exists. Will not overwrite.' % outputdir)
+ shutil.copytree(from_path, outputdir, ignore=shutil.ignore_patterns('subprojects'))
+
+def promote(argument):
+ path_segment, subproject_name = os.path.split(argument)
+ spdir_name = 'subprojects'
+ sprojs = mesonlib.detect_subprojects(spdir_name)
+ if subproject_name not in sprojs:
+ sys.exit('Subproject %s not found in directory tree.' % subproject_name)
+ matches = sprojs[subproject_name]
+ if len(matches) == 1:
+ do_promotion(matches[0], spdir_name)
+ return
+ if path_segment == '':
+ print('There are many versions of %s in tree. Please specify which one to promote:\n' % subproject_name)
+ for s in matches:
+ print(s)
+ sys.exit(1)
+ system_native_path_argument = argument.replace('/', os.sep)
+ if system_native_path_argument in matches:
+ do_promotion(argument, spdir_name)
+
def status():
print('Subproject status')
for w in glob('subprojects/*.wrap'):
@@ -189,6 +221,11 @@ def run(args):
print('info requires exactly one argument.')
return 1
info(args[0])
+ elif command == 'promote':
+ if len(args) != 1:
+ print('promote requires exactly one argument.')
+ return 1
+ promote(args[0])
elif command == 'status':
status()
else: