diff --git a/source/dub/dependencyresolver.d b/source/dub/dependencyresolver.d index 8a6414d..b5776a6 100644 --- a/source/dub/dependencyresolver.d +++ b/source/dub/dependencyresolver.d @@ -64,6 +64,8 @@ return p[0 .. idx]; } + auto root_base_pack = rootPackage(root.pack); + size_t[string] package_indices; CONFIG[][] all_configs; bool[TreeNode] visited; @@ -80,7 +82,7 @@ pidx = *pi; configs = all_configs[*pi]; } else { - if (basepack == root.pack) configs = [root.config]; + if (basepack == root_base_pack) configs = [root.config]; else configs = getAllConfigs(basepack); all_configs ~= configs; package_indices[basepack] = pidx; @@ -124,20 +126,19 @@ // get the current config/version of the current dependency sizediff_t childidx = package_indices[basepack]; if (!all_configs[childidx].length) { - enforce(parentbase != root.pack, format("Root package %s contains reference to invalid package %s", parent.pack, ch.pack)); + enforce(parentbase != root_base_pack, format("Root package %s contains reference to invalid package %s", parent.pack, ch.pack)); // choose another parent config to avoid the invalid child if (parentidx > maxcpi) { error = format("Package %s contains invalid dependency %s", parent.pack, ch.pack); logDiagnostic("%s (ci=%s)", error, parentidx); maxcpi = parentidx; } - enforce(parent != root, "Invalid dependecy %s referenced by the root package."); } else { auto config = all_configs[childidx][config_indices[childidx]]; auto chnode = TreeNode(ch.pack, config); if (!matches(ch.configs, config)) { // if we are at the root level, we can safely skip the maxcpi computation and instead choose another childidx config - if (parent == root) { + if (parentbase == root_base_pack) { error = format("No match for dependency %s %s of %s", ch.pack, ch.configs, parent.pack); return childidx; } diff --git a/source/dub/dub.d b/source/dub/dub.d index b70c223..93b1b3e 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -738,8 +738,22 @@ logDebug("Invalid package in dependency tree: %s %s", node.pack, node.config); return null; } + auto basepack = pack.basePackage; + foreach (dname, dspec; pack.dependencies) { auto dbasename = getBasePackageName(dname); + + // detect dependencies to the root package (or sub packages thereof) + if (dbasename == basepack.name) { + auto absdeppath = dspec.mapToPath(pack.path).path; + auto desireddeppath = dname == dbasename ? basepack.path : basepack.getSubPackage(getSubPackageName(dname)).path; + enforce(dspec.path.empty || absdeppath == desireddeppath, + format("Dependency from %s to root package references wrong path: %s vs. %s", + node.pack, absdeppath.toNativeString(), desireddeppath.toNativeString())); + ret ~= TreeNodes(dname, node.config); + continue; + } + if (dspec.optional && !m_dub.packageManager.getFirstPackage(dname)) continue; if (m_options & UpgradeOptions.upgrade || !m_selectedVersions || !m_selectedVersions.hasSelectedVersion(dbasename))