diff --git a/source/dub/commandline.d b/source/dub/commandline.d index b400dcf..6027461 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -986,7 +986,7 @@ ]); } - protected void setupPackage(Dub dub, string package_name, string default_build_type = "debug") + protected void setupPackage(Dub dub, string package_name, string default_build_type = "debug", Version ver = Version.unknown) { if (!m_compilerName.length) m_compilerName = dub.defaultCompiler; if (!m_arch.length) m_arch = dub.defaultArchitecture; @@ -995,7 +995,7 @@ m_buildSettings.addDebugVersions(m_debugVersions); m_defaultConfig = null; - enforce (loadSpecificPackage(dub, package_name), "Failed to load package."); + enforce (loadSpecificPackage(dub, package_name, ver), "Failed to load package."); if (m_buildConfig.length != 0 && !dub.configurations.canFind(m_buildConfig)) { @@ -1030,7 +1030,7 @@ } } - private bool loadSpecificPackage(Dub dub, string package_name) + private bool loadSpecificPackage(Dub dub, string package_name, Version ver) { if (m_single) { enforce(package_name.length, "Missing file name of single-file package."); @@ -1052,7 +1052,9 @@ enforce(package_name.length, "No valid root package found - aborting."); - auto pack = dub.packageManager.getFirstPackage(package_name); + auto pack = ver.isUnknown + ? dub.packageManager.getLatestPackage(package_name) + : dub.packageManager.getPackage(package_name, ver); enforce(pack, "Failed to find a package named '"~package_name~"' locally."); logInfo("Building package %s in %s", pack.name, pack.path.toNativeString()); dub.loadPackage(pack); @@ -1113,17 +1115,19 @@ override int execute(Dub dub, string[] free_args, string[] app_args) { - string package_name; + PackageAndVersion package_info; if (!m_generator.length) { enforceUsage(free_args.length >= 1 && free_args.length <= 2, "Expected one or two arguments."); m_generator = free_args[0]; - if (free_args.length >= 2) package_name = free_args[1]; + if (free_args.length >= 2) package_info = splitPackageName(free_args[1]); } else { enforceUsage(free_args.length <= 1, "Expected one or zero arguments."); - if (free_args.length >= 1) package_name = free_args[0]; + if (free_args.length >= 1) package_info = splitPackageName(free_args[0]); } - setupPackage(dub, package_name); + string package_name = package_info.name; + Version package_version = package_info.version_.length == 0 ? Version.unknown : Version(package_info.version_); + setupPackage(dub, package_name, "debug", package_version); if (m_printBuilds) { // FIXME: use actual package data logInfo("Available build types:"); @@ -1209,7 +1213,6 @@ const packageParts = splitPackageName(free_args[0]); if (auto rc = fetchMissingPackages(dub, packageParts)) return rc; - free_args[0] = packageParts.name; } return super.execute(dub, free_args, app_args); } @@ -1364,7 +1367,7 @@ enforceUsage(free_args.length <= 1, "Expected one or zero arguments."); if (free_args.length >= 1) package_name = free_args[0]; - setupPackage(dub, package_name, "unittest"); + setupPackage(dub, package_name, "unittest", Version.unknown); GeneratorSettings settings; settings.platform = m_buildPlatform; @@ -2699,6 +2702,7 @@ // https://github.com/dlang/dub/issues/1681 assert(splitPackageName("") == PackageAndVersion("", null)); + assert(splitPackageName("foo") == PackageAndVersion("foo", null)); assert(splitPackageName("foo=1.0.1") == PackageAndVersion("foo", "1.0.1")); assert(splitPackageName("foo@1.0.1") == PackageAndVersion("foo", "1.0.1")); assert(splitPackageName("foo@==1.0.1") == PackageAndVersion("foo", "==1.0.1")); diff --git a/source/dub/packagemanager.d b/source/dub/packagemanager.d index 76c2e0c..a4a23f2 100644 --- a/source/dub/packagemanager.d +++ b/source/dub/packagemanager.d @@ -188,9 +188,10 @@ /// ditto Package getPackage(string name, Version ver, NativePath path) { - auto ret = getPackage(name, path); - if (!ret || ret.version_ != ver) return null; - return ret; + foreach (p; getPackageIterator(name)) + if (p.version_ == ver && p.path.startsWith(path)) + return p; + return null; } /// ditto @@ -218,6 +219,17 @@ return null; } + /** Looks up the latest package matching the given name. + */ + Package getLatestPackage(string name) + { + Package pkg; + foreach (ep; getPackageIterator(name)) + if (pkg is null || pkg.version_ < ep.version_) + pkg = ep; + return pkg; + } + /** For a given package path, returns the corresponding package. If the package is already loaded, a reference is returned. Otherwise diff --git a/test/issue1040-run-with-ver.sh b/test/issue1040-run-with-ver.sh new file mode 100755 index 0000000..db3ea12 --- /dev/null +++ b/test/issue1040-run-with-ver.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +. $(dirname "${BASH_SOURCE[0]}")/common.sh + +if ! [ -d ${CURR_DIR}/issue1040-tmpdir ]; then + mkdir ${CURR_DIR}/issue1040-tmpdir + touch ${CURR_DIR}/issue1040-tmpdir/.no_build + touch ${CURR_DIR}/issue1040-tmpdir/.no_run + touch ${CURR_DIR}/issue1040-tmpdir/.no_test + function cleanup { + rm -rf ${CURR_DIR}/issue1040-tmpdir + } + trap cleanup EXIT +fi + +cd ${CURR_DIR}/issue1040-tmpdir + +$DUB fetch dub@1.17.0 --cache=local +$DUB fetch dub@1.18.0 --cache=local +$DUB fetch dub@1.19.0 --cache=local + +if { $DUB fetch dub@1.18.0 --cache=local || true; } | grep -cF 'Fetching' > /dev/null; then + die $LINENO 'Test for doubly fetch of the specified version has failed.' +fi +if ! { $DUB run dub -q --cache=local -- --version || true; } | grep -cF 'DUB version 1.19.0' > /dev/null; then + die $LINENO 'Test for selection of the latest fetched version has failed.' +fi +if ! { $DUB run dub@1.18.0 -q --cache=local -- --version || true; } | grep -cF 'DUB version 1.18.0' > /dev/null; then + die $LINENO 'Test for selection of the specified version has failed.' +fi