From c2ae7a440c345107574f380b70e09305f933b0d0 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 15:37:59 +0200 Subject: [PATCH 1/9] Add online tag to two dub tests --- tests/it/runtime/dub.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/it/runtime/dub.d b/tests/it/runtime/dub.d index f5fa964b..1a4321fa 100644 --- a/tests/it/runtime/dub.d +++ b/tests/it/runtime/dub.d @@ -72,7 +72,7 @@ unittest { @("dependencies not on file system already no dub.selections.json") @Flaky -@Tags(["dub", "ninja"]) +@Tags("dub", "ninja", "online") unittest { import std.file: exists, rmdirRecurse; @@ -98,7 +98,7 @@ unittest { @("no main function but with unit tests") -@Tags(["dub", "ninja"]) +@Tags("dub", "ninja", "online") @Flaky unittest { import std.file: mkdirRecurse; From 351573ef92e8d09636a5f2b862add6888bc523c0 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 15:42:02 +0200 Subject: [PATCH 2/9] Refactor dubTarget --- payload/reggae/rules/dub.d | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/payload/reggae/rules/dub.d b/payload/reggae/rules/dub.d index 803bcbaa..9f306aa8 100644 --- a/payload/reggae/rules/dub.d +++ b/payload/reggae/rules/dub.d @@ -38,12 +38,15 @@ static if(isDubProject) { CompilationMode compilationMode = CompilationMode.options) () { + import reggae.config: options; + enum config = "default"; enum dubInfo = configToDubInfo[config]; enum targetName = dubInfo.targetName; enum linkerFlags = dubInfo.mainLinkerFlags ~ linkerFlags.value; return dubTarget( + options, targetName, dubInfo, compilerFlags.value, @@ -80,6 +83,7 @@ static if(isDubProject) { () { import reggae.dub.info: TargetType, targetName; + import reggae.config: options; import std.exception : enforce; // No `dub test` config? Then it inherited some `targetType "none"`, and @@ -102,7 +106,8 @@ static if(isDubProject) { name = targetName(TargetType.executable, "ut"); } - return dubTarget(name, + return dubTarget(options, + name, dubInfo, compilerFlags.value, linkerFlags.value, @@ -120,8 +125,12 @@ static if(isDubProject) { ) () if(isCallable!objsFunction) { + import reggae.config: options; + const dubInfo = configToDubInfo[config.value]; - return dubTarget(dubInfo.targetName, + + return dubTarget(options, + dubInfo.targetName, dubInfo, compilerFlags.value, linkerFlags.value, @@ -139,17 +148,21 @@ static if(isDubProject) { ) () { - return dubTarget(targetName, - configToDubInfo[config.value], - compilerFlags.value, - linkerFlags.value, - compilationMode, - objsFunction(), - ); - } + import reggae.config: options; + return dubTarget( + options, + targetName, + configToDubInfo[config.value], + compilerFlags.value, + linkerFlags.value, + compilationMode, + objsFunction(), + ); + } Target dubTarget( + in imported!"reggae.options".Options options, in TargetName targetName, in DubInfo dubInfo, in string[] compilerFlags, @@ -159,7 +172,6 @@ static if(isDubProject) { in size_t startingIndex = 0, ) { - import reggae.config: options; import reggae.rules.common: staticLibraryTarget, link; import reggae.types: TargetName; import std.path: relativePath, buildPath; @@ -300,7 +312,7 @@ static if(isDubProject) { } - private Target[] objs(in TargetName targetName, + /*private*/ Target[] objs(in TargetName targetName, in DubInfo dubInfo, in string[] compilerFlags, in CompilationMode compilationMode, @@ -320,7 +332,7 @@ static if(isDubProject) { return allObjs; } - private string realName(in TargetName targetName, in DubInfo dubInfo) { + /*private*/ string realName(in TargetName targetName, in DubInfo dubInfo) { import std.path: buildPath; From a1d0fbb808a96e1a156bd3f5b2b445defc98bfc5 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 15:48:08 +0200 Subject: [PATCH 3/9] Runtime version of dubDefaultTarget --- payload/reggae/rules/dub.d | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/payload/reggae/rules/dub.d b/payload/reggae/rules/dub.d index 9f306aa8..395fb700 100644 --- a/payload/reggae/rules/dub.d +++ b/payload/reggae/rules/dub.d @@ -40,17 +40,35 @@ static if(isDubProject) { { import reggae.config: options; - enum config = "default"; - enum dubInfo = configToDubInfo[config]; - enum targetName = dubInfo.targetName; - enum linkerFlags = dubInfo.mainLinkerFlags ~ linkerFlags.value; + return dubDefaultTarget( + options, + configToDubInfo, + compilerFlags, + linkerFlags, + compilationMode + ); + } + + Target dubDefaultTarget(C)( + in imported!"reggae.options".Options options, + in C configToDubInfo, + CompilerFlags compilerFlags = CompilerFlags(), + LinkerFlags linkerFlags = LinkerFlags(), + CompilationMode compilationMode = CompilationMode.options) + { + import reggae.config: options; + + const config = "default"; + const dubInfo = configToDubInfo[config]; + const targetName = dubInfo.targetName; + const linkerFlags2 = dubInfo.mainLinkerFlags ~ linkerFlags.value; return dubTarget( options, targetName, dubInfo, compilerFlags.value, - linkerFlags, + linkerFlags2, compilationMode, ); } From bfa3b92af9b948e55306f2507ff3253f5d41121e Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 16:33:33 +0200 Subject: [PATCH 4/9] Runtime version of dubTestTarget --- payload/reggae/rules/dub.d | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/payload/reggae/rules/dub.d b/payload/reggae/rules/dub.d index 395fb700..0d4a9baf 100644 --- a/payload/reggae/rules/dub.d +++ b/payload/reggae/rules/dub.d @@ -100,8 +100,26 @@ static if(isDubProject) { CompilationMode compilationMode) () { - import reggae.dub.info: TargetType, targetName; import reggae.config: options; + return dubTestTarget( + options, + configToDubInfo, + compilerFlags, + linkerFlags, + compilationMode + ); + } + + Target dubTestTarget(C) + (in imported!"reggae.options".Options options, + in C configToDubInfo, + CompilerFlags compilerFlags = CompilerFlags(), + LinkerFlags linkerFlags = LinkerFlags(), + CompilationMode compilationMode = CompilationMode.options) + { + import reggae.build : Target; + import reggae.dub.info: TargetType, targetName; + import reggae.rules.dub: dubTarget; import std.exception : enforce; // No `dub test` config? Then it inherited some `targetType "none"`, and From f1a1f9b1d8498f8743cfef84115076401e583d47 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 16:33:42 +0200 Subject: [PATCH 5/9] No longer write out a default reggaefile for dub projects Even though the idea works, it takes too long. We end up compiling D code for the sake of it when we can generate the build at runtime instead. --- payload/reggae/options.d | 6 ++- payload/reggae/rules/dub.d | 6 +-- src/reggae/dub/interop/package.d | 14 ++++++ src/reggae/dub/interop/reggaefile.d | 68 +++++++++++------------------ src/reggae/reggae.d | 34 +++++++++++++-- tests/it/runtime/dub.d | 2 +- tests/ut/json_build/rules.d | 1 - 7 files changed, 78 insertions(+), 53 deletions(-) diff --git a/payload/reggae/options.d b/payload/reggae/options.d index 53b2caf6..c05ef990 100644 --- a/payload/reggae/options.d +++ b/payload/reggae/options.d @@ -199,7 +199,11 @@ struct Options { } string[] reggaeFileDependencies() @safe const { - return [ranFromPath, reggaeFilePath] ~ getReggaeFileDependenciesDlang ~ dependencies; + import std.file: exists; + auto maybeReggaeFile = reggaeFilePath.exists + ? [reggaeFilePath] + : []; + return ranFromPath ~ maybeReggaeFile ~ getReggaeFileDependenciesDlang ~ dependencies; } bool isJsonBuild() @safe const { diff --git a/payload/reggae/rules/dub.d b/payload/reggae/rules/dub.d index 0d4a9baf..57abfc2d 100644 --- a/payload/reggae/rules/dub.d +++ b/payload/reggae/rules/dub.d @@ -56,19 +56,17 @@ static if(isDubProject) { LinkerFlags linkerFlags = LinkerFlags(), CompilationMode compilationMode = CompilationMode.options) { - import reggae.config: options; - const config = "default"; const dubInfo = configToDubInfo[config]; const targetName = dubInfo.targetName; - const linkerFlags2 = dubInfo.mainLinkerFlags ~ linkerFlags.value; + const allLinkerFlags = dubInfo.mainLinkerFlags ~ linkerFlags.value; return dubTarget( options, targetName, dubInfo, compilerFlags.value, - linkerFlags2, + allLinkerFlags, compilationMode, ); } diff --git a/src/reggae/dub/interop/package.d b/src/reggae/dub/interop/package.d index 8b762354..7bc174d8 100644 --- a/src/reggae/dub/interop/package.d +++ b/src/reggae/dub/interop/package.d @@ -55,6 +55,20 @@ void writeDubConfig(O)(ref O output, file.writeln; } +auto dubInfos(O)(ref O output, + in from!"reggae.options".Options options) { + import reggae.io: log; + import reggae.dub.info: TargetType; + import reggae.dub.interop.fetch: dubFetch; + import reggae.dub.interop.dublib: Dub; + + // must check for dub.selections.json before creating dub instance + const dubSelectionsJson = ensureDubSelectionsJson(output, options); + auto dub = Dub(options); + dubFetch(output, dub, options, dubSelectionsJson); + auto dubInfo = getDubInfo(output, dub, options); + return gDubInfos.dup; +} private string ensureDubSelectionsJson (O) diff --git a/src/reggae/dub/interop/reggaefile.d b/src/reggae/dub/interop/reggaefile.d index c8210d67..afae2d60 100644 --- a/src/reggae/dub/interop/reggaefile.d +++ b/src/reggae/dub/interop/reggaefile.d @@ -7,46 +7,28 @@ module reggae.dub.interop.reggaefile; import reggae.from; -void maybeCreateReggaefile(T)(auto ref T output, - in from!"reggae.options".Options options) -{ +auto defaultDubBuild(in from!"reggae.options".Options options) { + import reggae.build: Build; + import reggae.dub.interop: dubInfos; import std.file: exists; + import std.stdio: stdout; - if(options.isDubProject && !options.reggaeFilePath.exists) { - createReggaefile(output, options); - } -} - -// default build for a dub project when there is no reggaefile -private void createReggaefile(T)(auto ref T output, - in from!"reggae.options".Options options) -{ - import reggae.io: log; - import reggae.path: buildPath; - import std.stdio: File; - import std.string: replace; - - output.log("Creating reggaefile.d from dub information"); - auto file = File(buildPath(options.projectPath, "reggaefile.d"), "w"); - - static cleanup(in string str) { - return str.replace("\n ", "\n"); - } + if(!options.isDubProject || options.reggaeFilePath.exists) + return Build(); - const text = options.dubConfig == "" - ? standardDubReggaefile - : reducedDubReggaefile; + const configToDubInfo = dubInfos(stdout, options); - file.write(text.replace("\n ", "\n")); + return options.dubConfig == "" + ? standardDubBuild(options, configToDubInfo) + : reducedDubBuild(options, configToDubInfo); } +auto standardDubBuild(in from!"reggae.options".Options options, in ConfigToDubInfo configToDubInfo) { + import reggae.build: Build, Target, optional; + import reggae.rules.dub: dubDefaultTarget, dubTestTarget; -// This is the default reggaefile for dub projects if one is not found -private enum standardDubReggaefile = q{ - import reggae; - - alias buildTarget = dubDefaultTarget!(); // dub build - alias testTarget = dubTestTarget!(); // dub test + auto buildTarget = dubDefaultTarget(options, configToDubInfo); // dub build + auto testTarget = dubTestTarget(options, configToDubInfo); // dub test Target aliasTarget(string aliasName, alias target)() { import std.algorithm: canFind, map; @@ -71,16 +53,14 @@ private enum standardDubReggaefile = q{ // And a `ut` convenience alias for the `dub test` target. alias utTarget = aliasTarget!("ut", testTarget); - mixin build!(buildTarget, optional!testTarget, optional!defaultTarget, optional!utTarget); -}; - + return Build(buildTarget, optional(testTarget), optional(defaultTarget), optional(utTarget)); +} -// This is the default reggaefile if one is not found when --dub-config is used. This speeds -// up running reggae -private enum reducedDubReggaefile = q{ - import reggae; +auto reducedDubBuild(in from!"reggae.options".Options options, in ConfigToDubInfo configToDubInfo) { + import reggae.build: Build, Target, optional; + import reggae.rules.dub: dubDefaultTarget; - alias buildTarget = dubDefaultTarget!(); // dub build + auto buildTarget = dubDefaultTarget(options, configToDubInfo); // dub build Target aliasTarget(string aliasName, alias target)() { import std.algorithm: map; @@ -92,5 +72,7 @@ private enum reducedDubReggaefile = q{ // Add a `default` convenience alias for the `dub build` target. alias defaultTarget = aliasTarget!("default", buildTarget); - mixin build!(buildTarget, optional!defaultTarget); -}; + return Build(buildTarget, optional(defaultTarget)); +} + +private alias ConfigToDubInfo = from!"reggae.dub.info".DubInfo[string]; diff --git a/src/reggae/reggae.d b/src/reggae/reggae.d index 9c4ce9bf..4e65f2f6 100644 --- a/src/reggae/reggae.d +++ b/src/reggae/reggae.d @@ -30,10 +30,13 @@ import reggae.path: buildPath; version(minimal) { //empty stubs for minimal version of reggae - void maybeCreateReggaefile(T...)(T) {} void writeDubConfig(T...)(T) {} + auto defaultDubBuild() { + import reggae.build: Build; + return Build(); + } } else { - import reggae.dub.interop: writeDubConfig, maybeCreateReggaefile; + import reggae.dub.interop: writeDubConfig, defaultDubBuild; } mixin template reggaeGen(targets...) { @@ -68,6 +71,9 @@ void run(T)(auto ref T output, Options options) { enforce(options.projectPath != "", "A project path must be specified"); + // if there's no custom reggaefile, execute and exit early + if(dubBuild(options)) return; + // write out the library source files to be compiled/interpreted // with the user's build description writeSrcFiles(output, options); @@ -77,7 +83,6 @@ void run(T)(auto ref T output, Options options) { if(haveToReturn) return; } - maybeCreateReggaefile(output, options); createBuild(output, options); } @@ -112,6 +117,29 @@ bool jsonBuild(Options options, in string jsonOutput) { } } +bool dubBuild(in Options options) { + import reggae.dub.interop.reggaefile: defaultDubBuild; + import reggae.buildgen: doBuild; + import reggae.types: Backend; + import std.algorithm: among; + + with(Backend) { + if(!options.backend.among(make, ninja, tup)) + return false; + } + + auto build = defaultDubBuild(options); + if(build == build.init) return false; + + doBuild(build, options); + + import reggae.buildgen:writeCompilationDB; + if(!options.noCompilationDB) writeCompilationDB(build, options); + + + return true; +} + private string getJsonOutput(in Options options) @safe { const args = getJsonOutputArgs(options); diff --git a/tests/it/runtime/dub.d b/tests/it/runtime/dub.d index 1a4321fa..1ca31261 100644 --- a/tests/it/runtime/dub.d +++ b/tests/it/runtime/dub.d @@ -16,7 +16,7 @@ unittest { with(immutable ReggaeSandbox("dub")) { shouldNotExist("reggaefile.d"); writelnUt("\n\nReggae output:\n\n", runReggae("-b", "ninja").lines.join("\n"), "-----\n"); - shouldExist("reggaefile.d"); + shouldNotExist("reggaefile.d"); auto output = ninja(["-v"]).shouldExecuteOk; version(Windows) { diff --git a/tests/ut/json_build/rules.d b/tests/ut/json_build/rules.d index e8bc37d2..1b2fbbb6 100644 --- a/tests/ut/json_build/rules.d +++ b/tests/ut/json_build/rules.d @@ -128,7 +128,6 @@ unittest { auto options = jsonToOptions(defaultOptions, parseJSON(jsonString)); options.reggaeFileDependencies.shouldEqual( [thisExePath, - buildPath(projectPath, "reggaefile.d"), "/path/to/foo.py", "/other/path/bar.py"]); } From 2b356ad51405ac3c1a73a6ffde24221875b57429 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 16:58:57 +0200 Subject: [PATCH 6/9] Update CI compilers --- .github/workflows/d.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/d.yml b/.github/workflows/d.yml index 399f3ba8..2c6da637 100644 --- a/.github/workflows/d.yml +++ b/.github/workflows/d.yml @@ -10,8 +10,8 @@ jobs: os: [ubuntu-22.04, windows-2019] # Remember to change the compiler versions further below as well as here dc: - - dmd-2.104.1 - - ldc-1.32.2 + - dmd-2.105.0 + - ldc-1.33.0 runs-on: ${{ matrix.os }} steps: @@ -68,10 +68,8 @@ jobs: matrix: os: [ubuntu-22.04, macos-12, windows-2022] dc: - - dmd-2.103.1 - - dmd-2.100.0 - - ldc-1.32.2 - - ldc-1.30.0 + - dmd-2.105.0 + - ldc-1.33.0 runs-on: ${{ matrix.os }} defaults: run: From 1eeb21ed58a8e23b9c35f76d504ba194e7cb2dce Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 17:18:34 +0200 Subject: [PATCH 7/9] Refactor jsonBuild and dubBuild --- src/reggae/reggae.d | 55 +++++++++++++------------------ tests/it/runtime/dependencies.d | 2 +- tests/it/runtime/error_messages.d | 12 +++---- 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/reggae/reggae.d b/src/reggae/reggae.d index 4e65f2f6..e4059da7 100644 --- a/src/reggae/reggae.d +++ b/src/reggae/reggae.d @@ -89,58 +89,47 @@ void run(T)(auto ref T output, Options options) { //get JSON description of the build from a scripting language //and transform it into a build description //return true if no D files are present -bool jsonBuild(Options options) { +private bool jsonBuild(Options options) { + import reggae.json_build; + immutable jsonOutput = getJsonOutput(options); - return jsonBuild(options, jsonOutput); + auto build = jsonToBuild(options.projectPath, jsonOutput); + + return runtimeBuild(jsonToOptions(options, jsonOutput), build); } -//transform JSON description into a Build struct -//return true if no D files are present -bool jsonBuild(Options options, in string jsonOutput) { - enforce(options.backend != Backend.binary, "Binary backend not supported via JSON"); +// Call dub, get the build description, and generate the build now +private bool dubBuild(in Options options) { + import reggae.dub.interop.reggaefile: defaultDubBuild; + auto build = defaultDubBuild(options); + return runtimeBuild(options, build); +} + +private bool runtimeBuild(in Options options, imported!"reggae.build".Build build) { + import reggae.buildgen: doBuild; + import reggae.types: Backend; + import std.algorithm: among; + + enforce(options.backend != Backend.binary, "Binary backend not supported at runtime"); version(minimal) assert(0, "JSON builds not supported in minimal version"); else { - import reggae.json_build; import reggae.buildgen; import reggae.rules.common: Language; - auto build = jsonToBuild(options.projectPath, jsonOutput); - doBuild(build, jsonToOptions(options, jsonOutput)); + if(build == build.init) return false; + + doBuild(build, options); import reggae.buildgen:writeCompilationDB; if(!options.noCompilationDB) writeCompilationDB(build, options); - //true -> exit early - return !build.targets.canFind!(a => a.getLanguage == Language.D); - } -} - -bool dubBuild(in Options options) { - import reggae.dub.interop.reggaefile: defaultDubBuild; - import reggae.buildgen: doBuild; - import reggae.types: Backend; - import std.algorithm: among; - - with(Backend) { - if(!options.backend.among(make, ninja, tup)) - return false; } - auto build = defaultDubBuild(options); - if(build == build.init) return false; - - doBuild(build, options); - - import reggae.buildgen:writeCompilationDB; - if(!options.noCompilationDB) writeCompilationDB(build, options); - - return true; } - private string getJsonOutput(in Options options) @safe { const args = getJsonOutputArgs(options); const path = environment.get("PATH", "").split(":"); diff --git a/tests/it/runtime/dependencies.d b/tests/it/runtime/dependencies.d index 434862fe..9031847c 100644 --- a/tests/it/runtime/dependencies.d +++ b/tests/it/runtime/dependencies.d @@ -43,7 +43,7 @@ version(DigitalMars) { version(DigitalMars) { version(linux) { - static foreach(backend; ["ninja", "make", "binary"]) { + static foreach(backend; ["ninja", "make"]) { @("change.compiler." ~ backend) @Tags(backend) diff --git a/tests/it/runtime/error_messages.d b/tests/it/runtime/error_messages.d index f6b9e49b..410497b9 100644 --- a/tests/it/runtime/error_messages.d +++ b/tests/it/runtime/error_messages.d @@ -11,7 +11,7 @@ import tests.it.runtime; else enum projectPath = "/non/existent"; - ReggaeSandbox().runReggae(["-b", "binary"], projectPath).shouldThrowWithMessage( + ReggaeSandbox().runReggae(["-b", "ninja"], projectPath).shouldThrowWithMessage( "Could not find " ~ buildPath(projectPath, "reggaefile.d") ); } @@ -21,7 +21,7 @@ import tests.it.runtime; with(immutable ReggaeSandbox()) { writeFile("foo.txt"); - runReggae("-b", "binary").shouldThrowWithMessage( + runReggae("-b", "ninja").shouldThrowWithMessage( "Could not find " ~ buildPath(testPath, "reggaefile.d")); } } @@ -32,22 +32,22 @@ import tests.it.runtime; writeFile("reggaefile.d"); writeFile("reggaefile.py"); - runReggae("-b", "binary").shouldThrowWithMessage( + runReggae("-b", "ninja").shouldThrowWithMessage( "Reggae builds may only use one language. Found: D, Python" ); writeFile("reggaefile.rb"); - runReggae("-b", "binary").shouldThrowWithMessage( + runReggae("-b", "ninja").shouldThrowWithMessage( "Reggae builds may only use one language. Found: D, Python, Ruby" ); writeFile("reggaefile.js"); - runReggae("-b", "binary").shouldThrowWithMessage( + runReggae("-b", "ninja").shouldThrowWithMessage( "Reggae builds may only use one language. Found: D, Python, Ruby, JavaScript" ); writeFile("reggaefile.lua"); - runReggae("-b", "binary").shouldThrowWithMessage( + runReggae("-b", "ninja").shouldThrowWithMessage( "Reggae builds may only use one language. Found: D, Python, Ruby, JavaScript, Lua" ); } From 48e01df655d5c451f6a82977270fdc0814eda791 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 18:17:04 +0200 Subject: [PATCH 8/9] Delete gDubInfos --- src/reggae/dub/interop/package.d | 94 +++++++++++++++----------------- 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/src/reggae/dub/interop/package.d b/src/reggae/dub/interop/package.d index 7bc174d8..2ba112ee 100644 --- a/src/reggae/dub/interop/package.d +++ b/src/reggae/dub/interop/package.d @@ -8,9 +8,6 @@ import reggae.from; public import reggae.dub.interop.reggaefile; -private from!"reggae.dub.info".DubInfo[string] gDubInfos; - - void writeDubConfig(O)(ref O output, in from!"reggae.options".Options options, from!"std.stdio".File file) { @@ -34,24 +31,23 @@ void writeDubConfig(O)(ref O output, dubFetch(output, dub, options, dubSelectionsJson); - file.writeln("import reggae.dub.info;"); - file.writeln("enum isDubProject = true;"); - output.log(" Getting dub build information"); - auto dubInfo = getDubInfo(output, dub, options); + auto dubInfos = getDubInfos(output, dub, options); output.log(" Got dub build information"); - const targetType = dubInfo.packages.length - ? dubInfo.packages[0].targetType + const targetType = dubInfos["default"].packages.length + ? dubInfos["default"].packages[0].targetType : TargetType.sourceLibrary; + file.writeln("import reggae.dub.info;"); + file.writeln("enum isDubProject = true;"); file.writeln(`const configToDubInfo = assocList([`); - const keys = () @trusted { return gDubInfos.keys; }(); - foreach(config; keys) { - file.writeln(` assocEntry("`, config, `", `, gDubInfos[config], `),`); + foreach(k, v; dubInfos) { + file.writeln(` assocEntry("`, k, `", `, v, `),`); } file.writeln(`]);`); + file.writeln; } @@ -66,8 +62,7 @@ auto dubInfos(O)(ref O output, const dubSelectionsJson = ensureDubSelectionsJson(output, options); auto dub = Dub(options); dubFetch(output, dub, options, dubSelectionsJson); - auto dubInfo = getDubInfo(output, dub, options); - return gDubInfos.dup; + return getDubInfos(output, dub, options); } private string ensureDubSelectionsJson @@ -95,60 +90,57 @@ private string ensureDubSelectionsJson } - -private from!"reggae.dub.info".DubInfo getDubInfo +private from!"reggae.dub.info".DubInfo[string] getDubInfos (O) (ref O output, ref from!"reggae.dub.interop.dublib".Dub dub, in from!"reggae.options".Options options) { - import reggae.dub.interop: gDubInfos; import reggae.io: log; import reggae.path: buildPath; + import reggae.dub.info: DubInfo; import std.file: exists; import std.exception: enforce; - version(unittest) gDubInfos = null; - - if("default" !in gDubInfos) { - - enforce(buildPath(options.projectPath, "dub.selections.json").exists, - "Cannot find dub.selections.json"); - - auto settings = dub.getGeneratorSettings(options); - const configs = dubConfigurations(output, dub, options, settings); - const haveTestConfig = configs.test != ""; - bool atLeastOneConfigOk; - Exception dubInfoFailure; - - foreach(config; configs.configurations) { - const isTestConfig = haveTestConfig && config == configs.test; - try { - gDubInfos[config] = handleDubConfig(output, dub, options, settings, config, isTestConfig); - atLeastOneConfigOk = true; - } catch(Exception ex) { - output.log("ERROR: Could not get info for configuration ", config, ": ", ex.msg); - if(dubInfoFailure is null) dubInfoFailure = ex; - } + DubInfo[string] ret; + + enforce(buildPath(options.projectPath, "dub.selections.json").exists, + "Cannot find dub.selections.json"); + + auto settings = dub.getGeneratorSettings(options); + const configs = dubConfigurations(output, dub, options, settings); + const haveTestConfig = configs.test != ""; + bool atLeastOneConfigOk; + Exception dubInfoFailure; + + foreach(config; configs.configurations) { + const isTestConfig = haveTestConfig && config == configs.test; + try { + ret[config] = handleDubConfig(output, dub, options, settings, config, isTestConfig); + atLeastOneConfigOk = true; + } catch(Exception ex) { + output.log("ERROR: Could not get info for configuration ", config, ": ", ex.msg); + if(dubInfoFailure is null) dubInfoFailure = ex; } + } - if(!atLeastOneConfigOk) { - assert(dubInfoFailure !is null, - "Internal error: no configurations worked and no exception to throw"); - throw dubInfoFailure; - } + if(!atLeastOneConfigOk) { + assert(dubInfoFailure !is null, + "Internal error: no configurations worked and no exception to throw"); + throw dubInfoFailure; + } - gDubInfos["default"] = gDubInfos[configs.default_]; + ret["default"] = ret[configs.default_]; - // (additionally) expose the special `dub test` config as `unittest` config in the DSL (`configToDubInfo`) - // (for `dubTestTarget!()`, `dubConfigurationTarget!(Configuration("unittest"))` etc.) - if(haveTestConfig && configs.test != "unittest" && configs.test in gDubInfos) - gDubInfos["unittest"] = gDubInfos[configs.test]; - } + // (additionally) expose the special `dub test` config as `unittest` config in the DSL (`configToDubInfo`) + // (for `dubTestTarget!()`, `dubConfigurationTarget!(Configuration("unittest"))` etc.) + if(haveTestConfig && configs.test != "unittest" && configs.test in ret) + ret["unittest"] = ret[configs.test]; - return gDubInfos["default"]; + return ret; } + private from!"reggae.dub.interop.configurations".DubConfigurations dubConfigurations (O) From 3944ac08de3d0ea6462731e9ab3dd7374f10ab8e Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Fri, 11 Aug 2023 18:19:30 +0200 Subject: [PATCH 9/9] Refactor usage of dubInfos --- src/reggae/dub/interop/package.d | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/reggae/dub/interop/package.d b/src/reggae/dub/interop/package.d index 2ba112ee..dbf82b9b 100644 --- a/src/reggae/dub/interop/package.d +++ b/src/reggae/dub/interop/package.d @@ -24,16 +24,7 @@ void writeDubConfig(O)(ref O output, return; } - // must check for dub.selections.json before creating dub instance - const dubSelectionsJson = ensureDubSelectionsJson(output, options); - - auto dub = Dub(options); - - dubFetch(output, dub, options, dubSelectionsJson); - - output.log(" Getting dub build information"); - auto dubInfos = getDubInfos(output, dub, options); - output.log(" Got dub build information"); + auto dubInfos = dubInfos(output, options); const targetType = dubInfos["default"].packages.length ? dubInfos["default"].packages[0].targetType @@ -60,9 +51,16 @@ auto dubInfos(O)(ref O output, // must check for dub.selections.json before creating dub instance const dubSelectionsJson = ensureDubSelectionsJson(output, options); + auto dub = Dub(options); + dubFetch(output, dub, options, dubSelectionsJson); - return getDubInfos(output, dub, options); + + output.log(" Getting dub build information"); + auto ret = getDubInfos(output, dub, options); + output.log(" Got dub build information"); + + return ret; } private string ensureDubSelectionsJson