diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py index 1c904ab2a5af..984bf6d968d9 100644 --- a/mesonbuild/dependencies/dub.py +++ b/mesonbuild/dependencies/dub.py @@ -5,10 +5,11 @@ from .base import ExternalDependency, DependencyException, DependencyTypeName from .pkgconfig import PkgConfigDependency -from ..mesonlib import (Popen_safe, join_args, version_compare) +from ..mesonlib import (Popen_safe, join_args, version_compare, version_compare_many) from ..options import OptionKey from ..programs import ExternalProgram from .. import mlog +from enum import Enum import re import os import json @@ -56,6 +57,8 @@ class FindTargetEntry(TypedDict): search: str artifactPath: str +DubDescriptionSource = Enum('DubDescriptionSource', ['Local', 'External']) + class DubDependency(ExternalDependency): # dub program and version class_dubbin: T.Optional[T.Tuple[ExternalProgram, str]] = None @@ -99,6 +102,8 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T. self._use_cache_describe = version_compare(dubver, '>=1.35.0') self._dub_has_build_deep = version_compare(dubver, '>=1.35.0') + self.is_found = False + if not self._search_in_cache and not self._use_cache_describe: if self.required: raise DependencyException( @@ -108,20 +113,11 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T. mlog.warning(f'DUB dependency {name} not found because Dub {dubver} ' "is not compatible with Meson. (Can't locate artifacts in DUB's cache)." ' Upgrade to Dub >= 1.35') - self.is_found = False return mlog.debug('Determining dependency {!r} with DUB executable ' '{!r}'.format(name, self.dubbin.get_path())) - # if an explicit version spec was stated, use this when querying Dub - main_pack_spec = name - if 'version' in kwargs: - version_spec = kwargs['version'] - if isinstance(version_spec, list): - version_spec = " ".join(version_spec) - main_pack_spec = f'{name}@{version_spec}' - # we need to know the target architecture dub_arch = self.compiler.arch @@ -135,37 +131,11 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T. elif dub_buildtype == 'minsize': dub_buildtype = 'release' - # A command that might be useful in case of missing DUB package - def dub_build_deep_command() -> str: - if self._dub_has_build_deep: - cmd = ['dub', 'build', '--deep'] - else: - cmd = ['dub', 'run', '--yes', 'dub-build-deep', '--'] - - return join_args(cmd + [ - main_pack_spec, - '--arch=' + dub_arch, - '--compiler=' + self.compiler.get_exelist()[-1], - '--build=' + dub_buildtype - ]) - - # Ask dub for the package - describe_cmd = [ - 'describe', main_pack_spec, '--arch=' + dub_arch, - '--build=' + dub_buildtype, '--compiler=' + self.compiler.get_exelist()[-1] - ] - ret, res, err = self._call_dubbin(describe_cmd) - - if ret != 0: - mlog.debug('DUB describe failed: ' + err) - if 'locally' in err: - mlog.error(mlog.bold(main_pack_spec), 'is not present locally. You may try the following command:') - mlog.log(mlog.bold(dub_build_deep_command())) - self.is_found = False + result = self._get_dub_description(dub_arch, dub_buildtype) + if result is None: return - + description, build_cmd, description_source = result dub_comp_id = self._ID_MAP[self.compiler.get_id()] - description: DubDescription = json.loads(res) self.compile_args = [] self.link_args = self.raw_link_args = [] @@ -204,7 +174,7 @@ def find_package_target(pkg: DubPackDesc) -> bool: mlog.error(mlog.bold(pack_id), 'not found') mlog.log('You may try the following command to install the necessary DUB libraries:') - mlog.log(mlog.bold(dub_build_deep_command())) + mlog.log(mlog.bold(build_cmd)) return False @@ -223,33 +193,45 @@ def find_package_target(pkg: DubPackDesc) -> bool: # 4. Add other build settings (imports, versions etc.) # 1 - self.is_found = False packages: T.Dict[str, DubPackDesc] = {} + found_it = False for pkg in description['packages']: packages[pkg['name']] = pkg if not pkg['active']: continue - if pkg['targetType'] == 'dynamicLibrary': - mlog.error('DUB dynamic library dependencies are not supported.') - self.is_found = False - return - # check that the main dependency is indeed a library if pkg['name'] == name: - self.is_found = True - if pkg['targetType'] not in ['library', 'sourceLibrary', 'staticLibrary']: - mlog.error(mlog.bold(name), "found but it isn't a library") - self.is_found = False + mlog.error(mlog.bold(name), "found but it isn't a static library, it is:", + pkg['targetType']) return + if self.version_reqs is not None: + ver = pkg['version'] + if not version_compare_many(ver, self.version_reqs)[0]: + mlog.error(mlog.bold(f'{name}@{ver}'), + 'does not satisfy all version requirements of:', + ' '.join(self.version_reqs)) + return + + found_it = True self.version = pkg['version'] self.pkg = pkg + if not found_it: + mlog.error(f'Could not find {name} in DUB description.') + if description_source == DubDescriptionSource.Local: + mlog.log('Make sure that the dependency is registered for your dub project by running:') + mlog.log(mlog.bold(f'dub add {name}')) + elif description_source == DubDescriptionSource.External: + # It shouldn't be possible to get here + mlog.log('Make sure that the dependency is built:') + mlog.log(mlog.bold(build_cmd)) + return + if name not in targets: - self.is_found = False if self.pkg['targetType'] == 'sourceLibrary': # source libraries have no associated targets, # but some build settings like import folders must be found from the package object. @@ -258,10 +240,7 @@ def find_package_target(pkg: DubPackDesc) -> bool: # (See openssl DUB package for example of sourceLibrary) mlog.error('DUB targets of type', mlog.bold('sourceLibrary'), 'are not supported.') else: - mlog.error('Could not find target description for', mlog.bold(main_pack_spec)) - - if not self.is_found: - mlog.error(f'Could not find {name} in DUB description') + mlog.error('Could not find target description for', mlog.bold(self.name)) return # Current impl only supports static libraries @@ -269,19 +248,17 @@ def find_package_target(pkg: DubPackDesc) -> bool: # 2 if not find_package_target(self.pkg): - self.is_found = False return # 3 for link_dep in targets[name]['linkDependencies']: pkg = packages[link_dep] if not find_package_target(pkg): - self.is_found = False return if show_buildtype_warning: mlog.log('If it is not suitable, try the following command and reconfigure Meson with', mlog.bold('--clearcache')) - mlog.log(mlog.bold(dub_build_deep_command())) + mlog.log(mlog.bold(build_cmd)) # 4 bs = targets[name]['buildSettings'] @@ -345,6 +322,60 @@ def find_package_target(pkg: DubPackDesc) -> bool: # fallback self.link_args.append('-l'+lib) + self.is_found = True + + # Get the dub description needed to resolve the dependency and a + # build command that can be used to build the dependency in case it is + # not present. + def _get_dub_description(self, dub_arch: str, dub_buildtype: str) -> T.Optional[T.Tuple[DubDescription, str, DubDescriptionSource]]: + def get_build_command() -> T.List[str]: + if self._dub_has_build_deep: + cmd = ['dub', 'build', '--deep'] + else: + cmd = ['dub', 'run', '--yes', 'dub-build-deep', '--'] + + return cmd + [ + '--arch=' + dub_arch, + '--compiler=' + self.compiler.get_exelist()[-1], + '--build=' + dub_buildtype, + ] + + # Ask dub for the package + describe_cmd = [ + 'describe', '--arch=' + dub_arch, + '--build=' + dub_buildtype, '--compiler=' + self.compiler.get_exelist()[-1] + ] + helper_build = join_args(get_build_command()) + source = DubDescriptionSource.Local + ret, res, err = self._call_dubbin(describe_cmd) + if ret == 0: + return (json.loads(res), helper_build, source) + + pack_spec = self.name + if self.version_reqs is not None: + if len(self.version_reqs) > 1: + mlog.error('Multiple version requirements are not supported for raw dub dependencies.') + mlog.error("Please specify only an exact version like '1.2.3'") + raise DependencyException('Multiple version requirements are not solvable for raw dub depencies') + if len(self.version_reqs) == 1: + pack_spec += '@' + self.version_reqs[0] + + describe_cmd = [ + 'describe', pack_spec, '--arch=' + dub_arch, + '--build=' + dub_buildtype, '--compiler=' + self.compiler.get_exelist()[-1] + ] + helper_build = join_args(get_build_command() + [pack_spec]) + source = DubDescriptionSource.External + ret, res, err = self._call_dubbin(describe_cmd) + if ret == 0: + return (json.loads(res), helper_build, source) + + mlog.debug('DUB describe failed: ' + err) + if 'locally' in err: + mlog.error(mlog.bold(pack_spec), 'is not present locally. You may try the following command:') + mlog.log(mlog.bold(helper_build)) + return + # This function finds the target of the provided JSON package, built for the right # compiler, architecture, configuration... # It returns (target|None, {compatibilities}) @@ -469,7 +500,7 @@ def _get_comp_versions_to_find(self, dub_comp_id: str) -> T.List[str]: def _call_dubbin(self, args: T.List[str], env: T.Optional[T.Dict[str, str]] = None) -> T.Tuple[int, str, str]: assert isinstance(self.dubbin, ExternalProgram) - p, out, err = Popen_safe(self.dubbin.get_command() + args, env=env) + p, out, err = Popen_safe(self.dubbin.get_command() + args, env=env, cwd=self.env.get_source_dir()) return p.returncode, out.strip(), err.strip() def _call_compbin(self, args: T.List[str], env: T.Optional[T.Dict[str, str]] = None) -> T.Tuple[int, str, str]: diff --git a/test cases/d/11 dub/meson.build b/test cases/d/11 dub/meson.build index 91955710e709..d4c6fa440191 100644 --- a/test cases/d/11 dub/meson.build +++ b/test cases/d/11 dub/meson.build @@ -17,7 +17,7 @@ test('test urld', test_exe) # If you want meson to generate/update a dub.json file dlang = import('dlang') -dlang.generate_dub_file(meson.project_name().to_lower(), meson.source_root(), +dlang.generate_dub_file(meson.project_name().to_lower(), meson.build_root(), authors: 'Meson Team', description: 'Test executable', copyright: 'Copyright © 2018, Meson Team', @@ -25,4 +25,4 @@ dlang.generate_dub_file(meson.project_name().to_lower(), meson.source_root(), sourceFiles: 'test.d', targetType: 'executable', dependencies: urld_dep -) \ No newline at end of file +) diff --git a/test cases/d/17 dub respects dub.selections.json/.gitignore b/test cases/d/17 dub respects dub.selections.json/.gitignore new file mode 100644 index 000000000000..3f5829545224 --- /dev/null +++ b/test cases/d/17 dub respects dub.selections.json/.gitignore @@ -0,0 +1 @@ +dub-respects-dub-selections-json* diff --git a/test cases/d/17 dub respects dub.selections.json/dub.json b/test cases/d/17 dub respects dub.selections.json/dub.json new file mode 100644 index 000000000000..7c8e3ec06031 --- /dev/null +++ b/test cases/d/17 dub respects dub.selections.json/dub.json @@ -0,0 +1,6 @@ +{ + "name": "dub-respects-dub-selections-json", + "dependencies": { + "urld": "2.0.2" + } +} diff --git a/test cases/d/17 dub respects dub.selections.json/dub.selections.json b/test cases/d/17 dub respects dub.selections.json/dub.selections.json new file mode 100644 index 000000000000..d5cb275d85ff --- /dev/null +++ b/test cases/d/17 dub respects dub.selections.json/dub.selections.json @@ -0,0 +1,6 @@ +{ + "fileVersion": 1, + "versions": { + "urld": "2.0.2" + } +} diff --git a/test cases/d/17 dub respects dub.selections.json/meson.build b/test cases/d/17 dub respects dub.selections.json/meson.build new file mode 100644 index 000000000000..fd50274d3f6d --- /dev/null +++ b/test cases/d/17 dub respects dub.selections.json/meson.build @@ -0,0 +1,25 @@ +project('Dub dependency respects dub.selections.json', 'd') + +dub_exe = find_program('dub', required : false) +if not dub_exe.found() + error('MESON_SKIP_TEST: Dub not found') +endif + +dub_ver = dub_exe.version() +if not dub_ver.version_compare('>=1.35.0') + error('MESON_SKIP_TEST: test requires dub >=1.35.0') +endif + +dc = meson.get_compiler('d').cmd_array()[0] +arch = host_machine.cpu_family() + +root = meson.source_root() +run_command(dub_exe, 'build', '--deep', '--compiler', dc, '--arch', arch, + '--root', root, + check: true) +urld = dependency('urld', method: 'dub') + +version = urld.version() +if version != '2.0.2' + error(f'Expected urld version to be the one selected in dub.selections.json but got @version@') +endif diff --git a/test cases/d/17 dub respects dub.selections.json/source/app.d b/test cases/d/17 dub respects dub.selections.json/source/app.d new file mode 100644 index 000000000000..d66321b3c581 --- /dev/null +++ b/test cases/d/17 dub respects dub.selections.json/source/app.d @@ -0,0 +1 @@ +void main () {} diff --git a/test cases/d/18 dub respects project root/.gitignore b/test cases/d/18 dub respects project root/.gitignore new file mode 100644 index 000000000000..d40ae8d2de4a --- /dev/null +++ b/test cases/d/18 dub respects project root/.gitignore @@ -0,0 +1 @@ +dub-respects-project-root* diff --git a/test cases/d/18 dub respects project root/dub.json b/test cases/d/18 dub respects project root/dub.json new file mode 100644 index 000000000000..b2ee577260bb --- /dev/null +++ b/test cases/d/18 dub respects project root/dub.json @@ -0,0 +1,6 @@ +{ + "name": "dub-respects-project-root", + "dependencies": { + "urld": "2.0.2" + } +} diff --git a/test cases/d/18 dub respects project root/dub.selections.json b/test cases/d/18 dub respects project root/dub.selections.json new file mode 100644 index 000000000000..d5cb275d85ff --- /dev/null +++ b/test cases/d/18 dub respects project root/dub.selections.json @@ -0,0 +1,6 @@ +{ + "fileVersion": 1, + "versions": { + "urld": "2.0.2" + } +} diff --git a/test cases/d/18 dub respects project root/meson.build b/test cases/d/18 dub respects project root/meson.build new file mode 100644 index 000000000000..d0d1cdd0a2ce --- /dev/null +++ b/test cases/d/18 dub respects project root/meson.build @@ -0,0 +1,16 @@ +project('Dub describes project root', 'd') + +dub_exe = find_program('dub', required : false) +if not dub_exe.found() + error('MESON_SKIP_TEST: Dub not found') +endif + +dub_ver = dub_exe.version() +if not dub_ver.version_compare('>=1.35.0') + error('MESON_SKIP_TEST: test requires dub >=1.35.0') +endif + +dc = meson.get_compiler('d').cmd_array()[0] +arch = host_machine.cpu_family() + +subdir('x/y/z') diff --git a/test cases/d/18 dub respects project root/source/app.d b/test cases/d/18 dub respects project root/source/app.d new file mode 100644 index 000000000000..d66321b3c581 --- /dev/null +++ b/test cases/d/18 dub respects project root/source/app.d @@ -0,0 +1 @@ +void main () {} diff --git a/test cases/d/18 dub respects project root/x/y/z/dub.json b/test cases/d/18 dub respects project root/x/y/z/dub.json new file mode 100644 index 000000000000..0442acb863e0 --- /dev/null +++ b/test cases/d/18 dub respects project root/x/y/z/dub.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "urld": "~>3.0.1" + }, + "name": "dub-respects-project-root-subdir" +} diff --git a/test cases/d/18 dub respects project root/x/y/z/dub.selections.json b/test cases/d/18 dub respects project root/x/y/z/dub.selections.json new file mode 100644 index 000000000000..a7acd78516f4 --- /dev/null +++ b/test cases/d/18 dub respects project root/x/y/z/dub.selections.json @@ -0,0 +1,6 @@ +{ + "fileVersion": 1, + "versions": { + "urld": "3.0.1" + } +} diff --git a/test cases/d/18 dub respects project root/x/y/z/meson.build b/test cases/d/18 dub respects project root/x/y/z/meson.build new file mode 100644 index 000000000000..a4a1420ac441 --- /dev/null +++ b/test cases/d/18 dub respects project root/x/y/z/meson.build @@ -0,0 +1,10 @@ +root = meson.source_root() +run_command(dub_exe, 'build', '--deep', '--compiler', dc, '--arch', arch, + '--root', root, + check: true) +urld = dependency('urld', method: 'dub') + +version = urld.version() +if version != '2.0.2' + error(f'Expected urld version to be the one selected in "@root@/dub.selections.json" but got @version@') +endif diff --git a/test cases/d/19 dub configured dependency/.gitignore b/test cases/d/19 dub configured dependency/.gitignore new file mode 100644 index 000000000000..c61a31998422 --- /dev/null +++ b/test cases/d/19 dub configured dependency/.gitignore @@ -0,0 +1 @@ +lib19-this-package* diff --git a/test cases/d/19 dub configured dependency/dub.json b/test cases/d/19 dub configured dependency/dub.json new file mode 100644 index 000000000000..f4e6db25496e --- /dev/null +++ b/test cases/d/19 dub configured dependency/dub.json @@ -0,0 +1,25 @@ +{ + "name": "19-this-package", + "subPackages": [ + { + "name": "dep", + "configurations": [ + { + "name": "default", + "targetType": "library" + }, + { + "name": "custom", + "targetType": "library" + } + ] + } + ], + "dependencies": { + ":dep": "*" + }, + "subConfigurations": { + "19-this-package:dep": "custom" + }, + "targetType": "library" +} diff --git a/test cases/d/19 dub configured dependency/dub.selections.json b/test cases/d/19 dub configured dependency/dub.selections.json new file mode 100644 index 000000000000..34876737fba0 --- /dev/null +++ b/test cases/d/19 dub configured dependency/dub.selections.json @@ -0,0 +1,6 @@ +{ + "fileVersion": 1, + "versions": { + "inifiled": "2.0.0" + } +} diff --git a/test cases/d/19 dub configured dependency/meson.build b/test cases/d/19 dub configured dependency/meson.build new file mode 100644 index 000000000000..89e07aad0025 --- /dev/null +++ b/test cases/d/19 dub configured dependency/meson.build @@ -0,0 +1,45 @@ +project('Dub dependency respects dub.selections.json', 'd') + +dub_exe = find_program('dub', required : false) +if not dub_exe.found() + error('MESON_SKIP_TEST: Dub not found') +endif + +dub_ver = dub_exe.version() +if not dub_ver.version_compare('>=1.35.0') + error('MESON_SKIP_TEST: test requires dub >=1.35.0') +endif + +dc = meson.get_compiler('d').cmd_array()[0] +arch = host_machine.cpu_family() + +# Test that the dependency resolution will only find dub packages as +# described in dub.json. In this case we test that the configurations +# must match. + +# 1. clean all built artifacts for this package + +root = meson.source_root() +run_command(dub_exe, 'clean', '--root', root, + check: true) + +# 2. Compile the dependency with the wrong configuration +# (dub.json expectes '--config custom') +run_command(dub_exe, 'build', '--deep', '--compiler', dc, '--arch', arch, + '--root', root, ':dep', '--config', 'default', + check: true) +bad_configuration = dependency('19-this-package:dep', method: 'dub', required: false) + +if bad_configuration.found() + error('Dependecy should not have been found because it is not built with the proper configuration') +endif + +# 3. Compile the dependency with the right configuration +# For caching reasons, the names provided to `dependency()` must differ. +run_command(dub_exe, 'build', '--deep', '--compiler', dc, '--arch', arch, + '--root', root, + check: true) +good_configuration = dependency('19-this-package', method: 'dub', required: false) +if not good_configuration.found() + error('Did not find dependecy after build with the proper configuration') +endif diff --git a/test cases/d/19 dub configured dependency/source/app.d b/test cases/d/19 dub configured dependency/source/app.d new file mode 100644 index 000000000000..d66321b3c581 --- /dev/null +++ b/test cases/d/19 dub configured dependency/source/app.d @@ -0,0 +1 @@ +void main () {} diff --git a/test cases/d/20 dub dependency multiple version reqs/.gitignore b/test cases/d/20 dub dependency multiple version reqs/.gitignore new file mode 100644 index 000000000000..6b10c73f2fe0 --- /dev/null +++ b/test cases/d/20 dub dependency multiple version reqs/.gitignore @@ -0,0 +1 @@ +20-vers-reqs* diff --git a/test cases/d/20 dub dependency multiple version reqs/dub.json b/test cases/d/20 dub dependency multiple version reqs/dub.json new file mode 100644 index 000000000000..902776681038 --- /dev/null +++ b/test cases/d/20 dub dependency multiple version reqs/dub.json @@ -0,0 +1,6 @@ +{ + "name": "20-vers-reqs", + "dependencies": { + "urld": "==3.0.1" + } +} diff --git a/test cases/d/20 dub dependency multiple version reqs/dub.selections.json b/test cases/d/20 dub dependency multiple version reqs/dub.selections.json new file mode 100644 index 000000000000..a7acd78516f4 --- /dev/null +++ b/test cases/d/20 dub dependency multiple version reqs/dub.selections.json @@ -0,0 +1,6 @@ +{ + "fileVersion": 1, + "versions": { + "urld": "3.0.1" + } +} diff --git a/test cases/d/20 dub dependency multiple version reqs/meson.build b/test cases/d/20 dub dependency multiple version reqs/meson.build new file mode 100644 index 000000000000..7c0497e5e989 --- /dev/null +++ b/test cases/d/20 dub dependency multiple version reqs/meson.build @@ -0,0 +1,20 @@ +project('Dub dependency with multiple version requirements', 'd') + +dub_exe = find_program('dub', required : false) +if not dub_exe.found() + error('MESON_SKIP_TEST: Dub not found') +endif + +dub_ver = dub_exe.version() +if not dub_ver.version_compare('>=1.35.0') + error('MESON_SKIP_TEST: test requires dub >=1.35.0') +endif + +dc = meson.get_compiler('d').cmd_array()[0] +arch = host_machine.cpu_family() + +root = meson.source_root() +run_command(dub_exe, 'build', '--deep', '--compiler', dc, '--arch', arch, + '--root', root, + check: true) +urld = dependency('urld', method: 'dub', version: [ '<3.1.0', '>=3.0.0', '>2.9.9' ]) diff --git a/test cases/d/20 dub dependency multiple version reqs/source/app.d b/test cases/d/20 dub dependency multiple version reqs/source/app.d new file mode 100644 index 000000000000..d66321b3c581 --- /dev/null +++ b/test cases/d/20 dub dependency multiple version reqs/source/app.d @@ -0,0 +1 @@ +void main () {} diff --git a/test cases/failing/132 dub missing dependency/dub.json b/test cases/failing/132 dub missing dependency/dub.json new file mode 100644 index 000000000000..1ad9ddcc1f19 --- /dev/null +++ b/test cases/failing/132 dub missing dependency/dub.json @@ -0,0 +1,3 @@ +{ + "name": "132-missing-dep" +} diff --git a/test cases/failing/132 dub missing dependency/dub.selections.json b/test cases/failing/132 dub missing dependency/dub.selections.json new file mode 100644 index 000000000000..322586b10676 --- /dev/null +++ b/test cases/failing/132 dub missing dependency/dub.selections.json @@ -0,0 +1,5 @@ +{ + "fileVersion": 1, + "versions": { + } +} diff --git a/test cases/failing/132 dub missing dependency/meson.build b/test cases/failing/132 dub missing dependency/meson.build new file mode 100644 index 000000000000..fcccb3b415d4 --- /dev/null +++ b/test cases/failing/132 dub missing dependency/meson.build @@ -0,0 +1,17 @@ +project('Dub dependency not in dub.json') + +if not add_languages('d', required: false) + error('MESON_SKIP_TEST test requires D compiler') +endif + +dub_exe = find_program('dub', required : false) +if not dub_exe.found() + error('MESON_SKIP_TEST: Dub not found') +endif + +dub_ver = dub_exe.version() +if not dub_ver.version_compare('>=1.35.0') + error('MESON_SKIP_TEST: test requires dub >=1.35.0') +endif + +dep = dependency('urld', method: 'dub') # not in dub.json diff --git a/test cases/failing/132 dub missing dependency/source/app.d b/test cases/failing/132 dub missing dependency/source/app.d new file mode 100644 index 000000000000..d66321b3c581 --- /dev/null +++ b/test cases/failing/132 dub missing dependency/source/app.d @@ -0,0 +1 @@ +void main () {} diff --git a/test cases/failing/132 dub missing dependency/test.json b/test cases/failing/132 dub missing dependency/test.json new file mode 100644 index 000000000000..e58dbc7aabee --- /dev/null +++ b/test cases/failing/132 dub missing dependency/test.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + { + "line": "test cases/failing/132 dub missing dependency/meson.build:17:6: ERROR: Dependency \"urld\" not found", + "line": "dub add urld" + } + ] +}