diff --git a/source/dub/dependency.d b/source/dub/dependency.d index d7a8681..2cb70b5 100644 --- a/source/dub/dependency.d +++ b/source/dub/dependency.d @@ -576,7 +576,7 @@ private void forAllDependencies(void delegate (const PkgType* avail, string pkgId, Dependency d, const Package issuer) dg) const { foreach(string issuerPackag, issuer; m_packages) { foreach(string depPkg, dependency; issuer.dependencies) { - auto availPkg = depPkg in m_packages; + auto availPkg = depPkg.getBasePackage() in m_packages; dg(availPkg, depPkg, dependency, issuer); } } @@ -689,7 +689,9 @@ Package r_master = new Package(R_json); auto graph = new DependencyGraph(r_master); + // See #100, a dependency on a subpackage should only refer the base + // project. auto missing = graph.missing(); - //assert(missing.length == 0); + assert(missing.length == 0); } } \ No newline at end of file diff --git a/source/dub/package_.d b/source/dub/package_.d index 5cce361..963b0d7 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -719,8 +719,15 @@ } } - +// @deprecated (move to private?) string[] getSubPackagePath(string package_name) { return package_name.split(":"); -} \ No newline at end of file +} + +// Returns the name of the base package in the case of some sub package or the +// package itself, if it is already a full package. +string getBasePackage(string package_name) +{ + return package_name.getSubPackagePath()[0]; +} diff --git a/source/dub/project.d b/source/dub/project.d index c33abcb..586890f 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -413,7 +413,7 @@ } auto graph = new DependencyGraph(m_main); - if(!gatherMissingDependencies(packageSuppliers, graph) || graph.missing().length > 0) { + if(!gatherMissingDependencies(packageSuppliers, graph) || graph.missing().length > 0) { // Check the conflicts first. auto conflicts = graph.conflicted(); if(conflicts.length > 0) { @@ -421,6 +421,7 @@ Action[] actions; foreach( string pkg, dbp; graph.conflicted()) actions ~= Action.conflict(pkg, dbp.dependency, dbp.packages); + // Missing dependencies could have some bogus results, therefore // return only the conflicts. return actions; @@ -452,8 +453,9 @@ // Check against installed and add install actions Action[] actions; + int[string] upgradePackages; foreach( string pkg, d; graph.needed() ) { - auto basepkg = pkg.getSubPackagePath()[0]; + auto basepkg = pkg.getBasePackage(); auto p = basepkg in installed; // TODO: auto update to latest head revision if(!p || (!d.dependency.matches(p.vers) && !d.dependency.matches(Version.MASTER))) { @@ -462,8 +464,13 @@ actions ~= Action.install(basepkg, InstallLocation.userWide, d.dependency, d.packages); } else { logDiagnostic("Required package '"~basepkg~"' found with version '"~p.vers~"'"); - if( option & UpdateOptions.Upgrade ) - actions ~= Action.install(basepkg, InstallLocation.userWide, d.dependency, d.packages); + if( option & UpdateOptions.Upgrade ) { + // Only add one upgrade action for each package. + if(basepkg !in upgradePackages) { + upgradePackages[basepkg] = 1; + actions ~= Action.install(basepkg, InstallLocation.userWide, d.dependency, d.packages); + } + } } }