diff --git a/build-gdc.sh b/build-gdc.sh index 203f8c9..df0e5ce 100755 --- a/build-gdc.sh +++ b/build-gdc.sh @@ -17,7 +17,7 @@ echo "enum dubVersion = \"$GITVER\";" >> source/dub/version_.d echo Running $GDC... -$GDC -obin/dub -lcurl -w -fversion=DubUseCurl -Isource $* $LIBS @build-files.txt +$GDC -obin/dub -lcurl -w -fversion=DubUseCurl -fversion=DubApplication -Isource $* $LIBS @build-files.txt echo DUB has been built as bin/dub. echo echo You may want to run diff --git a/build.cmd b/build.cmd index f965194..f6d6a34 100644 --- a/build.cmd +++ b/build.cmd @@ -7,7 +7,7 @@ @echo enum dubVersion = "%GITVER%"; >> source\dub\version_.d @echo Executing %DC%... -@%DC% -ofbin\dub.exe -g -debug -w -version=DubUseCurl -Isource curl.lib %* @build-files.txt +@%DC% -ofbin\dub.exe -g -debug -w -version=DubUseCurl -version=DubApplication -Isource curl.lib %* @build-files.txt @if errorlevel 1 exit /b 1 @echo DUB has been built. You probably also want to add the following entry to your diff --git a/build.sh b/build.sh index 1afe076..ba9fffc 100755 --- a/build.sh +++ b/build.sh @@ -56,7 +56,7 @@ MACOSX_DEPLOYMENT_TARGET=10.8 echo Running $DMD... -$DMD -ofbin/dub -g -O -w -version=DubUseCurl -Isource $* $LIBS @build-files.txt +$DMD -ofbin/dub -g -O -w -version=DubUseCurl -version=DubApplication -Isource $* $LIBS @build-files.txt bin/dub --version echo DUB has been built as bin/dub. echo diff --git a/changelog/addcommand.dd b/changelog/addcommand.dd new file mode 100644 index 0000000..d3ee0bd --- /dev/null +++ b/changelog/addcommand.dd @@ -0,0 +1,11 @@ +Add Command + +The `add` command adds a dependency to the dub.json/dub.sdl file. + +Running `dub add vibe-d` is equivalent to manually adding the following line to dub.sdl (X.Y.Z represents the latest version): +dependency "vibe-d" version="~>X.Y.Z" + +Or the following in dub.json: +"dependencies": { + "vibe-d": "~>X.Y.Z" +} diff --git a/changelog/dubEnvVar.dd b/changelog/dubEnvVar.dd new file mode 100644 index 0000000..b27a8cc --- /dev/null +++ b/changelog/dubEnvVar.dd @@ -0,0 +1,13 @@ +dub now supports `$DUB` variable + +With this release, one can call dub from build commands in the following way: +------ + // dub.sdl: + preBuildCommands "$DUB run --single somebuildscript.d" +----- +This is useful if dub is not in the `$PATH`, or if several versions of dub are installed. + +`$DUB` is also accessible as environment variable in the build commands processes. + +`$DUB` points to the running executable, unless it is used as a library. +In such case, `$DUB` will resolve to the first dub executable found in `$PATH`. diff --git a/changelog/pre-post-run-commands.dd b/changelog/pre-post-run-commands.dd new file mode 100644 index 0000000..a9fc6b9 --- /dev/null +++ b/changelog/pre-post-run-commands.dd @@ -0,0 +1,6 @@ +Pre/Post run commands added + +DUB now supports commands preRunCommands which are executed before the target run +and postRunCommands which are executed after the target run. +Environment variable DUB_TARGET_EXIT_STATUS contains the target executable call status +and is available in postRunCommands. \ No newline at end of file diff --git a/changelog/shebang-without-d-extension.dd b/changelog/shebang-without-d-extension.dd new file mode 100644 index 0000000..7e9b33d --- /dev/null +++ b/changelog/shebang-without-d-extension.dd @@ -0,0 +1,6 @@ +Shebang without .d extension + +Dub single-file packages e.g. `app.d` can now be called without .d extension. +In addition to `dub app.d --param` you can call `dub app --param`. + +Also files without .d extension are supported now as single-file packages. \ No newline at end of file diff --git a/changelog/sortJson.dd b/changelog/sortJson.dd new file mode 100644 index 0000000..fd3dc54 --- /dev/null +++ b/changelog/sortJson.dd @@ -0,0 +1,3 @@ +Sort JSON + +JSON files are now sorted before being written to dub.json. This is to prevent the order of the JSON properties from changing when dub.json is updated. diff --git a/changelog/version-identifier-filter.dd b/changelog/version-identifier-filter.dd new file mode 100644 index 0000000..57b8269 --- /dev/null +++ b/changelog/version-identifier-filter.dd @@ -0,0 +1,54 @@ +Added experimental feature to improve build cache efficiency + +Using version identifiers to configure certain features can often lead to +unnecessary rebuilds of dependencies that don't use those version +identifiers. In order to improve the build cache efficiency, dub gained a new +experimental `--filter-versions` switch. + +When `--filter-versions` is passed to any build, test, or generate command, dub +will grep for all the version identifiers packages actually use and only apply +those during building. This allows for example to reuse a cached build for a +library between two applications using different version identifiers when the +library isn't using any of those itself. + +The following regular expressions used to grep for version identifiers. +--- +enum verRE = ctRegex!`(?:^|\s)version\s*\(\s*([^\s]*?)\s*\)`; +enum debVerRE = ctRegex!`(?:^|\s)debug\s*\(\s*([^\s]*?)\s*\)`; +--- + +For packages that use version identifiers in mixins or auto-generated sources, +the list of applicable version identifiers can be specified explicitly in the +package file. + +dub.json: +--- +"-versionFilters": ["Have_vibe_d"] +"-versionFilters-posix": ["UseUnixSockets", "UseMMap"] +"-debugVersionFilters": ["ValidateRequests"] +--- +dub.sdl: +--- +x:versionFilters "Have_vibe_d" +x:versionFilters "UseUnixSockets" "UseMMap" platform="posix" +x:debugVersionFilters "ValidateRequests" +--- + +Note that the inferred version identifiers are cached and grepping is generally +very fast, so explicitly specifying version identifiers should only be used if +necessary. + +Also note that specifying either of versionFilters or debugVersionFilters will +disable inference for both of them. + +The reservered version identifier none can be used for packages that don't use +any version identifiers or debug version identifiers at all. + +dub.json: +---- +"-versionFilters": ["none"] +---- +dub.sdl: +---- +x:debugVersionFilters "none" +---- diff --git a/dub.sdl b/dub.sdl index 2607c34..3f17241 100644 --- a/dub.sdl +++ b/dub.sdl @@ -11,7 +11,7 @@ targetType "executable" mainSourceFile "source/app.d" libs "curl" - versions "DubUseCurl" + versions "DubUseCurl" "DubApplication" } configuration "library" { diff --git a/source/dub/commandline.d b/source/dub/commandline.d index bd947f4..7a2a742 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -19,7 +19,7 @@ import dub.packagemanager; import dub.packagesuppliers; import dub.project; -import dub.internal.utils : getDUBVersion, getClosestMatch; +import dub.internal.utils : getDUBVersion, getClosestMatch, getTempFile; import std.algorithm; import std.array; @@ -33,7 +33,7 @@ import std.string; import std.typecons : Tuple, tuple; import std.variant; - +import std.path: setExtension; /** Retrieves a list of all available commands. @@ -57,6 +57,7 @@ CommandGroup("Package management", new FetchCommand, new InstallCommand, + new AddCommand, new RemoveCommand, new UninstallCommand, new UpgradeCommand, @@ -100,13 +101,26 @@ // special stdin syntax if (args.length >= 2 && args[1] == "-") { - import dub.internal.utils: getTempFile; - auto path = getTempFile("app", ".d"); stdin.byChunk(4096).joiner.toFile(path.toNativeString()); args = args[0] ~ [path.toNativeString()] ~ args[2..$]; } + // create the list of all supported commands + CommandGroup[] commands = getCommands(); + string[] commandNames = commands.map!(g => g.commands.map!(c => c.name).array).join.array; + + // Shebang syntax support for files without .d extension + if (args.length >= 2 && !args[1].endsWith(".d") && !args[1].startsWith("-") && !commandNames.canFind(args[1])) { + if (exists(args[1])) { + auto path = getTempFile("app", ".d"); + copy(args[1], path.toNativeString()); + args[1] = path.toNativeString(); + } else if (exists(args[1].setExtension(".d"))) { + args[1] = args[1].setExtension(".d"); + } + } + // special single-file package shebang syntax if (args.length >= 2 && args[1].endsWith(".d")) { args = args[0] ~ ["run", "-q", "--temp-build", "--single", args[1], "--"] ~ args[2 ..$]; @@ -162,9 +176,6 @@ options.root_path = options.root_path.absolutePath.buildNormalizedPath; } - // create the list of all supported commands - CommandGroup[] commands = getCommands(); - // extract the command string cmdname; args = common_args.extractRemainingArgs(); @@ -602,6 +613,7 @@ bool m_nodeps; bool m_forceRemove = false; bool m_single; + bool m_filterVersions = true; } override void prepare(scope CommandArgs args) @@ -642,6 +654,9 @@ args.getopt("force-remove", &m_forceRemove, [ "Deprecated option that does nothing." ]); + args.getopt("filter-versions", &m_filterVersions, [ + "[Experimental] Filter version identifiers and debug version identifiers to improve build cache efficiency." + ]); } protected void setupPackage(Dub dub, string package_name, string default_build_type = "debug") @@ -696,11 +711,16 @@ return true; } + bool from_cwd = package_name.length == 0 || package_name.startsWith(":"); // load package in root_path to enable searching for sub packages - if (loadCwdPackage(dub, package_name.length == 0)) { + if (loadCwdPackage(dub, from_cwd)) { if (package_name.startsWith(":")) - package_name = dub.projectName ~ package_name; - if (!package_name.length) return true; + { + auto pack = dub.packageManager.getSubPackage(dub.project.rootPackage, package_name[1 .. $], false); + dub.loadPackage(pack); + return true; + } + if (from_cwd) return true; } enforce(package_name.length, "No valid root package found - aborting."); @@ -802,6 +822,7 @@ gensettings.compiler = m_compiler; gensettings.buildSettings = m_buildSettings; gensettings.combined = m_combined; + gensettings.filterVersions = m_filterVersions; gensettings.run = m_run; gensettings.runArgs = app_args; gensettings.force = m_force; @@ -947,6 +968,7 @@ settings.buildMode = m_buildMode; settings.buildSettings = m_buildSettings; settings.combined = m_combined; + settings.filterVersions = m_filterVersions; settings.parallelBuild = m_parallel; settings.force = m_force; settings.tempBuild = m_single; @@ -1063,6 +1085,7 @@ settings.config = config; settings.buildType = m_buildType; settings.compiler = m_compiler; + settings.filterVersions = m_filterVersions; if (m_importPaths) { m_data = ["import-paths"]; m_dataList = true; } else if (m_stringImportPaths) { m_data = ["string-import-paths"]; m_dataList = true; } @@ -1125,9 +1148,52 @@ /******************************************************************************/ -/* FETCH / REMOVE / UPGRADE */ +/* FETCH / ADD / REMOVE / UPGRADE */ /******************************************************************************/ +class AddCommand : Command { + this() + { + this.name = "add"; + this.argumentsPattern = ""; + this.description = "Adds dependencies to the package file."; + this.helpText = [ + "Adds as dependencies.", + "", + "Running \"dub add \" is the same as adding to the \"dependencies\" section in dub.json/dub.sdl." + ]; + } + + override void prepare(scope CommandArgs args) {} + + override int execute(Dub dub, string[] free_args, string[] app_args) + { + import dub.recipe.io : readPackageRecipe, writePackageRecipe; + import dub.internal.vibecompat.core.file : existsFile; + enforceUsage(free_args.length != 0, "Expected one or more arguments."); + enforceUsage(app_args.length == 0, "Unexpected application arguments."); + + string filetype = existsFile(dub.rootPath ~ "dub.json") ? "json" : "sdl"; + foreach (depname; free_args) { + try { + auto ver = dub.getLatestVersion(depname); + auto dep = ver.isBranch ? Dependency(ver) : Dependency("~>" ~ ver.toString()); + auto pkg = readPackageRecipe(dub.rootPath ~ ("dub." ~ filetype)); + + pkg.buildSettings.dependencies[depname] = dep; + writePackageRecipe(dub.rootPath ~ ("dub." ~ filetype), pkg); + + logInfo("Added dependency %s %s", depname, dep.versionSpec); + } catch (Exception e) { + logError("Could not find package '%s'.", depname); + logDebug("Full error: %s", e.toString().sanitize); + } + } + + return 0; + } +} + class UpgradeCommand : Command { private { bool m_prerelease = false; @@ -1214,9 +1280,9 @@ this.argumentsPattern = ""; this.description = "Manually retrieves and caches a package"; this.helpText = [ - "Note: Use the \"dependencies\" field in the package description file (e.g. dub.json) if you just want to use a certain package as a dependency, you don't have to explicitly fetch packages.", + "Note: Use \"dub add \" if you just want to use a certain package as a dependency, you don't have to explicitly fetch packages.", "", - "Explicit retrieval/removal of packages is only needed when you want to put packages to a place where several applications can share these. If you just have an dependency to a package, just add it to your dub.json, dub will do the rest for you.", + "Explicit retrieval/removal of packages is only needed when you want to put packages in a place where several applications can share them. If you just have a dependency to add, use the `add` command. Dub will do the rest for you.", "", "Without specified options, placement/removal will default to a user wide shared location.", "", @@ -1720,6 +1786,7 @@ gensettings.compiler = m_compiler; gensettings.buildSettings = m_buildSettings; gensettings.combined = m_combined; + gensettings.filterVersions = m_filterVersions; gensettings.run = m_programStatusCode != int.min || m_programRegex.length; gensettings.runArgs = app_args; gensettings.force = true; diff --git a/source/dub/compilers/buildsettings.d b/source/dub/compilers/buildsettings.d index 939a1f1..87a4f1a 100644 --- a/source/dub/compilers/buildsettings.d +++ b/source/dub/compilers/buildsettings.d @@ -33,6 +33,8 @@ string[] copyFiles; string[] versions; string[] debugVersions; + string[] versionFilters; + string[] debugVersionFilters; string[] importPaths; string[] stringImportPaths; string[] importFiles; @@ -41,6 +43,8 @@ string[] postGenerateCommands; string[] preBuildCommands; string[] postBuildCommands; + string[] preRunCommands; + string[] postRunCommands; @byName BuildRequirements requirements; @byName BuildOptions options; @@ -69,6 +73,8 @@ addCopyFiles(bs.copyFiles); addVersions(bs.versions); addDebugVersions(bs.debugVersions); + addVersionFilters(bs.versionFilters); + addDebugVersionFilters(bs.debugVersionFilters); addImportPaths(bs.importPaths); addStringImportPaths(bs.stringImportPaths); addImportFiles(bs.importFiles); @@ -77,6 +83,8 @@ addPostGenerateCommands(bs.postGenerateCommands); addPreBuildCommands(bs.preBuildCommands); addPostBuildCommands(bs.postBuildCommands); + addPreRunCommands(bs.preRunCommands); + addPostRunCommands(bs.postRunCommands); } void addDFlags(in string[] value...) { dflags ~= value; } @@ -91,6 +99,8 @@ void addCopyFiles(in string[] value...) { add(copyFiles, value); } void addVersions(in string[] value...) { add(versions, value); } void addDebugVersions(in string[] value...) { add(debugVersions, value); } + void addVersionFilters(in string[] value...) { add(versionFilters, value); } + void addDebugVersionFilters(in string[] value...) { add(debugVersionFilters, value); } void addImportPaths(in string[] value...) { add(importPaths, value); } void addStringImportPaths(in string[] value...) { add(stringImportPaths, value); } void prependStringImportPaths(in string[] value...) { prepend(stringImportPaths, value); } @@ -100,6 +110,8 @@ void addPostGenerateCommands(in string[] value...) { add(postGenerateCommands, value, false); } void addPreBuildCommands(in string[] value...) { add(preBuildCommands, value, false); } void addPostBuildCommands(in string[] value...) { add(postBuildCommands, value, false); } + void addPreRunCommands(in string[] value...) { add(preRunCommands, value, false); } + void addPostRunCommands(in string[] value...) { add(postRunCommands, value, false); } void addRequirements(in BuildRequirement[] value...) { foreach (v; value) this.requirements |= v; } void addRequirements(in BuildRequirements value) { this.requirements |= value; } void addOptions(in BuildOption[] value...) { foreach (v; value) this.options |= v; } @@ -171,9 +183,9 @@ static bool pathMatch(string path, string pattern) { import std.functional : memoize; - + alias nativePath = memoize!((string stringPath) => NativePath(stringPath)); - + return nativePath(path) == nativePath(pattern) || globMatch(path, pattern); } diff --git a/source/dub/description.d b/source/dub/description.d index c9c347c..d38181a 100644 --- a/source/dub/description.d +++ b/source/dub/description.d @@ -93,6 +93,8 @@ string[] postGenerateCommands; /// commands executed after creating the description string[] preBuildCommands; /// Commands to execute prior to every build string[] postBuildCommands; /// Commands to execute after every build + string[] preRunCommands; /// Commands to execute prior to every run + string[] postRunCommands; /// Commands to execute after every run @byName BuildRequirement[] buildRequirements; @byName BuildOption[] options; SourceFileDescription[] files; /// A list of all source/import files possibly used by the package diff --git a/source/dub/dub.d b/source/dub/dub.d index 3c5c11c..f6e3682 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -28,7 +28,7 @@ import std.exception : enforce; import std.file; import std.process : environment; -import std.range : empty; +import std.range : assumeSorted, empty; import std.string; import std.encoding : sanitize; @@ -311,7 +311,7 @@ mkdirRecurse(localDirPath); } - runCommand("xcopy /s /e /y " ~ roamingDirPath ~ " " ~ localDirPath ~ " > NUL"); + runCommand(`xcopy /s /e /y "` ~ roamingDirPath ~ `" "` ~ localDirPath ~ `" > NUL`); rmdirRecurse(roamingDirPath); } @@ -592,8 +592,18 @@ } } + string[] missingDependenciesBeforeReinit = m_project.missingDependencies; m_project.reinit(); + if (!m_project.hasAllDependencies) { + auto resolvedDependencies = setDifference( + assumeSorted(missingDependenciesBeforeReinit), + assumeSorted(m_project.missingDependencies) + ); + if (!resolvedDependencies.empty) + upgrade(options, m_project.missingDependencies); + } + if ((options & UpgradeOptions.select) && !(options & (UpgradeOptions.noSaveSelections | UpgradeOptions.dryRun))) m_project.saveSelections(); } @@ -773,6 +783,7 @@ if (existsFile(path ~ ".dub/build")) rmdirRecurse((path ~ ".dub/build").toNativeString()); if (existsFile(path ~ ".dub/obj")) rmdirRecurse((path ~ ".dub/obj").toNativeString()); + if (existsFile(path ~ ".dub/metadata_cache.json")) std.file.remove((path ~ ".dub/metadata_cache.json").toNativeString()); auto p = Package.load(path); if (p.getBuildSettings().targetType == TargetType.none) { @@ -1254,7 +1265,7 @@ GeneratorSettings settings; settings.config = "application"; settings.compiler = getCompiler(compiler_binary); // TODO: not using --compiler ??? - settings.platform = settings.compiler.determinePlatform(settings.buildSettings, compiler_binary); + settings.platform = settings.compiler.determinePlatform(settings.buildSettings, compiler_binary, m_defaultArchitecture); settings.buildType = "debug"; settings.run = true; @@ -1278,7 +1289,7 @@ if (!run) { // TODO: ddox should copy those files itself - version(Windows) runCommand("xcopy /S /D "~tool_path~"public\\* docs\\"); + version(Windows) runCommand(`xcopy /S /D "`~tool_path~`public\*" docs\`); else runCommand("rsync -ru '"~tool_path~"public/' docs/"); } } diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index 1895e3b..3586aa7 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -34,7 +34,6 @@ private { PackageManager m_packageMan; NativePath[] m_temporaryFiles; - NativePath m_targetExecutablePath; } this(Project project) @@ -108,10 +107,10 @@ auto buildsettings = targets[m_project.rootPackage.name].buildSettings.dup; if (settings.run && !(buildsettings.options & BuildOption.syntaxOnly)) { NativePath exe_file_path; - if (m_targetExecutablePath.empty) + if (m_tempTargetExecutablePath.empty) exe_file_path = getTargetPath(buildsettings, settings); else - exe_file_path = m_targetExecutablePath ~ settings.compiler.getTargetFileName(buildsettings, settings.platform); + exe_file_path = m_tempTargetExecutablePath ~ settings.compiler.getTargetFileName(buildsettings, settings.platform); runTarget(exe_file_path, buildsettings, settings.runArgs, settings); } } @@ -161,7 +160,7 @@ NativePath target_path; if (settings.tempBuild) { string packageName = pack.basePackage is null ? pack.name : pack.basePackage.name; - m_targetExecutablePath = target_path = getTempDir() ~ format(".dub/build/%s-%s/%s/", packageName, pack.version_, build_id); + m_tempTargetExecutablePath = target_path = getTempDir() ~ format(".dub/build/%s-%s/%s/", packageName, pack.version_, build_id); } else target_path = pack.path ~ format(".dub/build/%s/", build_id); @@ -529,19 +528,42 @@ if (!exe_path_string.startsWith(".") && (exe_path_string.length < 2 || exe_path_string[1] != ':')) exe_path_string = ".\\" ~ exe_path_string; } + runPreRunCommands(m_project.rootPackage, m_project, settings, buildsettings); logInfo("Running %s %s", exe_path_string, run_args.join(" ")); if (settings.runCallback) { auto res = execute(exe_path_string ~ run_args); settings.runCallback(res.status, res.output); + settings.targetExitStatus = res.status; + runPostRunCommands(m_project.rootPackage, m_project, settings, buildsettings); } else { auto prg_pid = spawnProcess(exe_path_string ~ run_args); auto result = prg_pid.wait(); + settings.targetExitStatus = result; + runPostRunCommands(m_project.rootPackage, m_project, settings, buildsettings); enforce(result == 0, "Program exited with code "~to!string(result)); } } else enforce(false, "Target is a library. Skipping execution."); } + private void runPreRunCommands(in Package pack, in Project proj, in GeneratorSettings settings, + in BuildSettings buildsettings) + { + if (buildsettings.preRunCommands.length) { + logInfo("Running pre-run commands..."); + runBuildCommands(buildsettings.preRunCommands, pack, proj, settings, buildsettings); + } + } + + private void runPostRunCommands(in Package pack, in Project proj, in GeneratorSettings settings, + in BuildSettings buildsettings) + { + if (buildsettings.postRunCommands.length) { + logInfo("Running post-run commands..."); + runBuildCommands(buildsettings.postRunCommands, pack, proj, settings, buildsettings); + } + } + private void cleanupTemporaries() { foreach_reverse (f; m_temporaryFiles) { diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index 700b150..ddbbc33 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -74,6 +74,7 @@ protected { Project m_project; + NativePath m_tempTargetExecutablePath; } this(Project project) @@ -101,12 +102,10 @@ prepareGeneration(pack, m_project, settings, buildSettings); } - string[] mainfiles = configurePackages(m_project.rootPackage, targets, settings); + configurePackages(m_project.rootPackage, targets, settings); addBuildTypeSettings(targets, settings); foreach (ref t; targets.byValue) enforceBuildRequirements(t.buildSettings); - auto bs = &targets[m_project.rootPackage.name].buildSettings; - if (bs.targetType == TargetType.executable) bs.addSourceFiles(mainfiles); generateTargets(settings, targets); @@ -114,7 +113,9 @@ BuildSettings buildsettings; buildsettings.processVars(m_project, pack, pack.getBuildSettings(settings.platform, configs[pack.name]), settings, true); bool generate_binary = !(buildsettings.options & BuildOption.syntaxOnly); - finalizeGeneration(pack, m_project, settings, buildsettings, NativePath(bs.targetPath), generate_binary); + auto bs = &targets[m_project.rootPackage.name].buildSettings; + auto targetPath = (m_tempTargetExecutablePath.empty) ? NativePath(bs.targetPath) : m_tempTargetExecutablePath; + finalizeGeneration(pack, m_project, settings, buildsettings, targetPath, generate_binary); } performPostGenerateActions(settings, targets); @@ -158,13 +159,17 @@ compatible. This also transports all Have_dependency_xyz version identifiers to `rootPackage`. + 4. Filter unused versions and debugVersions from all targets. The + filters have previously been upwards inherited (3.) so that versions + used in a dependency are also applied to all dependents. + Note: The upwards inheritance is done at last so that siblings do not influence each other, also see https://github.com/dlang/dub/pull/1128. Note: Targets without output are integrated into their dependents and removed from `targets`. */ - private string[] configurePackages(Package rootPackage, TargetInfo[string] targets, GeneratorSettings genSettings) + private void configurePackages(Package rootPackage, TargetInfo[string] targets, GeneratorSettings genSettings) { import std.algorithm : remove, sort; import std.range : repeat; @@ -227,6 +232,16 @@ hasOutput[ti.pack.name] = generatesBinary || ti.pack is rootPackage; } + // add main source files to root executable + { + auto bs = &targets[rootPackage.name].buildSettings; + if (bs.targetType == TargetType.executable) bs.addSourceFiles(mainSourceFiles); + } + + if (genSettings.filterVersions) + foreach (ref ti; targets.byValue) + inferVersionFilters(ti); + // mark packages as visited (only used during upwards propagation) void[0][Package] visited; @@ -321,7 +336,7 @@ bs.addVersions(pkgnames.map!(pn => "Have_" ~ stripDlangSpecialChars(pn)).array); } - // 3. upwards inherit full build configurations (import paths, versions, debugVersions, ...) + // 3. upwards inherit full build configurations (import paths, versions, debugVersions, versionFilters, importPaths, ...) void configureDependents(ref TargetInfo ti, TargetInfo[string] targets, size_t level = 0) { // use `visited` here as pkgs cannot depend on themselves @@ -348,7 +363,26 @@ else destroy(visited); - // 4. override string import files in dependencies + // 4. Filter applicable version and debug version identifiers + if (genSettings.filterVersions) + { + foreach (name, ref ti; targets) + { + import std.algorithm.sorting : partition; + + auto bs = &ti.buildSettings; + + auto filtered = bs.versions.partition!(v => bs.versionFilters.canFind(v)); + logDebug("Filtering out unused versions for %s: %s", name, filtered); + bs.versions = bs.versions[0 .. $ - filtered.length]; + + filtered = bs.debugVersions.partition!(v => bs.debugVersionFilters.canFind(v)); + logDebug("Filtering out unused debug versions for %s: %s", name, filtered); + bs.debugVersions = bs.debugVersions[0 .. $ - filtered.length]; + } + } + + // 5. override string import files in dependencies static void overrideStringImports(ref TargetInfo ti, TargetInfo[string] targets, string[] overrides) { // do not use visited here as string imports can be overridden by *any* parent @@ -386,8 +420,96 @@ if (!hasOutput[name]) targets.remove(name); } + } - return mainSourceFiles; + // infer applicable version identifiers + private static void inferVersionFilters(ref TargetInfo ti) + { + import std.algorithm.searching : any; + import std.file : timeLastModified; + import std.path : extension; + import std.range : chain; + import std.regex : ctRegex, matchAll; + import std.stdio : File; + import std.datetime : Clock, SysTime, UTC; + import dub.compilers.utils : isLinkerFile; + import dub.internal.vibecompat.data.json : Json, JSONException; + + auto bs = &ti.buildSettings; + + // only infer if neither version filters are specified explicitly + if (bs.versionFilters.length || bs.debugVersionFilters.length) + { + logDebug("Using specified versionFilters for %s: %s %s", ti.pack.name, + bs.versionFilters, bs.debugVersionFilters); + return; + } + + // check all existing source files for version identifiers + static immutable dexts = [".d", ".di"]; + auto srcs = chain(bs.sourceFiles, bs.importFiles, bs.stringImportFiles) + .filter!(f => dexts.canFind(f.extension)).filter!exists; + // try to load cached filters first + auto cache = ti.pack.metadataCache; + try + { + auto cachedFilters = cache["versionFilters"]; + if (cachedFilters.type != Json.Type.undefined) + cachedFilters = cachedFilters[ti.config]; + if (cachedFilters.type != Json.Type.undefined) + { + immutable mtime = SysTime.fromISOExtString(cachedFilters["mtime"].get!string); + if (!srcs.any!(src => src.timeLastModified > mtime)) + { + auto versionFilters = cachedFilters["versions"][].map!(j => j.get!string).array; + auto debugVersionFilters = cachedFilters["debugVersions"][].map!(j => j.get!string).array; + logDebug("Using cached versionFilters for %s: %s %s", ti.pack.name, + versionFilters, debugVersionFilters); + bs.addVersionFilters(versionFilters); + bs.addDebugVersionFilters(debugVersionFilters); + return; + } + } + } + catch (JSONException e) + { + logWarn("Exception during loading invalid package cache %s.\n%s", + ti.pack.path ~ ".dub/metadata_cache.json", e); + } + + // use ctRegex for performance reasons, only small compile time increase + enum verRE = ctRegex!`(?:^|\s)version\s*\(\s*([^\s]*?)\s*\)`; + enum debVerRE = ctRegex!`(?:^|\s)debug\s*\(\s*([^\s]*?)\s*\)`; + + auto versionFilters = appender!(string[]); + auto debugVersionFilters = appender!(string[]); + + foreach (file; srcs) + { + foreach (line; File(file).byLine) + { + foreach (m; line.matchAll(verRE)) + if (!versionFilters.data.canFind(m[1])) + versionFilters.put(m[1].idup); + foreach (m; line.matchAll(debVerRE)) + if (!debugVersionFilters.data.canFind(m[1])) + debugVersionFilters.put(m[1].idup); + } + } + logDebug("Using inferred versionFilters for %s: %s %s", ti.pack.name, + versionFilters.data, debugVersionFilters.data); + bs.addVersionFilters(versionFilters.data); + bs.addDebugVersionFilters(debugVersionFilters.data); + + auto cachedFilters = cache["versionFilters"]; + if (cachedFilters.type == Json.Type.undefined) + cachedFilters = cache["versionFilters"] = [ti.config: Json.emptyObject]; + cachedFilters[ti.config] = [ + "mtime": Json(Clock.currTime(UTC()).toISOExtString), + "versions": Json(versionFilters.data.map!Json.array), + "debugVersions": Json(debugVersionFilters.data.map!Json.array), + ]; + ti.pack.metadataCache = cache; } private static void mergeFromDependent(in ref BuildSettings parent, ref BuildSettings child) @@ -404,6 +526,8 @@ parent.addDFlags(child.dflags); parent.addVersions(child.versions); parent.addDebugVersions(child.debugVersions); + parent.addVersionFilters(child.versionFilters); + parent.addDebugVersionFilters(child.debugVersionFilters); parent.addImportPaths(child.importPaths); parent.addStringImportPaths(child.stringImportPaths); // linking of static libraries is done by parent @@ -439,8 +563,10 @@ string buildType; BuildSettings buildSettings; BuildMode buildMode = BuildMode.separate; + int targetExitStatus; bool combined; // compile all in one go instead of each dependency separately + bool filterVersions; // only used for generator "build" bool run, force, direct, rdmd, tempBuild, parallelBuild; @@ -618,9 +744,9 @@ void runBuildCommands(in string[] commands, in Package pack, in Project proj, in GeneratorSettings settings, in BuildSettings build_settings) { - import std.conv; - import std.process; - import dub.internal.utils; + import dub.internal.utils : getDUBExePath, runCommands; + import std.conv : to, text; + import std.process : environment, escapeShellFileName; string[string] env = environment.toAA(); // TODO: do more elaborate things here @@ -636,12 +762,14 @@ env["DC_BASE"] = settings.platform.compiler; env["D_FRONTEND_VER"] = to!string(settings.platform.frontendVersion); + env["DUB_EXE"] = getDUBExePath(settings.platform.compilerBinary); env["DUB_PLATFORM"] = join(cast(string[])settings.platform.platform," "); env["DUB_ARCH"] = join(cast(string[])settings.platform.architecture," "); env["DUB_TARGET_TYPE"] = to!string(build_settings.targetType); env["DUB_TARGET_PATH"] = build_settings.targetPath; env["DUB_TARGET_NAME"] = build_settings.targetName; + env["DUB_TARGET_EXIT_STATUS"] = settings.targetExitStatus.text; env["DUB_WORKING_DIRECTORY"] = build_settings.workingDirectory; env["DUB_MAIN_SOURCE_FILE"] = build_settings.mainSourceFile; diff --git a/source/dub/init.d b/source/dub/init.d index 7836ab3..c5e4598 100644 --- a/source/dub/init.d +++ b/source/dub/init.d @@ -182,6 +182,7 @@ docs.json __dummy.html docs/ +/%1$s %1$s.so %1$s.dylib %1$s.dll diff --git a/source/dub/internal/utils.d b/source/dub/internal/utils.d index 3e36af7..42ecdf1 100644 --- a/source/dub/internal/utils.d +++ b/source/dub/internal/utils.d @@ -325,6 +325,94 @@ return download(url.toString(), timeout); } +/** + Downloads a file from the specified URL with retry logic. + + Downloads a file from the specified URL with up to n tries on failure + Throws: `Exception` if the download failed or `HTTPStatusException` after the nth retry or + on "unrecoverable failures" such as 404 not found + Otherwise might throw anything else that `download` throws. + See_Also: download +**/ +void retryDownload(URL url, NativePath filename, size_t retryCount = 3) +{ + foreach(i; 0..retryCount) { + version(DubUseCurl) { + try { + download(url, filename); + return; + } + catch(HTTPStatusException e) { + if (e.status == 404) throw e; + else { + logDebug("Failed to download %s (Attempt %s of %s)", url, i + 1, retryCount); + if (i == retryCount - 1) throw e; + else continue; + } + } + catch(CurlException e) { + logDebug("Failed to download %s (Attempt %s of %s)", url, i + 1, retryCount); + continue; + } + } + else + { + try { + download(url, filename); + return; + } + catch(HTTPStatusException e) { + if (e.status == 404) throw e; + else { + logDebug("Failed to download %s (Attempt %s of %s)", url, i + 1, retryCount); + if (i == retryCount - 1) throw e; + else continue; + } + } + } + } + throw new Exception("Failed to download %s".format(url)); +} + +///ditto +ubyte[] retryDownload(URL url, size_t retryCount = 3) +{ + foreach(i; 0..retryCount) { + version(DubUseCurl) { + try { + return download(url); + } + catch(HTTPStatusException e) { + if (e.status == 404) throw e; + else { + logDebug("Failed to download %s (Attempt %s of %s)", url, i + 1, retryCount); + if (i == retryCount - 1) throw e; + else continue; + } + } + catch(CurlException e) { + logDebug("Failed to download %s (Attempt %s of %s)", url, i + 1, retryCount); + continue; + } + } + else + { + try { + return download(url); + } + catch(HTTPStatusException e) { + if (e.status == 404) throw e; + else { + logDebug("Failed to download %s (Attempt %s of %s)", url, i + 1, retryCount); + if (i == retryCount - 1) throw e; + else continue; + } + } + } + } + throw new Exception("Failed to download %s".format(url)); +} + /// Returns the current DUB version in semantic version format string getDUBVersion() { @@ -342,6 +430,65 @@ return verstr; } + +/** + Get current executable's path if running as DUB executable, + or find a DUB executable if DUB is used as a library. + For the latter, the following locations are checked in order: + $(UL + $(LI current working directory) + $(LI same directory as `compilerBinary` (if supplied)) + $(LI all components of the `$PATH` variable) + ) + Params: + compilerBinary = optional path to a D compiler executable, used to locate DUB executable + Returns: + The path to a valid DUB executable + Throws: + an Exception if no valid DUB executable is found +*/ +public string getDUBExePath(in string compilerBinary=null) +{ + version(DubApplication) { + import std.file : thisExePath; + return thisExePath(); + } + else { + // this must be dub as a library + import std.algorithm : filter, map, splitter; + import std.array : array; + import std.file : exists, getcwd; + import std.path : chainPath, dirName; + import std.range : chain, only, take; + import std.process : environment; + + version(Windows) { + enum exeName = "dub.exe"; + enum pathSep = ';'; + } + else { + enum exeName = "dub"; + enum pathSep = ':'; + } + + auto dubLocs = only( + getcwd().chainPath(exeName), + compilerBinary.dirName.chainPath(exeName), + ) + .take(compilerBinary.length ? 2 : 1) + .chain( + environment.get("PATH", "") + .splitter(pathSep) + .map!(p => p.chainPath(exeName)) + ) + .filter!exists; + + enforce(!dubLocs.empty, "Could not find DUB executable"); + return dubLocs.front.array; + } +} + + version(DubUseCurl) { void setupHTTPClient(ref HTTP conn, uint timeout) { diff --git a/source/dub/internal/vibecompat/data/json.d b/source/dub/internal/vibecompat/data/json.d index 9d2a7b6..3671ddf 100644 --- a/source/dub/internal/vibecompat/data/json.d +++ b/source/dub/internal/vibecompat/data/json.d @@ -1779,24 +1779,38 @@ case Json.Type.object: dst.put('{'); bool first = true; - foreach( string k, ref const Json e; json ){ - if( e.type == Json.Type.undefined ) continue; - if( !first ) dst.put(','); - first = false; - static if (pretty) { + + static if (pretty) { + import std.algorithm.sorting : sort; + string[] keyOrder; + foreach (string key, ref const Json e; json) keyOrder ~= key; + keyOrder.sort(); + + foreach( key; keyOrder ){ + if( json[key].type == Json.Type.undefined ) continue; + if( !first ) dst.put(','); + first = false; dst.put('\n'); foreach (tab; 0 .. level+1) dst.put('\t'); + dst.put('\"'); + jsonEscape(dst, key); + dst.put(pretty ? `": ` : `":`); + writeJsonString!(R, pretty)(dst, json[key], level+1); } - dst.put('\"'); - jsonEscape(dst, k); - dst.put(pretty ? `": ` : `":`); - writeJsonString!(R, pretty)(dst, e, level+1); - } - static if (pretty) { if (json.length > 0) { dst.put('\n'); foreach (tab; 0 .. level) dst.put('\t'); } + } else { + foreach( string k, ref const Json e; json ){ + if( e.type == Json.Type.undefined ) continue; + if( !first ) dst.put(','); + first = false; + dst.put('\"'); + jsonEscape(dst, k); + dst.put(pretty ? `": ` : `":`); + writeJsonString!(R, pretty)(dst, e, level+1); + } } dst.put('}'); break; @@ -1818,13 +1832,6 @@ 1, {} ] -}` || a.toPrettyString() == -`{ - "b": [ - 1, - {} - ], - "a": [] }`); } diff --git a/source/dub/package_.d b/source/dub/package_.d index bac7020..5da9201 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -274,6 +274,22 @@ dstFile.writePrettyJsonString(m_info.toJson()); } + /// Get the metadata cache for this package + @property Json metadataCache() + { + enum silent_fail = true; + return jsonFromFile(m_path ~ ".dub/metadata_cache.json", silent_fail); + } + + /// Write metadata cache for this package + @property void metadataCache(Json json) + { + enum create_if_missing = true; + if (isWritableDir(m_path ~ ".dub", create_if_missing)) + writeJsonFile(m_path ~ ".dub/metadata_cache.json", json); + // TODO: store elsewhere + } + /** Returns the package recipe of a non-path-based sub package. For sub packages that are declared within the package recipe of the diff --git a/source/dub/packagesuppliers/maven.d b/source/dub/packagesuppliers/maven.d index 235aa32..372851d 100644 --- a/source/dub/packagesuppliers/maven.d +++ b/source/dub/packagesuppliers/maven.d @@ -9,7 +9,7 @@ to search for available packages. */ class MavenRegistryPackageSupplier : PackageSupplier { - import dub.internal.utils : download, HTTPStatusException; + import dub.internal.utils : retryDownload, HTTPStatusException; import dub.internal.vibecompat.data.json : serializeToJson; import dub.internal.vibecompat.core.log; import dub.internal.vibecompat.inet.url : URL; @@ -55,19 +55,17 @@ return; auto vers = best["version"].get!string; auto url = m_mavenUrl~NativePath("%s/%s/%s-%s.zip".format(packageId, vers, packageId, vers)); - logDiagnostic("Downloading from '%s'", url); - foreach(i; 0..3) { - try{ - download(url, path); - return; - } - catch(HTTPStatusException e) { - if (e.status == 404) throw e; - else { - logDebug("Failed to download package %s from %s (Attempt %s of 3)", packageId, url, i + 1); - continue; - } - } + + try { + retryDownload(url, path); + return; + } + catch(HTTPStatusException e) { + if (e.status == 404) throw e; + else logDebug("Failed to download package %s from %s", packageId, url); + } + catch(Exception e) { + logDebug("Failed to download package %s from %s", packageId, url); } throw new Exception("Failed to download package %s from %s".format(packageId, url)); } @@ -92,27 +90,16 @@ auto url = m_mavenUrl~NativePath(packageId~"/maven-metadata.xml"); logDebug("Downloading maven metadata for %s", packageId); - logDebug("Getting from %s", url); - string xmlData; - foreach(i; 0..3) { - try { - xmlData = cast(string)download(url); - break; + + try + xmlData = cast(string)retryDownload(url); + catch(HTTPStatusException e) { + if (e.status == 404) { + logDebug("Maven metadata %s not found at %s (404): %s", packageId, description, e.msg); + return Json(null); } - catch (HTTPStatusException e) - { - if (e.status == 404) { - logDebug("Maven metadata %s not found at %s (404): %s", packageId, description, e.msg); - return Json(null); - } - else { - logDebug("Error getting maven metadata for %s at %s (attempt %s of 3): %s", packageId, description, i + 1, e.msg); - if (i == 2) - throw e; - continue; - } - } + else throw e; } auto json = Json(["name": Json(packageId), "versions": Json.emptyArray]); diff --git a/source/dub/packagesuppliers/registry.d b/source/dub/packagesuppliers/registry.d index 6706b47..3eb2c88 100644 --- a/source/dub/packagesuppliers/registry.d +++ b/source/dub/packagesuppliers/registry.d @@ -11,7 +11,7 @@ $(LINK https://code.dlang.org/)) to search for available packages. */ class RegistryPackageSupplier : PackageSupplier { - import dub.internal.utils : download, HTTPStatusException; + import dub.internal.utils : download, retryDownload, HTTPStatusException; import dub.internal.vibecompat.core.log; import dub.internal.vibecompat.data.json : parseJson, parseJsonString, serializeToJson; import dub.internal.vibecompat.inet.url : URL; @@ -57,19 +57,16 @@ return; auto vers = best["version"].get!string; auto url = m_registryUrl ~ NativePath(PackagesPath~"/"~packageId~"/"~vers~".zip"); - logDiagnostic("Downloading from '%s'", url); - foreach(i; 0..3) { - try{ - download(url, path); - return; - } - catch(HTTPStatusException e) { - if (e.status == 404) throw e; - else { - logDebug("Failed to download package %s from %s (Attempt %s of 3)", packageId, url, i + 1); - continue; - } - } + try { + retryDownload(url, path); + return; + } + catch(HTTPStatusException e) { + if (e.status == 404) throw e; + else logDebug("Failed to download package %s from %s", packageId, url); + } + catch(Exception e) { + logDebug("Failed to download package %s from %s", packageId, url); } throw new Exception("Failed to download package %s from %s".format(packageId, url)); } @@ -92,28 +89,18 @@ auto url = m_registryUrl ~ NativePath(PackagesPath ~ "/" ~ packageId ~ ".json"); logDebug("Downloading metadata for %s", packageId); - logDebug("Getting from %s", url); - string jsonData; - foreach(i; 0..3) { - try { - jsonData = cast(string)download(url); - break; + + try + jsonData = cast(string)retryDownload(url); + catch(HTTPStatusException e) { + if (e.status == 404) { + logDebug("Package %s not found at %s (404): %s", packageId, description, e.msg); + return Json(null); } - catch (HTTPStatusException e) - { - if (e.status == 404) { - logDebug("Package %s not found at %s (404): %s", packageId, description, e.msg); - return Json(null); - } - else { - logDebug("Error getting metadata for package %s at %s (attempt %s of 3): %s", packageId, description, i + 1, e.msg); - if (i == 2) - throw e; - continue; - } - } + else throw e; } + Json json = parseJsonString(jsonData, url.toString()); // strip readme data (to save size and time) foreach (ref v; json["versions"]) @@ -129,7 +116,7 @@ auto url = m_registryUrl; url.localURI = "/api/packages/search?q="~encodeComponent(query); string data; - data = cast(string)download(url); + data = cast(string)retryDownload(url); return data.parseJson.opt!(Json[]) .map!(j => SearchResult(j["name"].opt!string, j["description"].opt!string, j["version"].opt!string)) .array; diff --git a/source/dub/project.d b/source/dub/project.d index 9689f85..5171433 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -43,7 +43,7 @@ Package[] m_dependencies; Package[][Package] m_dependees; SelectedVersions m_selections; - bool m_hasAllDependencies; + string[] m_missingDependencies; string[string] m_overriddenConfigs; } @@ -114,7 +114,10 @@ to `selections`, or to use `Dub.upgrade` to automatically select all missing dependencies. */ - bool hasAllDependencies() const { return m_hasAllDependencies; } + bool hasAllDependencies() const { return m_missingDependencies.length == 0; } + + /// Sorted list of missing dependencies. + string[] missingDependencies() { return m_missingDependencies; } /** Allows iteration of the dependency tree in topological order */ @@ -318,7 +321,7 @@ void reinit() { m_dependencies = null; - m_hasAllDependencies = true; + m_missingDependencies = []; m_packageManager.refresh(false); void collectDependenciesRec(Package pack, int depth = 0) @@ -346,7 +349,7 @@ try p = m_packageManager.getSubPackage(m_rootPackage.basePackage, subname, false); catch (Exception e) { logDiagnostic("%sError getting sub package %s: %s", indent, dep.name, e.msg); - if (is_desired) m_hasAllDependencies = false; + if (is_desired) m_missingDependencies ~= dep.name; continue; } } else if (m_selections.hasSelectedVersion(basename)) { @@ -386,7 +389,7 @@ if (!p) { logDiagnostic("%sMissing dependency %s %s of %s", indent, dep.name, vspec, pack.name); - if (is_desired) m_hasAllDependencies = false; + if (is_desired) m_missingDependencies ~= dep.name; continue; } @@ -403,6 +406,7 @@ } } collectDependenciesRec(m_rootPackage); + m_missingDependencies.sort(); } /// Returns the name of the root package. @@ -991,6 +995,8 @@ case "post-generate-commands": return listBuildSetting!"postGenerateCommands"(args); case "pre-build-commands": return listBuildSetting!"preBuildCommands"(args); case "post-build-commands": return listBuildSetting!"postBuildCommands"(args); + case "pre-run-commands": return listBuildSetting!"preRunCommands"(args); + case "post-run-commands": return listBuildSetting!"postRunCommands"(args); case "requirements": return listBuildSetting!"requirements"(args); case "options": return listBuildSetting!"options"(args); @@ -1149,12 +1155,16 @@ dst.addCopyFiles(processVars(project, pack, gsettings, settings.copyFiles, true)); dst.addVersions(processVars(project, pack, gsettings, settings.versions)); dst.addDebugVersions(processVars(project, pack, gsettings, settings.debugVersions)); + dst.addVersionFilters(processVars(project, pack, gsettings, settings.versionFilters)); + dst.addDebugVersionFilters(processVars(project, pack, gsettings, settings.debugVersionFilters)); dst.addImportPaths(processVars(project, pack, gsettings, settings.importPaths, true)); dst.addStringImportPaths(processVars(project, pack, gsettings, settings.stringImportPaths, true)); dst.addPreGenerateCommands(processVars(project, pack, gsettings, settings.preGenerateCommands)); dst.addPostGenerateCommands(processVars(project, pack, gsettings, settings.postGenerateCommands)); dst.addPreBuildCommands(processVars(project, pack, gsettings, settings.preBuildCommands)); dst.addPostBuildCommands(processVars(project, pack, gsettings, settings.postBuildCommands)); + dst.addPreRunCommands(processVars(project, pack, gsettings, settings.preRunCommands)); + dst.addPostRunCommands(processVars(project, pack, gsettings, settings.postRunCommands)); dst.addRequirements(settings.requirements); dst.addOptions(settings.options); @@ -1205,8 +1215,10 @@ private string getVariable(Project, Package)(string name, in Project project, in Package pack, in GeneratorSettings gsettings) { - import std.process : environment; + import dub.internal.utils : getDUBExePath; + import std.process : environment, escapeShellFileName; import std.uni : asUpperCase; + NativePath path; if (name == "PACKAGE_DIR") path = pack.path; @@ -1230,6 +1242,10 @@ return path.toNativeString(); } + if (name == "DUB") { + return getDUBExePath(gsettings.platform.compilerBinary); + } + if (name == "ARCH") { foreach (a; gsettings.platform.architecture) return a; diff --git a/source/dub/recipe/json.d b/source/dub/recipe/json.d index a254e89..418f827 100644 --- a/source/dub/recipe/json.d +++ b/source/dub/recipe/json.d @@ -214,12 +214,16 @@ case "copyFiles": bs.copyFiles[suffix] = deserializeJson!(string[])(value); break; case "versions": bs.versions[suffix] = deserializeJson!(string[])(value); break; case "debugVersions": bs.debugVersions[suffix] = deserializeJson!(string[])(value); break; + case "-versionFilters": bs.versionFilters[suffix] = deserializeJson!(string[])(value); break; + case "-debugVersionFilters": bs.debugVersionFilters[suffix] = deserializeJson!(string[])(value); break; case "importPaths": bs.importPaths[suffix] = deserializeJson!(string[])(value); break; case "stringImportPaths": bs.stringImportPaths[suffix] = deserializeJson!(string[])(value); break; case "preGenerateCommands": bs.preGenerateCommands[suffix] = deserializeJson!(string[])(value); break; case "postGenerateCommands": bs.postGenerateCommands[suffix] = deserializeJson!(string[])(value); break; case "preBuildCommands": bs.preBuildCommands[suffix] = deserializeJson!(string[])(value); break; case "postBuildCommands": bs.postBuildCommands[suffix] = deserializeJson!(string[])(value); break; + case "preRunCommands": bs.preRunCommands[suffix] = deserializeJson!(string[])(value); break; + case "postRunCommands": bs.postRunCommands[suffix] = deserializeJson!(string[])(value); break; case "buildRequirements": BuildRequirements reqs; foreach (req; deserializeJson!(string[])(value)) @@ -261,12 +265,16 @@ foreach (suffix, arr; bs.copyFiles) ret["copyFiles"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.versions) ret["versions"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.debugVersions) ret["debugVersions"~suffix] = serializeToJson(arr); + foreach (suffix, arr; bs.versionFilters) ret["-versionFilters"~suffix] = serializeToJson(arr); + foreach (suffix, arr; bs.debugVersionFilters) ret["-debugVersionFilters"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.importPaths) ret["importPaths"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.stringImportPaths) ret["stringImportPaths"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.preGenerateCommands) ret["preGenerateCommands"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.postGenerateCommands) ret["postGenerateCommands"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.preBuildCommands) ret["preBuildCommands"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.postBuildCommands) ret["postBuildCommands"~suffix] = serializeToJson(arr); + foreach (suffix, arr; bs.preRunCommands) ret["preRunCommands"~suffix] = serializeToJson(arr); + foreach (suffix, arr; bs.postRunCommands) ret["postRunCommands"~suffix] = serializeToJson(arr); foreach (suffix, arr; bs.buildRequirements) { string[] val; foreach (i; [EnumMembers!BuildRequirement]) diff --git a/source/dub/recipe/packagerecipe.d b/source/dub/recipe/packagerecipe.d index 7775bdb..d4382b2 100644 --- a/source/dub/recipe/packagerecipe.d +++ b/source/dub/recipe/packagerecipe.d @@ -20,6 +20,7 @@ import std.exception : enforce; import std.file; import std.range; +import std.process : environment; /** @@ -151,12 +152,16 @@ string[][string] copyFiles; string[][string] versions; string[][string] debugVersions; + string[][string] versionFilters; + string[][string] debugVersionFilters; string[][string] importPaths; string[][string] stringImportPaths; string[][string] preGenerateCommands; string[][string] postGenerateCommands; string[][string] preBuildCommands; string[][string] postBuildCommands; + string[][string] preRunCommands; + string[][string] postRunCommands; BuildRequirements[string] buildRequirements; BuildOptions[string] buildOptions; @@ -179,6 +184,9 @@ { auto files = appender!(string[]); + import dub.project : buildSettingsVars; + auto envVars = environment.toAA(); + foreach (suffix, paths; paths_map) { if (!platform.matchesSpecification(suffix)) continue; @@ -188,9 +196,8 @@ auto path = NativePath(spath); if (!path.absolute) path = base_path ~ path; if (!existsFile(path) || !isDir(path.toNativeString())) { - import dub.project : buildSettingsVars; import std.algorithm : any, find; - const hasVar = buildSettingsVars.any!((string var) { + const hasVar = chain(buildSettingsVars, envVars.byKey).any!((string var) { return spath.find("$"~var).length > 0 || spath.find("${"~var~"}").length > 0; }); if (!hasVar) @@ -232,12 +239,16 @@ getPlatformSetting!("copyFiles", "addCopyFiles")(dst, platform); getPlatformSetting!("versions", "addVersions")(dst, platform); getPlatformSetting!("debugVersions", "addDebugVersions")(dst, platform); + getPlatformSetting!("versionFilters", "addVersionFilters")(dst, platform); + getPlatformSetting!("debugVersionFilters", "addDebugVersionFilters")(dst, platform); getPlatformSetting!("importPaths", "addImportPaths")(dst, platform); getPlatformSetting!("stringImportPaths", "addStringImportPaths")(dst, platform); getPlatformSetting!("preGenerateCommands", "addPreGenerateCommands")(dst, platform); getPlatformSetting!("postGenerateCommands", "addPostGenerateCommands")(dst, platform); getPlatformSetting!("preBuildCommands", "addPreBuildCommands")(dst, platform); getPlatformSetting!("postBuildCommands", "addPostBuildCommands")(dst, platform); + getPlatformSetting!("preRunCommands", "addPreRunCommands")(dst, platform); + getPlatformSetting!("postRunCommands", "addPostRunCommands")(dst, platform); getPlatformSetting!("buildRequirements", "addRequirements")(dst, platform); getPlatformSetting!("buildOptions", "addOptions")(dst, platform); } diff --git a/source/dub/recipe/sdl.d b/source/dub/recipe/sdl.d index 33dc59d..cecca7c 100644 --- a/source/dub/recipe/sdl.d +++ b/source/dub/recipe/sdl.d @@ -121,7 +121,7 @@ private void parseBuildSettings(Tag settings, ref BuildSettingsTemplate bs, string package_name) { - foreach (setting; settings.tags) + foreach (setting; settings.all.tags) parseBuildSetting(setting, bs, package_name); } @@ -150,12 +150,16 @@ case "copyFiles": setting.parsePlatformStringArray(bs.copyFiles); break; case "versions": setting.parsePlatformStringArray(bs.versions); break; case "debugVersions": setting.parsePlatformStringArray(bs.debugVersions); break; + case "x:versionFilters": setting.parsePlatformStringArray(bs.versionFilters); break; + case "x:debugVersionFilters": setting.parsePlatformStringArray(bs.debugVersionFilters); break; case "importPaths": setting.parsePlatformStringArray(bs.importPaths); break; case "stringImportPaths": setting.parsePlatformStringArray(bs.stringImportPaths); break; case "preGenerateCommands": setting.parsePlatformStringArray(bs.preGenerateCommands); break; case "postGenerateCommands": setting.parsePlatformStringArray(bs.postGenerateCommands); break; case "preBuildCommands": setting.parsePlatformStringArray(bs.preBuildCommands); break; case "postBuildCommands": setting.parsePlatformStringArray(bs.postBuildCommands); break; + case "preRunCommands": setting.parsePlatformStringArray(bs.preRunCommands); break; + case "postRunCommands": setting.parsePlatformStringArray(bs.postRunCommands); break; case "buildRequirements": setting.parsePlatformEnumArray!BuildRequirement(bs.buildRequirements); break; case "buildOptions": setting.parsePlatformEnumArray!BuildOption(bs.buildOptions); break; } @@ -214,9 +218,9 @@ private Tag[] toSDL(in ref BuildSettingsTemplate bs) { Tag[] ret; - void add(string name, string value) { ret ~= new Tag(null, name, [Value(value)]); } - void adda(string name, string suffix, in string[] values) { - ret ~= new Tag(null, name, values[].map!(v => Value(v)).array, + void add(string name, string value, string namespace = null) { ret ~= new Tag(namespace, name, [Value(value)]); } + void adda(string name, string suffix, in string[] values, string namespace = null) { + ret ~= new Tag(namespace, name, values[].map!(v => Value(v)).array, suffix.length ? [new Attribute(null, "platform", Value(suffix[1 .. $]))] : null); } @@ -251,12 +255,16 @@ foreach (suffix, arr; bs.copyFiles) adda("copyFiles", suffix, arr); foreach (suffix, arr; bs.versions) adda("versions", suffix, arr); foreach (suffix, arr; bs.debugVersions) adda("debugVersions", suffix, arr); + foreach (suffix, arr; bs.versionFilters) adda("versionFilters", suffix, arr, "x"); + foreach (suffix, arr; bs.debugVersionFilters) adda("debugVersionFilters", suffix, arr, "x"); foreach (suffix, arr; bs.importPaths) adda("importPaths", suffix, arr); foreach (suffix, arr; bs.stringImportPaths) adda("stringImportPaths", suffix, arr); foreach (suffix, arr; bs.preGenerateCommands) adda("preGenerateCommands", suffix, arr); foreach (suffix, arr; bs.postGenerateCommands) adda("postGenerateCommands", suffix, arr); foreach (suffix, arr; bs.preBuildCommands) adda("preBuildCommands", suffix, arr); foreach (suffix, arr; bs.postBuildCommands) adda("postBuildCommands", suffix, arr); + foreach (suffix, arr; bs.preRunCommands) adda("preRunCommands", suffix, arr); + foreach (suffix, arr; bs.postRunCommands) adda("postRunCommands", suffix, arr); foreach (suffix, bits; bs.buildRequirements) adda("buildRequirements", suffix, toNameArray!BuildRequirement(bits)); foreach (suffix, bits; bs.buildOptions) adda("buildOptions", suffix, toNameArray!BuildOption(bits)); return ret; @@ -388,6 +396,12 @@ versions "version3" debugVersions "debug1" "debug2" debugVersions "debug3" +x:versionFilters "version1" "version2" +x:versionFilters "version3" +x:versionFilters +x:debugVersionFilters "debug1" "debug2" +x:debugVersionFilters "debug3" +x:debugVersionFilters importPaths "import1" "import2" importPaths "import3" stringImportPaths "string1" "string2" @@ -400,6 +414,10 @@ preBuildCommands "preb3" postBuildCommands "postb1" "postb2" postBuildCommands "postb3" +preRunCommands "prer1" "prer2" +preRunCommands "prer3" +postRunCommands "postr1" "postr2" +postRunCommands "postr3" dflags "df1" "df2" dflags "df3" lflags "lf1" "lf2" @@ -460,12 +478,16 @@ assert(rec.buildSettings.copyFiles == ["": ["copy1", "copy2", "copy3"]]); assert(rec.buildSettings.versions == ["": ["version1", "version2", "version3"]]); assert(rec.buildSettings.debugVersions == ["": ["debug1", "debug2", "debug3"]]); + assert(rec.buildSettings.versionFilters == ["": ["version1", "version2", "version3"]]); + assert(rec.buildSettings.debugVersionFilters == ["": ["debug1", "debug2", "debug3"]]); assert(rec.buildSettings.importPaths == ["": ["import1", "import2", "import3"]]); assert(rec.buildSettings.stringImportPaths == ["": ["string1", "string2", "string3"]]); assert(rec.buildSettings.preGenerateCommands == ["": ["preg1", "preg2", "preg3"]]); assert(rec.buildSettings.postGenerateCommands == ["": ["postg1", "postg2", "postg3"]]); assert(rec.buildSettings.preBuildCommands == ["": ["preb1", "preb2", "preb3"]]); assert(rec.buildSettings.postBuildCommands == ["": ["postb1", "postb2", "postb3"]]); + assert(rec.buildSettings.preRunCommands == ["": ["prer1", "prer2", "prer3"]]); + assert(rec.buildSettings.postRunCommands == ["": ["postr1", "postr2", "postr3"]]); assert(rec.buildSettings.dflags == ["": ["df1", "df2", "df3"]]); assert(rec.buildSettings.lflags == ["": ["lf1", "lf2", "lf3"]]); } diff --git a/test/4-describe-data-1-list.sh b/test/4-describe-data-1-list.sh index def3899..630b609 100755 --- a/test/4-describe-data-1-list.sh +++ b/test/4-describe-data-1-list.sh @@ -12,7 +12,8 @@ trap cleanup EXIT -if ! $DUB describe --compiler=$DC --data-list \ +if ! $DUB describe --compiler=$DC --filter-versions \ + --data-list \ '--data= target-type , target-path , target-name ' \ '--data= working-directory ' \ --data=main-source-file \ @@ -77,11 +78,8 @@ echo >> "$expected_file" # --data=versions echo "someVerIdent" >> "$expected_file" -echo "Have_describe_project" >> "$expected_file" -echo "Have_describe_dependency_1" >> "$expected_file" -echo "Have_describe_dependency_2" >> "$expected_file" -echo "Have_describe_dependency_3" >> "$expected_file" echo "anotherVerIdent" >> "$expected_file" +echo "Have_describe_dependency_3" >> "$expected_file" echo >> "$expected_file" # --data=debug-versions echo "someDebugVerIdent" >> "$expected_file" diff --git a/test/4-describe-data-2-dmd.sh b/test/4-describe-data-2-dmd.sh index 225537a..5120f1b 100755 --- a/test/4-describe-data-2-dmd.sh +++ b/test/4-describe-data-2-dmd.sh @@ -54,11 +54,8 @@ echo -n "'$CURR_DIR/describe-dependency-1/source/dummy.d' " >> "$expected_file" # --data=versions echo -n "-version=someVerIdent " >> "$expected_file" -echo -n "-version=Have_describe_project " >> "$expected_file" -echo -n "-version=Have_describe_dependency_1 " >> "$expected_file" -echo -n "-version=Have_describe_dependency_2 " >> "$expected_file" -echo -n "-version=Have_describe_dependency_3 " >> "$expected_file" echo -n "-version=anotherVerIdent " >> "$expected_file" +echo -n "-version=Have_describe_dependency_3 " >> "$expected_file" # --data=debug-versions echo -n "-debug=someDebugVerIdent " >> "$expected_file" echo -n "-debug=anotherDebugVerIdent " >> "$expected_file" diff --git a/test/describe-dependency-1/source/dummy.d b/test/describe-dependency-1/source/dummy.d index 8b13789..3c1514d 100644 --- a/test/describe-dependency-1/source/dummy.d +++ b/test/describe-dependency-1/source/dummy.d @@ -1 +1,2 @@ - +version (anotherVerIdent) {} +debug (anotherDebugVerIdent) {} diff --git a/test/describe-project/src/dummy.d b/test/describe-project/src/dummy.d index 8b13789..733017c 100644 --- a/test/describe-project/src/dummy.d +++ b/test/describe-project/src/dummy.d @@ -1 +1,3 @@ - +version (Have_describe_dependency_3) {} +version (someVerIdent) {} +debug (someDebugVerIdent) {} diff --git a/test/issue103-single-file-package-no-ext b/test/issue103-single-file-package-no-ext new file mode 100755 index 0000000..8c76638 --- /dev/null +++ b/test/issue103-single-file-package-no-ext @@ -0,0 +1,12 @@ +#!../bin/dub +/+ dub.sdl: + name "single-file-test" ++/ +module hello; + +void main(string[] args) +{ + import std.stdio : writeln; + assert(args.length == 4 && args[1 .. 4] == ["foo", "--", "bar"]); + writeln("Hello, World!"); +} diff --git a/test/issue103-single-file-package.sh b/test/issue103-single-file-package.sh index 0c23eb2..cce4674 100755 --- a/test/issue103-single-file-package.sh +++ b/test/issue103-single-file-package.sh @@ -10,6 +10,8 @@ rm single-file-test ./issue103-single-file-package.d foo -- bar +${DUB} ./issue103-single-file-package foo -- bar +./issue103-single-file-package-no-ext foo -- bar ${DUB} issue103-single-file-package-w-dep.d diff --git a/test/issue1136-temp-copy-files.sh b/test/issue1136-temp-copy-files.sh new file mode 100755 index 0000000..ab935cb --- /dev/null +++ b/test/issue1136-temp-copy-files.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +. $(dirname "${BASH_SOURCE[0]}")/common.sh +cd ${CURR_DIR}/issue1136-temp-copy-files + +"$DUB" app.d diff --git a/test/issue1136-temp-copy-files/.no_build b/test/issue1136-temp-copy-files/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1136-temp-copy-files/.no_build diff --git a/test/issue1136-temp-copy-files/app.d b/test/issue1136-temp-copy-files/app.d new file mode 100644 index 0000000..3883984 --- /dev/null +++ b/test/issue1136-temp-copy-files/app.d @@ -0,0 +1,15 @@ +/+ dub.sdl: + +name "app" +dependency "mylib" path="./mylib" ++/ + +import std.exception: enforce; +import std.file: exists, thisExePath; +import std.path: dirName, buildPath; + +void main() +{ + string filePath = buildPath(thisExePath.dirName, "helloworld.txt"); + enforce(filePath.exists); +} \ No newline at end of file diff --git a/test/issue1136-temp-copy-files/mylib/dub.sdl b/test/issue1136-temp-copy-files/mylib/dub.sdl new file mode 100644 index 0000000..8276ed1 --- /dev/null +++ b/test/issue1136-temp-copy-files/mylib/dub.sdl @@ -0,0 +1,3 @@ +name "mylib" +copyFiles "./helloworld.txt" +targetType "none" \ No newline at end of file diff --git a/test/issue1136-temp-copy-files/mylib/helloworld.txt b/test/issue1136-temp-copy-files/mylib/helloworld.txt new file mode 100644 index 0000000..bc7774a --- /dev/null +++ b/test/issue1136-temp-copy-files/mylib/helloworld.txt @@ -0,0 +1 @@ +hello world! \ No newline at end of file diff --git a/test/issue1396-pre-post-run-commands.sh b/test/issue1396-pre-post-run-commands.sh new file mode 100755 index 0000000..fdb797e --- /dev/null +++ b/test/issue1396-pre-post-run-commands.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +. $(dirname "${BASH_SOURCE[0]}")/common.sh +cd ${CURR_DIR}/issue1396-pre-post-run-commands +rm -rf .dub +rm -rf test.txt +"$DUB" + +if ! grep -c -e "pre-run" test.txt; then + die $LINENO 'pre run not executed.' +fi + +if ! grep -c -e "post-run-0" test.txt; then + die $LINENO 'post run not executed.' +fi diff --git a/test/issue1396-pre-post-run-commands/.no_build b/test/issue1396-pre-post-run-commands/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1396-pre-post-run-commands/.no_build diff --git a/test/issue1396-pre-post-run-commands/dub.sdl b/test/issue1396-pre-post-run-commands/dub.sdl new file mode 100644 index 0000000..aaad878 --- /dev/null +++ b/test/issue1396-pre-post-run-commands/dub.sdl @@ -0,0 +1,3 @@ +name "test" +preRunCommands "echo pre-run >> test.txt" +postRunCommands "./post-run.sh" \ No newline at end of file diff --git a/test/issue1396-pre-post-run-commands/post-run.sh b/test/issue1396-pre-post-run-commands/post-run.sh new file mode 100755 index 0000000..7b98010 --- /dev/null +++ b/test/issue1396-pre-post-run-commands/post-run.sh @@ -0,0 +1 @@ +echo post-run-$DUB_TARGET_EXIT_STATUS >> test.txt \ No newline at end of file diff --git a/test/issue1396-pre-post-run-commands/source/app.d b/test/issue1396-pre-post-run-commands/source/app.d new file mode 100644 index 0000000..ab73b3a --- /dev/null +++ b/test/issue1396-pre-post-run-commands/source/app.d @@ -0,0 +1 @@ +void main() {} diff --git a/test/issue1504-envvar-in-path.sh b/test/issue1504-envvar-in-path.sh new file mode 100755 index 0000000..51cb805 --- /dev/null +++ b/test/issue1504-envvar-in-path.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e + +. $(dirname "${BASH_SOURCE[0]}")/common.sh + +rm -rf ${CURR_DIR}/issue1504-envvar-in-path/.dub +rm -rf ${CURR_DIR}/issue1504-envvar-in-path/test +rm -rf ${CURR_DIR}/output-1504.txt + + +export MY_VARIABLE=teststrings +# pragma(msg) outputs to stderr +${DUB} build --force --root ${CURR_DIR}/issue1504-envvar-in-path 2> ${CURR_DIR}/output-1504.txt + +grep "env_variables_work" < ${CURR_DIR}/output-1504.txt + +# Don't manage to make it work +#grep "Invalid source" < ${CURR_DIR}/output-1504.txt && true + diff --git a/test/issue1504-envvar-in-path/.no_build b/test/issue1504-envvar-in-path/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1504-envvar-in-path/.no_build diff --git a/test/issue1504-envvar-in-path/dub.json b/test/issue1504-envvar-in-path/dub.json new file mode 100644 index 0000000..1858aa6 --- /dev/null +++ b/test/issue1504-envvar-in-path/dub.json @@ -0,0 +1,5 @@ +{ + "name": "test", + "stringImportPaths": ["$MY_VARIABLE"] +} + diff --git a/test/issue1504-envvar-in-path/source/app.d b/test/issue1504-envvar-in-path/source/app.d new file mode 100644 index 0000000..131d984 --- /dev/null +++ b/test/issue1504-envvar-in-path/source/app.d @@ -0,0 +1,5 @@ +pragma(msg, import("message.txt")); + +void main() +{ +} \ No newline at end of file diff --git a/test/issue1504-envvar-in-path/teststrings/message.txt b/test/issue1504-envvar-in-path/teststrings/message.txt new file mode 100644 index 0000000..88f0c20 --- /dev/null +++ b/test/issue1504-envvar-in-path/teststrings/message.txt @@ -0,0 +1 @@ +env_variables_work \ No newline at end of file diff --git a/test/issue1524-maven-upgrade-dependency-tree.sh b/test/issue1524-maven-upgrade-dependency-tree.sh new file mode 100755 index 0000000..711cded --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +DIR=$(dirname "${BASH_SOURCE[0]}") + +. "$DIR"/common.sh + +PORT=$(($$ + 1024)) # PID + 1024 + +dub remove maven-dubpackage-a --non-interactive --version=* 2>/dev/null || true +dub remove maven-dubpackage-b --non-interactive --version=* 2>/dev/null || true + +"$DUB" build --single "$DIR"/test_registry.d +"$DIR"/test_registry --folder="$DIR/issue1524-maven-upgrade-dependency-tree" --port=$PORT & +PID=$! +sleep 1 +trap 'kill $PID 2>/dev/null || true' exit + +echo "Trying to download maven-dubpackage-a (1.0.5) with dependency to maven-dubpackage-b (1.0.6)" +"$DUB" upgrade --root "$DIR/issue1524-maven-upgrade-dependency-tree" --skip-registry=standard --registry=mvn+http://localhost:$PORT/maven/release/dubpackages + +if ! dub remove maven-dubpackage-a --non-interactive --version=1.0.5 2>/dev/null; then + die 'DUB did not install package "maven-dubpackage-a" from maven registry.' +fi + +if ! dub remove maven-dubpackage-b --non-interactive --version=1.0.6 2>/dev/null; then + die 'DUB did not install package "maven-dubpackage-b" from maven registry.' +fi + diff --git a/test/issue1524-maven-upgrade-dependency-tree.sh.min_frontend b/test/issue1524-maven-upgrade-dependency-tree.sh.min_frontend new file mode 100644 index 0000000..bb0a2e1 --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree.sh.min_frontend @@ -0,0 +1 @@ +2.076 diff --git a/test/issue1524-maven-upgrade-dependency-tree/.gitignore b/test/issue1524-maven-upgrade-dependency-tree/.gitignore new file mode 100644 index 0000000..304e955 --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/.gitignore @@ -0,0 +1,8 @@ +.dub +docs.json +__dummy.html +docs/ +*.exe +*.o +*.obj +*.lst diff --git a/test/issue1524-maven-upgrade-dependency-tree/.no_build b/test/issue1524-maven-upgrade-dependency-tree/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/.no_build diff --git a/test/issue1524-maven-upgrade-dependency-tree/dub.json b/test/issue1524-maven-upgrade-dependency-tree/dub.json new file mode 100644 index 0000000..131a264 --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/dub.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "maven-dubpackage-a": "~>1.0.5" + } +} \ No newline at end of file diff --git a/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-a/1.0.5/maven-dubpackage-a-1.0.5.zip b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-a/1.0.5/maven-dubpackage-a-1.0.5.zip new file mode 100644 index 0000000..6d5cfc9 --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-a/1.0.5/maven-dubpackage-a-1.0.5.zip Binary files differ diff --git a/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-a/maven-metadata.xml b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-a/maven-metadata.xml new file mode 100644 index 0000000..b3202ee --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-a/maven-metadata.xml @@ -0,0 +1,13 @@ + + + dubpackages + maven-dubpackage-a + + 1.0.5 + 1.0.5 + + 1.0.5 + + 20180317184845 + + \ No newline at end of file diff --git a/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-b/1.0.6/maven-dubpackage-b-1.0.6.zip b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-b/1.0.6/maven-dubpackage-b-1.0.6.zip new file mode 100644 index 0000000..c793c0b --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-b/1.0.6/maven-dubpackage-b-1.0.6.zip Binary files differ diff --git a/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-b/maven-metadata.xml b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-b/maven-metadata.xml new file mode 100644 index 0000000..f7dcd2a --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/maven/release/dubpackages/maven-dubpackage-b/maven-metadata.xml @@ -0,0 +1,13 @@ + + + dubpackages + maven-dubpackage-b + + 1.0.6 + 1.0.6 + + 1.0.6 + + 20180317184845 + + \ No newline at end of file diff --git a/test/issue1524-maven-upgrade-dependency-tree/source/app.d b/test/issue1524-maven-upgrade-dependency-tree/source/app.d new file mode 100644 index 0000000..ef93217 --- /dev/null +++ b/test/issue1524-maven-upgrade-dependency-tree/source/app.d @@ -0,0 +1 @@ +void main(){} \ No newline at end of file diff --git a/test/issue1574-addcommand.sh b/test/issue1574-addcommand.sh new file mode 100755 index 0000000..c2fb1c7 --- /dev/null +++ b/test/issue1574-addcommand.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +DIR=$(dirname "${BASH_SOURCE[0]}") + +. "$DIR"/common.sh + +PORT=$(($$ + 1024)) # PID + 1024 +tempDir="issue1574-addcommand" + +"$DUB" build --single "$DIR"/test_registry.d +"$DIR"/test_registry --folder="$DIR/issue1336-registry" --port=$PORT & +PID=$! +sleep 1 + +function cleanup { + cd .. + rm -rf $tempDir + kill $PID 2>/dev/null || true +} +trap cleanup EXIT + + +$DUB init -n $tempDir +cd $tempDir + +echo "import gitcompatibledubpackage.subdir.file; void main(){}" > source/app.d + +$DUB add gitcompatibledubpackage --skip-registry=all --registry=http://localhost:$PORT + +#if dub fails to compile, that means that the "import mir.math.common" did not work +if ! $DUB build; then + die "Add command failed" +fi diff --git a/test/issue1574-addcommand.sh.min_frontend b/test/issue1574-addcommand.sh.min_frontend new file mode 100644 index 0000000..bb0a2e1 --- /dev/null +++ b/test/issue1574-addcommand.sh.min_frontend @@ -0,0 +1 @@ +2.076 diff --git a/test/pr1549-dub-exe-var.sh b/test/pr1549-dub-exe-var.sh new file mode 100755 index 0000000..7ad9f55 --- /dev/null +++ b/test/pr1549-dub-exe-var.sh @@ -0,0 +1,11 @@ +#! /usr/bin/env bash +set -e + +. $(dirname "${BASH_SOURCE[0]}")/common.sh + +PR1549=$CURR_DIR/pr1549-dub-exe-var + +${DUB} build --root ${PR1549} +OUTPUT=$(${PR1549}/test-application) + +if [[ "$OUTPUT" != "modified code" ]]; then die "\$DUB build variable was (likely) not evaluated correctly"; fi diff --git a/test/pr1549-dub-exe-var/.gitignore b/test/pr1549-dub-exe-var/.gitignore new file mode 100644 index 0000000..964cd1d --- /dev/null +++ b/test/pr1549-dub-exe-var/.gitignore @@ -0,0 +1,2 @@ +setmsg +setmsg.exe diff --git a/test/pr1549-dub-exe-var/.no_build b/test/pr1549-dub-exe-var/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/pr1549-dub-exe-var/.no_build diff --git a/test/pr1549-dub-exe-var/dub.sdl b/test/pr1549-dub-exe-var/dub.sdl new file mode 100644 index 0000000..fdb283a --- /dev/null +++ b/test/pr1549-dub-exe-var/dub.sdl @@ -0,0 +1,4 @@ +name "test-application" +targetType "executable" +preBuildCommands "$DUB run --single $PACKAGE_DIR/setmsg.d -- \"modified code\"" +postBuildCommands "$DUB run --single $PACKAGE_DIR/setmsg.d -- \"unmodified code\"" diff --git a/test/pr1549-dub-exe-var/setmsg.d b/test/pr1549-dub-exe-var/setmsg.d new file mode 100644 index 0000000..6eb7f93 --- /dev/null +++ b/test/pr1549-dub-exe-var/setmsg.d @@ -0,0 +1,21 @@ +/+ dub.sdl: ++/ + +import std.exception; +import std.path; +import std.process; +import std.stdio; + +void main(in string[] args) +{ + enforce(args.length > 1); + const string msg = args[1]; + + const path = buildPath(environment["DUB_PACKAGE_DIR"], "source", "app.d"); + auto file = File(path, "w"); + file.writeln(`import std.stdio;`); + file.writeln(); + file.writeln(`void main() {`); + file.writefln(` writeln("%s");`, msg); + file.writeln(`}`); +} diff --git a/test/pr1549-dub-exe-var/source/app.d b/test/pr1549-dub-exe-var/source/app.d new file mode 100644 index 0000000..e143585 --- /dev/null +++ b/test/pr1549-dub-exe-var/source/app.d @@ -0,0 +1,5 @@ +import std.stdio; + +void main() { + writeln("unmodified code"); +} diff --git a/test/version-filters-diamond/.gitignore b/test/version-filters-diamond/.gitignore new file mode 100644 index 0000000..c09a597 --- /dev/null +++ b/test/version-filters-diamond/.gitignore @@ -0,0 +1,15 @@ +.dub +docs.json +__dummy.html +docs/ +issue1262-version-inheritance-diamond +issue1262-version-inheritance-diamond.so +issue1262-version-inheritance-diamond.dylib +issue1262-version-inheritance-diamond.dll +issue1262-version-inheritance-diamond.a +issue1262-version-inheritance-diamond.lib +issue1262-version-inheritance-diamond-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters-diamond/.no_build b/test/version-filters-diamond/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-diamond/.no_build diff --git a/test/version-filters-diamond/.no_run b/test/version-filters-diamond/.no_run new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-diamond/.no_run diff --git a/test/version-filters-diamond/.no_test b/test/version-filters-diamond/.no_test new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-diamond/.no_test diff --git a/test/version-filters-diamond/daughter/.gitignore b/test/version-filters-diamond/daughter/.gitignore new file mode 100644 index 0000000..f190acb --- /dev/null +++ b/test/version-filters-diamond/daughter/.gitignore @@ -0,0 +1,14 @@ +.dub +docs.json +__dummy.html +docs/ +daughter.so +daughter.dylib +daughter.dll +daughter.a +daughter.lib +daughter-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters-diamond/daughter/dub.sdl b/test/version-filters-diamond/daughter/dub.sdl new file mode 100644 index 0000000..9562cc5 --- /dev/null +++ b/test/version-filters-diamond/daughter/dub.sdl @@ -0,0 +1,6 @@ +name "daughter" +versions "Daughter" +debugVersions "dDaughter" +x:versionFilters "Daughter" "Parent" +x:debugVersionFilters "dDaughter" "dParent" +dependency "diamond" path="../diamond" diff --git a/test/version-filters-diamond/daughter/source/dummy.d b/test/version-filters-diamond/daughter/source/dummy.d new file mode 100644 index 0000000..4006f06 --- /dev/null +++ b/test/version-filters-diamond/daughter/source/dummy.d @@ -0,0 +1,15 @@ +module daughter.dummy; + +version (Parent) {} else static assert(0, "Expected Parent to be set"); // via dependency +version (Daughter) {} else static assert(0, "Expected Daughter to be set"); // local +version (Son) static assert(0, "Expected Son to not be set"); +version (Diamond) static assert(0, "Expected Diamond to not be set"); + +debug (dParent) {} else static assert(0, "Expected dParent to be set"); // via dependency +debug (dDaughter) {} else static assert(0, "Expected dDaughter to be set"); // local +debug (dSon) {} else static assert(0, "Expected dSon to be set"); // via diamond dependency +debug (dDiamond) static assert(0, "Expected dDiamond to not be set"); + +version (Have_daughter) static assert(0, "Expected Have_daughter to not be set"); +version (Have_son) static assert(0, "Expected Have_son to not be set"); +version (Have_diamond) static assert(0, "Expected Have_diamond to not be set"); diff --git a/test/version-filters-diamond/diamond/.gitignore b/test/version-filters-diamond/diamond/.gitignore new file mode 100644 index 0000000..c359a73 --- /dev/null +++ b/test/version-filters-diamond/diamond/.gitignore @@ -0,0 +1,14 @@ +.dub +docs.json +__dummy.html +docs/ +diamond.so +diamond.dylib +diamond.dll +diamond.a +diamond.lib +diamond-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters-diamond/diamond/dub.sdl b/test/version-filters-diamond/diamond/dub.sdl new file mode 100644 index 0000000..afdb272 --- /dev/null +++ b/test/version-filters-diamond/diamond/dub.sdl @@ -0,0 +1,3 @@ +name "diamond" +versions "Diamond" +debugVersions "dDiamond" diff --git a/test/version-filters-diamond/diamond/source/dummy.d b/test/version-filters-diamond/diamond/source/dummy.d new file mode 100644 index 0000000..3c1fca5 --- /dev/null +++ b/test/version-filters-diamond/diamond/source/dummy.d @@ -0,0 +1,26 @@ +module diamond.dummy; + +template hasVersion(string v) +{ + mixin("version ("~v~") enum hasVersion = true; else enum hasVersion = false;"); +} + +template hasDebugVersion(string v) +{ + mixin("debug ("~v~") enum hasDebugVersion = true; else enum hasDebugVersion = false;"); +} + +// checking inference here +version (Parent) {} else static assert(0, "Expected Parent to be set"); +version (Daughter) {} else static assert(0, "Expected Daughter to be set"); +static assert(!hasVersion!"Son"); +static assert(!hasVersion!"Diamond"); + +debug (dParent) {} else static assert(0, "Expected dParent to be set"); +static assert(!hasDebugVersion!"dDaughter"); +debug (dSon) {} else static assert(0, "Expected dSon to be set"); +static assert(!hasDebugVersion!"dDiamond"); + +static assert(!hasVersion!"Have_daughter"); +static assert(!hasVersion!"Have_son"); +static assert(!hasVersion!"Have_diamond"); diff --git a/test/version-filters-diamond/dub.sdl b/test/version-filters-diamond/dub.sdl new file mode 100644 index 0000000..51295fd --- /dev/null +++ b/test/version-filters-diamond/dub.sdl @@ -0,0 +1,7 @@ +name "version-filters-diamond" +versions "Parent" +debugVersions "dParent" +x:versionFilters "Parent" +x:debugVersionFilters "dParent" +dependency "daughter" path="daughter" +dependency "son" path="son" diff --git a/test/version-filters-diamond/son/.gitignore b/test/version-filters-diamond/son/.gitignore new file mode 100644 index 0000000..601a33b --- /dev/null +++ b/test/version-filters-diamond/son/.gitignore @@ -0,0 +1,14 @@ +.dub +docs.json +__dummy.html +docs/ +son.so +son.dylib +son.dll +son.a +son.lib +son-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters-diamond/son/dub.sdl b/test/version-filters-diamond/son/dub.sdl new file mode 100644 index 0000000..3e0a630 --- /dev/null +++ b/test/version-filters-diamond/son/dub.sdl @@ -0,0 +1,6 @@ +name "son" +versions "Son" +debugVersions "dSon" +x:versionFilters "Son" +x:debugVersionFilters "dSon" +dependency "diamond" path="../diamond" diff --git a/test/version-filters-diamond/son/source/dummy.d b/test/version-filters-diamond/son/source/dummy.d new file mode 100644 index 0000000..7e56da0 --- /dev/null +++ b/test/version-filters-diamond/son/source/dummy.d @@ -0,0 +1,15 @@ +module son.dummy; + +version (Parent) {} else static assert(0, "Expected Parent to be set"); // via dependency +version (Daughter) {} else static assert(0, "Expected Daughter to not be set"); // via diamond dependency +version (Son) {} else static assert(0, "Expected Son to be set"); // local +version (Diamond) static assert(0, "Expected Diamond to not be set"); + +debug (dParent) {} else static assert(0, "Expected dParent to be set"); // via dependency +debug (dDaughter) static assert(0, "Expected dDaughter to not be set"); // via diamond dependency +debug (dSon) {} else static assert(0, "Expected dSon to be set"); // local +debug (dDiamond) static assert(0, "Expected dDiamond to not be set"); + +version (Have_daughter) static assert(0, "Expected Have_daughter to not be set"); +version (Have_son) static assert(0, "Expected Have_son to not be set"); +version (Have_diamond) static assert(0, "Expected Have_diamond to not be set"); diff --git a/test/version-filters-diamond/source/app.d b/test/version-filters-diamond/source/app.d new file mode 100644 index 0000000..2f19e5c --- /dev/null +++ b/test/version-filters-diamond/source/app.d @@ -0,0 +1,17 @@ +version (Parent) {} else static assert(0, "Expected Parent to be set"); // local +version (Daughter) {} else static assert(0, "Expected Daughter to not be set"); // via dependency +version (Son) {} else static assert(0, "Expected Son to not be set"); // via dependency +version (Diamond) static assert(0, "Expected Diamond to not be set"); // unused by dependencies + +debug (dParent) {} else static assert(0, "Expected dParent to be set"); // local +debug (dDaughter) {} else static assert(0, "Expected dDaughter to be set"); // via dependency +debug (dSon) {} else static assert(0, "Expected dSon to not be set"); // via dependency +debug (dDiamond) static assert(0, "Expected dDiamond to not be set"); // unused by dependencies + +version (Have_daugther) static assert(0, "Expected Have_daugther to not be set"); +version (Have_son) static assert(0, "Expected Have_son to not be set"); +version (Have_diamond) static assert(0, "Expected Have_diamond to not be set"); + +void main() +{ +} diff --git a/test/version-filters-none/.gitignore b/test/version-filters-none/.gitignore new file mode 100644 index 0000000..c09a597 --- /dev/null +++ b/test/version-filters-none/.gitignore @@ -0,0 +1,15 @@ +.dub +docs.json +__dummy.html +docs/ +issue1262-version-inheritance-diamond +issue1262-version-inheritance-diamond.so +issue1262-version-inheritance-diamond.dylib +issue1262-version-inheritance-diamond.dll +issue1262-version-inheritance-diamond.a +issue1262-version-inheritance-diamond.lib +issue1262-version-inheritance-diamond-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters-none/.no_build b/test/version-filters-none/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-none/.no_build diff --git a/test/version-filters-none/.no_run b/test/version-filters-none/.no_run new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-none/.no_run diff --git a/test/version-filters-none/.no_test b/test/version-filters-none/.no_test new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-none/.no_test diff --git a/test/version-filters-none/dub.sdl b/test/version-filters-none/dub.sdl new file mode 100644 index 0000000..5ad696c --- /dev/null +++ b/test/version-filters-none/dub.sdl @@ -0,0 +1,4 @@ +name "version-filters-none" +versions "Parent" +debugVersions "dParent" +x:versionFilters "none" diff --git a/test/version-filters-none/source/app.d b/test/version-filters-none/source/app.d new file mode 100644 index 0000000..cafe4cf --- /dev/null +++ b/test/version-filters-none/source/app.d @@ -0,0 +1,6 @@ +version (Parent) static assert(0, "Expected Parent to not be set"); +debug (dParent) static assert(0, "Expected dParent to not be set"); + +void main() +{ +} diff --git a/test/version-filters-source-dep/.gitignore b/test/version-filters-source-dep/.gitignore new file mode 100644 index 0000000..c09a597 --- /dev/null +++ b/test/version-filters-source-dep/.gitignore @@ -0,0 +1,15 @@ +.dub +docs.json +__dummy.html +docs/ +issue1262-version-inheritance-diamond +issue1262-version-inheritance-diamond.so +issue1262-version-inheritance-diamond.dylib +issue1262-version-inheritance-diamond.dll +issue1262-version-inheritance-diamond.a +issue1262-version-inheritance-diamond.lib +issue1262-version-inheritance-diamond-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters-source-dep/.no_build b/test/version-filters-source-dep/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-source-dep/.no_build diff --git a/test/version-filters-source-dep/.no_run b/test/version-filters-source-dep/.no_run new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-source-dep/.no_run diff --git a/test/version-filters-source-dep/.no_test b/test/version-filters-source-dep/.no_test new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters-source-dep/.no_test diff --git a/test/version-filters-source-dep/dub.sdl b/test/version-filters-source-dep/dub.sdl new file mode 100644 index 0000000..73d4834 --- /dev/null +++ b/test/version-filters-source-dep/dub.sdl @@ -0,0 +1,5 @@ +name "version-filters-source-dep" +versions "Parent" +debugVersions "dParent" +x:versionFilters "none" +dependency "source-dep" path="source-dep" diff --git a/test/version-filters-source-dep/source-dep/dub.sdl b/test/version-filters-source-dep/source-dep/dub.sdl new file mode 100644 index 0000000..d9b7c63 --- /dev/null +++ b/test/version-filters-source-dep/source-dep/dub.sdl @@ -0,0 +1,7 @@ +name "source-dep" +versions "SourceDep" +debugVersions "dSourceDep" +# filter of sourceOnly libs are merged with dependents +x:versionFilters "SourceDep" +x:debugVersionFilters "dSourceDep" +targetType "sourceLibrary" diff --git a/test/version-filters-source-dep/source-dep/source/dummy.d b/test/version-filters-source-dep/source-dep/source/dummy.d new file mode 100644 index 0000000..daee233 --- /dev/null +++ b/test/version-filters-source-dep/source-dep/source/dummy.d @@ -0,0 +1,7 @@ +module sourcedep.dummy; + +version (Parent) static assert(0, "Expected Parent to not be set"); +version (SourceDep) {} else static assert(0, "Expected SourceDep to be set"); + +debug (dParent) static assert(0, "Expected dParent to not be set"); +debug (dSourceDep) {} else static assert(0, "Expected dSourceDep to be set"); diff --git a/test/version-filters-source-dep/source/app.d b/test/version-filters-source-dep/source/app.d new file mode 100644 index 0000000..13de8f5 --- /dev/null +++ b/test/version-filters-source-dep/source/app.d @@ -0,0 +1,9 @@ +version (Parent) static assert(0, "Expected Parent to not be set"); +version (SourceDep) {} else static assert(0, "Expected SourceDep to be set"); + +debug (dParent) static assert(0, "Expected dParent to not be set"); +debug (dSourceDep) {} else static assert(0, "Expected dSourceDep to be set"); + +void main() +{ +} diff --git a/test/version-filters.sh b/test/version-filters.sh new file mode 100755 index 0000000..e92f3fa --- /dev/null +++ b/test/version-filters.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +. $(dirname "${BASH_SOURCE[0]}")/common.sh + +$DUB build --root="$CURR_DIR/version-filters" --filter-versions +$DUB build --root="$CURR_DIR/version-filters-diamond" --filter-versions +$DUB build --root="$CURR_DIR/version-filters-source-dep" --filter-versions +$DUB build --root="$CURR_DIR/version-filters-none" --filter-versions diff --git a/test/version-filters/.gitignore b/test/version-filters/.gitignore new file mode 100644 index 0000000..c09a597 --- /dev/null +++ b/test/version-filters/.gitignore @@ -0,0 +1,15 @@ +.dub +docs.json +__dummy.html +docs/ +issue1262-version-inheritance-diamond +issue1262-version-inheritance-diamond.so +issue1262-version-inheritance-diamond.dylib +issue1262-version-inheritance-diamond.dll +issue1262-version-inheritance-diamond.a +issue1262-version-inheritance-diamond.lib +issue1262-version-inheritance-diamond-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters/.no_build b/test/version-filters/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters/.no_build diff --git a/test/version-filters/.no_run b/test/version-filters/.no_run new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters/.no_run diff --git a/test/version-filters/.no_test b/test/version-filters/.no_test new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/version-filters/.no_test diff --git a/test/version-filters/daughter/.gitignore b/test/version-filters/daughter/.gitignore new file mode 100644 index 0000000..f190acb --- /dev/null +++ b/test/version-filters/daughter/.gitignore @@ -0,0 +1,14 @@ +.dub +docs.json +__dummy.html +docs/ +daughter.so +daughter.dylib +daughter.dll +daughter.a +daughter.lib +daughter-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters/daughter/dub.sdl b/test/version-filters/daughter/dub.sdl new file mode 100644 index 0000000..7eb94da --- /dev/null +++ b/test/version-filters/daughter/dub.sdl @@ -0,0 +1,5 @@ +name "daughter" +versions "Daughter" +debugVersions "dDaughter" +x:versionFilters "Daughter" "Parent" +x:debugVersionFilters "dDaughter" "dParent" diff --git a/test/version-filters/daughter/source/dummy.d b/test/version-filters/daughter/source/dummy.d new file mode 100644 index 0000000..7295801 --- /dev/null +++ b/test/version-filters/daughter/source/dummy.d @@ -0,0 +1,12 @@ +module daughter.dummy; + +version (Parent) {} else static assert(0, "Expected Parent to be set"); +version (Daughter) {} else static assert(0, "Expected Daughter to be set"); +version (Son) static assert(0, "Expected Son to not be set"); + +debug (dParent) {} else static assert(0, "Expected dParent to be set"); +debug (dDaughter) {} else static assert(0, "Expected dDaughter to be set"); +debug (dSon) static assert(0, "Expected dSon to not be set"); + +version (Have_daughter) static assert(0, "Expected Have_daughter to not be set"); +version (Have_son) static assert(0, "Expected Have_son to not be set"); diff --git a/test/version-filters/dub.sdl b/test/version-filters/dub.sdl new file mode 100644 index 0000000..9f79da4 --- /dev/null +++ b/test/version-filters/dub.sdl @@ -0,0 +1,7 @@ +name "version-filters" +versions "Parent" +debugVersions "dParent" +x:versionFilters "Parent" +x:debugVersionFilters "dParent" +dependency "daughter" path="daughter" +dependency "son" path="son" diff --git a/test/version-filters/son/.gitignore b/test/version-filters/son/.gitignore new file mode 100644 index 0000000..601a33b --- /dev/null +++ b/test/version-filters/son/.gitignore @@ -0,0 +1,14 @@ +.dub +docs.json +__dummy.html +docs/ +son.so +son.dylib +son.dll +son.a +son.lib +son-test-* +*.exe +*.o +*.obj +*.lst diff --git a/test/version-filters/son/dub.sdl b/test/version-filters/son/dub.sdl new file mode 100644 index 0000000..e851dd6 --- /dev/null +++ b/test/version-filters/son/dub.sdl @@ -0,0 +1,5 @@ +name "son" +versions "Son" +debugVersions "dSon" +x:versionFilters "Son" +x:debugVersionFilters "dSon" diff --git a/test/version-filters/son/source/dummy.d b/test/version-filters/son/source/dummy.d new file mode 100644 index 0000000..0cfbcd3 --- /dev/null +++ b/test/version-filters/son/source/dummy.d @@ -0,0 +1,12 @@ +module son.dummy; + +version (Parent) static assert(0, "Expected Parent to not be set"); +version (Daughter) static assert(0, "Expected Daughter to not be set"); +version (Son) {} else static assert(0, "Expected Son to be set"); + +debug (dParent) static assert(0, "Expected dParent to not be set"); +debug (dDaughter) static assert(0, "Expected dDaughter to not be set"); +debug (dSon) {} else static assert(0, "Expected dSon to be set"); + +version (Have_daughter) static assert(0, "Expected Have_daughter to not be set"); +version (Have_son) static assert(0, "Expected Have_son to not be set"); diff --git a/test/version-filters/source/app.d b/test/version-filters/source/app.d new file mode 100644 index 0000000..e674170 --- /dev/null +++ b/test/version-filters/source/app.d @@ -0,0 +1,14 @@ +version (Parent) {} else static assert(0, "Expected Parent to be set"); // local +version (Daughter) {} else static assert(0, "Expected Daughter to be set"); // via dependency +version (Son) {} else static assert(0, "Expected Son to be set"); // via dependency + +debug (dParent) {} else static assert(0, "Expected dParent to be set"); // local +debug (dDaughter) {} else static assert(0, "Expected dDaughter to be set"); // via dependency +debug (dSon) {} else static assert(0, "Expected dSon to be set"); // via dependency + +version (Have_daugther) static assert(0, "Expected Have_daugther to not be set"); +version (Have_son) static assert(0, "Expected Have_son to not be set"); + +void main() +{ +}