From 02bb37446d640f34ac036253a7772d24d251e5b8 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Tue, 13 Feb 2024 22:22:16 +0100 Subject: [PATCH] Fix dub dependency selection --- source/served/commands/dub.d | 72 ++++++++----------- test/tc_dub_dependencies/source/app.d | 37 ++++++++-- workspace-d/source/workspaced/com/dub.d | 31 ++++++-- .../workspaced/com/snippets/dependencies.d | 9 +-- 4 files changed, 91 insertions(+), 58 deletions(-) diff --git a/source/served/commands/dub.d b/source/served/commands/dub.d index cb6305b8..7584e1c2 100644 --- a/source/served/commands/dub.d +++ b/source/served/commands/dub.d @@ -271,8 +271,11 @@ void onDidSaveDubRecipe(DidSaveTextDocumentParams params) return; } - rpc.window.runOrMessage(backend.get!DubComponent(workspaceRoot) - .selectAndDownloadMissing(), MessageType.warning, translate!"d.ext.dubUpgradeFail"); + rpc.window.runOrMessage({ + DubComponent dub = backend.get!DubComponent(workspaceRoot); + dub.updateImportPaths(true); + dub.selectAndDownloadMissing(); + }(), MessageType.warning, translate!"d.ext.dubUpgradeFail"); } else { @@ -285,7 +288,7 @@ void onDidSaveDubRecipe(DidSaveTextDocumentParams params) setTimeout({ const successfulUpdate = rpc.window.runOrMessage(backend.get!DubComponent(workspaceRoot) - .updateImportPaths(true), MessageType.warning, translate!"d.ext.dubImportFail"); + .updateImportPaths(false), MessageType.warning, translate!"d.ext.dubImportFail"); if (successfulUpdate) { rpc.window.runOrMessage(updateImports(UpdateImportsParams(false)), @@ -312,7 +315,7 @@ void onDidSaveDubRecipe(DidSaveTextDocumentParams params) if (backend.attach(backend.getInstance(workspaceRoot), "dub", err)) { rpc.window.runOrMessage(backend.get!DubComponent(workspaceRoot) - .updateImportPaths(true), MessageType.warning, + .updateImportPaths(false), MessageType.warning, translate!"d.ext.dubRecipeMaybeBroken"); error(err); } @@ -329,62 +332,49 @@ DubDependency[] listDependencies(ListDependenciesParams params) if (!instance.has!DubComponent) return ret; - auto allDeps = instance.get!DubComponent.dependencies; - auto failed = instance.get!DubComponent.failedPackages; + auto dub = instance.get!DubComponent; + auto failed = dub.failedPackages; if (!params.packageName.length) { - auto deps = instance.get!DubComponent.rootDependencies; + auto deps = dub.rootDependencies; foreach (dep; deps) { DubDependency r; r.name = dep; r.failed = failed.canFind(dep); r.root = true; - foreach (other; allDeps) - if (other.name == dep) - { - r.version_ = other.ver; - r.path = other.path; - r.description = other.description; - r.homepage = other.homepage; - r.authors = other.authors; - r.copyright = other.copyright; - r.license = other.license; - r.subPackages = other.subPackages.map!"a.name".array; - r.hasDependencies = other.dependencies.length > 0; - break; - } + auto other = dub.getPackageInfo(dep); + r.version_ = other.ver; + r.path = other.path; + r.description = other.description; + r.homepage = other.homepage; + r.authors = other.authors; + r.copyright = other.copyright; + r.license = other.license; + r.subPackages = other.subPackages.map!"a.name".array; + r.hasDependencies = other.dependencies.length > 0; ret ~= r; } } else { - string[string] aa; - foreach (other; allDeps) - if (other.name == params.packageName) - { - aa = other.dependencies; - break; - } + auto info = dub.getPackageInfo(params.packageName); + string[string] aa = info.dependencies; foreach (name, ver; aa) { DubDependency r; r.name = name; r.failed = failed.canFind(name); r.version_ = ver; - foreach (other; allDeps) - if (other.name == name) - { - r.path = other.path; - r.description = other.description; - r.homepage = other.homepage; - r.authors = other.authors; - r.copyright = other.copyright; - r.license = other.license; - r.subPackages = other.subPackages.map!"a.name".array; - r.hasDependencies = other.dependencies.length > 0; - break; - } + auto other = dub.getPackageInfo(name); + r.path = other.path; + r.description = other.description; + r.homepage = other.homepage; + r.authors = other.authors; + r.copyright = other.copyright; + r.license = other.license; + r.subPackages = other.subPackages.map!"a.name".array; + r.hasDependencies = other.dependencies.length > 0; ret ~= r; } } diff --git a/test/tc_dub_dependencies/source/app.d b/test/tc_dub_dependencies/source/app.d index 810783d0..0da4dc08 100644 --- a/test/tc_dub_dependencies/source/app.d +++ b/test/tc_dub_dependencies/source/app.d @@ -12,30 +12,53 @@ import workspaced.com.dub; void main() { + { + import std.logger; + globalLogLevel = LogLevel.trace; + static if (__VERSION__ < 2101) + sharedLog = new FileLogger(stderr); + else + sharedLog = (() @trusted => cast(shared) new FileLogger(stderr))(); + } + string dir = buildNormalizedPath(fs.getcwd, "project"); + + fs.write(buildPath(dir, "dub.sdl"), "name \"project\"\n"); + scope backend = new WorkspaceD(); backend.addInstance(dir); backend.register!DubComponent; + import dub.internal.logging : LogLevel, setLogLevel; + setLogLevel(LogLevel.debug_); + version (Posix) + { if (fs.exists(expandTilde(`~/.dub/packages/gitcompatibledubpackage-1.0.4/`))) fs.rmdirRecurse(expandTilde(`~/.dub/packages/gitcompatibledubpackage-1.0.4/`)); + if (fs.exists(expandTilde(`~/.dub/packages/gitcompatibledubpackage/1.0.4/`))) + fs.rmdirRecurse(expandTilde(`~/.dub/packages/gitcompatibledubpackage/1.0.4/`)); + } auto dub = backend.get!DubComponent(dir); - dub.upgradeAndSelectAll(); - assert(dub.dependencies.length == 0); + assert(dub.rootDependencies.length == 0); + dub.selectAndDownloadMissing(); + assert(dub.rootDependencies.length == 0); fs.write(buildPath(dir, "dub.sdl"), "name \"project\"\ndependency \"gitcompatibledubpackage\" version=\"1.0.4\"\n"); - assert(dub.dependencies.length == 0); dub.updateImportPaths(); - assert(dub.dependencies.length == 1); - assert(dub.dependencies[0].name == "gitcompatibledubpackage"); + assert(dub.missingDependencies.length == 1); + assert(dub.rootDependencies.length == 1); + dub.selectAndDownloadMissing(); + assert(dub.missingDependencies.length == 0); + assert(dub.rootDependencies.length == 1); + assert(dub.rootDependencies[0] == "gitcompatibledubpackage"); fs.write(buildPath(dir, "dub.sdl"), "name \"project\"\n"); - assert(dub.dependencies.length == 1); + assert(dub.rootDependencies.length == 1); dub.updateImportPaths(); - assert(dub.dependencies.length == 0); + assert(dub.rootDependencies.length == 0); } diff --git a/workspace-d/source/workspaced/com/dub.d b/workspace-d/source/workspaced/com/dub.d index 5d4f59ee..3a3fd0fc 100644 --- a/workspace-d/source/workspaced/com/dub.d +++ b/workspace-d/source/workspaced/com/dub.d @@ -47,10 +47,7 @@ class DubComponent : ComponentWrapper static void registered() { - static if (__traits(compiles, { import dub.internal.logging; })) - import dub.internal.logging; - else - import dub.internal.vibecompat.core.log; + import dub.internal.logging; setLogLevel(LogLevel.none); } @@ -319,6 +316,9 @@ class DubComponent : ComponentWrapper void upgrade(UpgradeOptions options) { _dub.upgrade(options); + trace("dependencies after upgrade(", options, + "): found: ", rootDependencies, + "\nmissing:", missingDependencies); optionalifyRoot(); } @@ -387,6 +387,7 @@ class DubComponent : ComponentWrapper /// Lists all dependencies. This will go through all dependencies and contain the dependencies of dependencies. You need to create a tree structure from this yourself. /// Returns: `[{dependencies: string[string], ver: string, name: string}]` + deprecated("this API is broken without dub.selections.json - use rootDependencies, selectedVersions and getPackageInfo instead to operate on IDE selections") auto dependencies() @property const { validateConfiguration(); @@ -394,6 +395,27 @@ class DubComponent : ComponentWrapper return listDependencies(_dub.project); } + /// Lists all selected dependencies. + Dependency[string] selectedVersions() @property const + { + validateConfiguration(); + + Dependency[string] ret; + foreach (key; _dub.project.selections.selectedPackages) + ret[key] = _dub.project.selections.getSelectedVersion(key); + return ret; + } + + /// Gets the dependency information about a package. + /// Returns `DubPackageInfo.init` if it's not found. + DubPackageInfo getPackageInfo(string pkgName) @property const + { + auto pkg = _dub.project.getDependency(pkgName, true); + if (!pkg) + return DubPackageInfo.init; + return getInfo(pkg); + } + /// Lists dependencies of the root package. This can be used as a base to create a tree structure. string[] rootDependencies() @property const { @@ -996,6 +1018,7 @@ DubPackageInfo getInfo(in Package dep) return info; } +deprecated("This API doesn't take into account local / IDE selections") auto listDependencies(scope const Project project) { auto deps = project.dependencies; diff --git a/workspace-d/source/workspaced/com/snippets/dependencies.d b/workspace-d/source/workspaced/com/snippets/dependencies.d index 60f70bbe..8f28f477 100644 --- a/workspace-d/source/workspaced/com/snippets/dependencies.d +++ b/workspace-d/source/workspaced/com/snippets/dependencies.d @@ -102,12 +102,9 @@ class DependencyBasedSnippetProvider : SnippetProvider string id = typeid(this).name; auto dub = instance.get!DubComponent; return typeof(return).async(delegate() { - string[] deps; - foreach (dep; dub.dependencies) - { - deps ~= dep.name; - deps ~= dep.dependencies.keys; - } + // TODO: this should use dependencies, not selections, but this + // regressed: https://github.com/dlang/dub/issues/2853 + string[] deps = dub.selectedVersions.keys; Snippet[] ret; foreach (k, v; snippets) {