diff --git a/.travis.yml b/.travis.yml index 4b2fbd8..e92df82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,11 @@ language: d -dist: trusty -sudo: false +dist: bionic addons: apt: packages: - libevent-dev -before_install: - # Use the dub-updating fork of the installer script until https://github.com/dlang/installer/pull/301 is merged - - wget https://raw.githubusercontent.com/wilzbach/installer-dub/master/script/install.sh -O ~/dlang/install.dub.sh - - . $(bash ~/dlang/install.dub.sh -a dub) - - dub --version - script: - ./travis-ci.sh @@ -21,32 +14,18 @@ - d: gdc include: - stage: test - d: dmd-2.086.0 - env: [FRONTEND=2.086] - - d: dmd-2.081.1 - env: [FRONTEND=2.081] - - d: dmd-2.080.1 - env: [FRONTEND=2.080] - - d: dmd-2.079.1 - env: [FRONTEND=2.078] - - d: dmd-2.078.1 - env: [FRONTEND=2.078] - - d: dmd-2.077.1 + d: dmd-2.089.0,dub + env: [FRONTEND=2.089] + - d: dmd-2.088.1,dub + env: [FRONTEND=2.088] + - d: dmd-2.077.1,dub env: [FRONTEND=2.077, COVERAGE=true] - - d: dmd-2.076.1 + - d: dmd-2.076.1,dub env: [FRONTEND=2.076] - - d: ldc-1.10.0 - env: [FRONTEND=2.080] - - d: ldc-1.9.0 - env: [FRONTEND=2.079] - - d: ldc-1.8.0 - env: [FRONTEND=2.078] - - d: ldc-1.7.0 - env: [FRONTEND=2.077] - - d: ldc-1.6.0 - env: [FRONTEND=2.076] + - d: ldc-1.18.0,dub + env: [FRONTEND=2.088] - stage: deploy - d: ldc-1.15.0 + d: ldc-1.18.0,dub os: osx script: echo "Deploying to GitHub releases ..." && ./release.sh deploy: @@ -57,7 +36,7 @@ api_key: $GH_REPO_TOKEN on: tags: true - - d: ldc-1.15.0 + - d: ldc-1.18.0,dub script: echo "Deploying to GitHub releases ..." && ./release.sh env: [ARCH=32] addons: @@ -73,7 +52,7 @@ api_key: $GH_REPO_TOKEN on: tags: true - - d: ldc-1.15.0 + - d: ldc-1.18.0,dub script: echo "Deploying to GitHub releases ..." && ./release.sh deploy: - provider: releases @@ -83,7 +62,7 @@ api_key: $GH_REPO_TOKEN on: tags: true - - d: ldc-1.15.0 + - d: ldc-1.18.0,dub script: echo "Deploying to GitHub releases (win32) ..." && ./release-windows.sh addons: apt: @@ -97,7 +76,7 @@ api_key: $GH_REPO_TOKEN on: tags: true - - d: ldc-1.15.0 + - d: ldc-1.18.0,dub script: echo "Deploying to GitHub releases (win64) ..." && ARCH=64 ./release-windows.sh addons: apt: diff --git a/README.md b/README.md index 030cf7a..8c2e953 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,11 @@ Daniel Jost maintains a dub package on [chocolatey](https://chocolatey.org/packages/dub). Use `cinst dub` or `cinst dub -version #.#.#` to install stable or a custom version respectively. +## Alpine Linux + +Mathias (@Geod24) Lang maintains the Alpine Linux packages. +It is currently part of 'edge' and can be installed through `apk --no-cache add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing dub`. + ## Using DUB as a library The [DUB package of DUB](http://code.dlang.org/packages/dub) can be used as a library to load or manipulate packages, or to resemble any functionality of the command line tool. The former task can be achieved by using the [Package class](https://github.com/dlang/dub/blob/master/source/dub/package_.d#L40). For examples on how to replicate the command line functionality, see [commandline.d](https://github.com/dlang/dub/blob/master/source/dub/commandline.d). diff --git a/build-files.txt b/build-files.txt index fbda121..34171d7 100644 --- a/build-files.txt +++ b/build-files.txt @@ -29,6 +29,7 @@ source/dub/generators/sublimetext.d source/dub/generators/targetdescription.d source/dub/generators/visuald.d +source/dub/internal/git.d source/dub/internal/libInputVisitor.d source/dub/internal/sdlang/ast.d source/dub/internal/sdlang/exception.d diff --git a/build.sh b/build.sh index 7b2357c..65d26ac 100755 --- a/build.sh +++ b/build.sh @@ -31,7 +31,8 @@ MACOSX_DEPLOYMENT_TARGET=10.8 echo Running $DMD... -$DMD -ofbin/dub -g -O -w -version=DubUseCurl -version=DubApplication -Isource $* @build-files.txt +DFLAGS="${DFLAGS:--g -O -w}" +$DMD -ofbin/dub $DFLAGS -version=DubUseCurl -version=DubApplication -Isource $* @build-files.txt bin/dub --version echo DUB has been built as bin/dub. echo diff --git a/dub.selections.json b/dub.selections.json index 5ef0425..3f215bf 100644 --- a/dub.selections.json +++ b/dub.selections.json @@ -3,8 +3,8 @@ "versions": { "botan": "1.12.10", "botan-math": "1.0.3", - "diet-ng": "1.5.0", - "eventcore": "0.8.41", + "diet-ng": "1.6.0", + "eventcore": "0.8.48", "libasync": "0.8.4", "libev": "5.0.0+4.04", "libevent": "2.0.2+2.0.16", @@ -12,8 +12,8 @@ "mir-linux-kernel": "1.0.1", "openssl": "1.1.6+1.0.1g", "stdx-allocator": "2.77.5", - "taggedalgebraic": "0.10.13", - "vibe-core": "1.6.0", - "vibe-d": "0.8.4" + "taggedalgebraic": "0.11.8", + "vibe-core": "1.8.1", + "vibe-d": "0.8.6" } } diff --git a/source/app.d b/source/app.d index 370cd8f..50daaf1 100644 --- a/source/app.d +++ b/source/app.d @@ -9,6 +9,18 @@ import dub.commandline; +/** + * Workaround https://github.com/dlang/dub/issues/1812 + * + * On Linux, a segmentation fault happens when dub is compiled with a recent + * compiler. While not confirmed, the logs seem to point to parallel marking + * done by the GC. Hence this disables it. + * + * https://dlang.org/changelog/2.087.0.html#gc_parallel + */ +static if (__VERSION__ >= 2087) + extern(C) __gshared string[] rt_options = [ "gcopt=parallel:0" ]; + int main(string[] args) { return runDubCommandLine(args); diff --git a/source/dub/commandline.d b/source/dub/commandline.d index fc06a32..93981f6 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -814,6 +814,7 @@ gensettings.rdmd = m_rdmd; gensettings.tempBuild = m_tempBuild; gensettings.parallelBuild = m_parallel; + gensettings.single = m_single; logDiagnostic("Generating using %s", m_generator); dub.generateProject(m_generator, gensettings); @@ -1281,8 +1282,25 @@ enforce(free_args.length == 0, "Cleaning a specific package isn't possible right now."); if (m_allPackages) { - foreach (p; dub.packageManager.getPackageIterator()) - dub.cleanPackage(p.path); + bool any_error = false; + + foreach (p; dub.packageManager.getPackageIterator()) { + try dub.cleanPackage(p.path); + catch (Exception e) { + logWarn("Failed to clean package %s at %s: %s", p.name, p.path, e.msg); + any_error = true; + } + + foreach (sp; p.subPackages.filter!(sp => !sp.path.empty)) { + try dub.cleanPackage(p.path ~ sp.path); + catch (Exception e) { + logWarn("Failed to clean sub package of %s at %s: %s", p.name, p.path ~ sp.path, e.msg); + any_error = true; + } + } + } + + if (any_error) return 1; } else { dub.cleanPackage(dub.rootPath); } @@ -2316,12 +2334,11 @@ into `name` and `version_`. */ private PackageAndVersion splitPackageName(string packageName) { - - // split = - auto parts = packageName.findSplit("="); + // split @ + auto parts = packageName.findSplit("@"); if (parts[1].empty) { - // support splitting @ too - parts = packageName.findSplit("@"); + // split = + parts = packageName.findSplit("="); } PackageAndVersion p; @@ -2331,10 +2348,15 @@ return p; } -// https://github.com/dlang/dub/issues/1681 unittest { - auto pv = splitPackageName(""); - assert(pv.name == ""); - assert(pv.version_ is null); + // https://github.com/dlang/dub/issues/1681 + assert(splitPackageName("") == PackageAndVersion("", null)); + + assert(splitPackageName("foo=1.0.1") == PackageAndVersion("foo", "1.0.1")); + assert(splitPackageName("foo@1.0.1") == PackageAndVersion("foo", "1.0.1")); + assert(splitPackageName("foo@==1.0.1") == PackageAndVersion("foo", "==1.0.1")); + assert(splitPackageName("foo@>=1.0.1") == PackageAndVersion("foo", ">=1.0.1")); + assert(splitPackageName("foo@~>1.0.1") == PackageAndVersion("foo", "~>1.0.1")); + assert(splitPackageName("foo@<1.0.1") == PackageAndVersion("foo", "<1.0.1")); } diff --git a/source/dub/compilers/buildsettings.d b/source/dub/compilers/buildsettings.d index cfc39c4..27fc596 100644 --- a/source/dub/compilers/buildsettings.d +++ b/source/dub/compilers/buildsettings.d @@ -164,9 +164,9 @@ static void addSI(ref string[] arr, in string[] vals) { bool[string] existing; - foreach (v; arr) existing[NativePath(v).head.toString()] = true; + foreach (v; arr) existing[NativePath(v).head.name] = true; foreach (v; vals) { - auto s = NativePath(v).head.toString(); + auto s = NativePath(v).head.name; if (s !in existing) { existing[s] = true; arr ~= v; diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index f81d0cf..bca6114 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -142,11 +142,6 @@ auto build_platform = readPlatformJsonProbe(result.output); build_platform.compilerBinary = compiler_binary; - if (build_platform.compiler != this.name) { - logWarn(`The determined compiler type "%s" doesn't match the expected type "%s". `~ - `This will probably result in build errors.`, build_platform.compiler, this.name); - } - auto ver = determineVersion(compiler_binary, result.output) .strip; if (ver.empty) { diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index 051e122..fd5b73f 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -217,7 +217,7 @@ case TargetType.executable: if (platform.platform.canFind("windows")) return settings.targetName ~ ".exe"; - else return settings.targetName; + else return settings.targetName.idup; case TargetType.library: case TargetType.staticLibrary: if (platform.platform.canFind("windows")) diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index eb753d8..71f4257 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -163,7 +163,7 @@ case TargetType.executable: if (platform.platform.canFind("windows")) return settings.targetName ~ ".exe"; - else return settings.targetName; + else return settings.targetName.idup; case TargetType.library: case TargetType.staticLibrary: return "lib" ~ settings.targetName ~ ".a"; diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 7e77d0e..da0cdff 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -184,7 +184,7 @@ return settings.targetName ~ ".exe"; else if (p.canFind("wasm")) return settings.targetName ~ ".wasm"; - else return settings.targetName; + else return settings.targetName.idup; case TargetType.library: case TargetType.staticLibrary: if (p.canFind("windows") && !p.canFind("mingw")) diff --git a/source/dub/compilers/utils.d b/source/dub/compilers/utils.d index da847bc..12c55f3 100644 --- a/source/dub/compilers/utils.d +++ b/source/dub/compilers/utils.d @@ -298,6 +298,7 @@ import dub.internal.vibecompat.core.file; import dub.internal.vibecompat.data.json; import dub.internal.utils; + import std.string : format; // try to not use phobos in the probe to avoid long import times enum probe = q{ @@ -314,23 +315,25 @@ return res; } - pragma(msg, } ~ `"` ~ probeBeginMark ~ `"` ~q{ ); - pragma(msg, `{`); - pragma(msg,` "compiler": "`~ determineCompiler() ~ `",`); - pragma(msg, ` "frontendVersion": ` ~ toString!__VERSION__ ~ `,`); - pragma(msg, ` "compilerVendor": "` ~ __VENDOR__ ~ `",`); - pragma(msg, ` "platform": [`); - pragma(msg, ` ` ~ determinePlatform().stringArray); - pragma(msg, ` ],`); - pragma(msg, ` "architecture": [`); - pragma(msg, ` ` ~ determineArchitecture().stringArray); - pragma(msg, ` ],`); - pragma(msg, `}`); - pragma(msg, } ~ `"` ~ probeEndMark ~ `"` ~ q{ ); + pragma(msg, `%1$s` + ~ '\n' ~ `{` + ~ '\n' ~ ` "compiler": "`~ determineCompiler() ~ `",` + ~ '\n' ~ ` "frontendVersion": ` ~ toString!__VERSION__ ~ `,` + ~ '\n' ~ ` "compilerVendor": "` ~ __VENDOR__ ~ `",` + ~ '\n' ~ ` "platform": [` + ~ '\n' ~ ` ` ~ determinePlatform().stringArray + ~ '\n' ~ ` ],` + ~ '\n' ~ ` "architecture": [` + ~ '\n' ~ ` ` ~ determineArchitecture().stringArray + ~ '\n' ~ ` ],` + ~ '\n' ~ `}` + ~ '\n' ~ `%2$s`); - string[] determinePlatform() } ~ '{' ~ platformCheck ~ '}' ~ q{ - string[] determineArchitecture() } ~ '{' ~ archCheck ~ '}' ~ q{ - string determineCompiler() } ~ '{' ~ compilerCheck ~ '}'; + string[] determinePlatform() { %3$s } + string[] determineArchitecture() { %4$s } + string determineCompiler() { %5$s } + + }.format(probeBeginMark, probeEndMark, platformCheck, archCheck, compilerCheck); auto path = getTempFile("dub_platform_probe", ".d"); auto fil = openFile(path, FileMode.createTrunc); diff --git a/source/dub/dependency.d b/source/dub/dependency.d index 1d2c51f..f16edcc 100644 --- a/source/dub/dependency.d +++ b/source/dub/dependency.d @@ -77,7 +77,7 @@ /** Constructs a new dependency specification that matches a specific version. */ - this(in Version ver) + this(const Version ver) { m_inclusiveA = m_inclusiveB = true; m_versA = ver; @@ -143,7 +143,6 @@ static import std.string; enforce(ves.length > 0); - string orig = ves; if (ves == ANY_IDENT) { // Any version is good. @@ -373,7 +372,7 @@ These methods are suitable for equality comparisons, as well as for using `Dependency` as a key in hash or tree maps. */ - bool opEquals(in Dependency o) + bool opEquals(const Dependency o) const { // TODO(mdondorff): Check if not comparing the path is correct for all clients. return o.m_inclusiveA == m_inclusiveA && o.m_inclusiveB == m_inclusiveB @@ -382,7 +381,7 @@ } /// ditto - int opCmp(in Dependency o) + int opCmp(const Dependency o) const { if (m_inclusiveA != o.m_inclusiveA) return m_inclusiveA < o.m_inclusiveA ? -1 : 1; if (m_inclusiveB != o.m_inclusiveB) return m_inclusiveB < o.m_inclusiveB ? -1 : 1; @@ -762,7 +761,7 @@ return compareVersions(m_version, other.m_version); } /// ditto - int opCmp(in Version other) const { return opCmp(other); } + int opCmp(const Version other) const { return opCmp(other); } /// Returns the string representation of the version/branch. string toString() const { return m_version; } diff --git a/source/dub/dub.d b/source/dub/dub.d index 3f0d9ca..97d87fc 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -33,7 +33,7 @@ import std.encoding : sanitize; // Set output path and options for coverage reports -version (DigitalMars) version (D_Coverage) static if (__VERSION__ >= 2068) +version (DigitalMars) version (D_Coverage) { shared static this() { @@ -59,7 +59,7 @@ deprecated("use defaultRegistryURLs") enum defaultRegistryURL = defaultRegistryURLs[0]; /// The URL to the official package registry and it's default fallback registries. -enum defaultRegistryURLs = [ +static immutable string[] defaultRegistryURLs = [ "https://code.dlang.org/", "https://code-mirror.dlang.io/", "https://dub-registry.herokuapp.com/", @@ -168,7 +168,7 @@ else m_packageSuppliers = getPackageSuppliers(additional_package_suppliers, skip_registry); - m_packageManager = new PackageManager(m_dirs.localRepository, m_dirs.systemSettings); + m_packageManager = new PackageManager(m_rootPath, m_dirs.localRepository, m_dirs.systemSettings); auto ccps = m_config.customCachePaths; if (ccps.length) @@ -260,7 +260,7 @@ { init(NativePath()); m_overrideSearchPath = override_path; - m_packageManager = new PackageManager(NativePath(), NativePath(), false); + m_packageManager = new PackageManager(NativePath(), NativePath(), NativePath(), false); updatePackageSearchPath(); } @@ -677,14 +677,14 @@ import std.path; tcinfo.sourceFiles[""] ~= custom_main_file.relativeTo(m_project.rootPackage.path).toNativeString(); tcinfo.importPaths[""] ~= custom_main_file.parentPath.toNativeString(); - custommodname = custom_main_file.head.toString().baseName(".d"); + custommodname = custom_main_file.head.name.baseName(".d"); } // prepare the list of tested modules string[] import_modules; foreach (file; lbuildsettings.sourceFiles) { if (file.endsWith(".d")) { - auto fname = NativePath(file).head.toString(); + auto fname = NativePath(file).head.name; if (NativePath(file).relativeTo(m_project.rootPackage.path) == NativePath(mainfil)) { logWarn("Excluding main source file %s from test.", mainfil); tcinfo.excludedSourceFiles[""] ~= mainfil; @@ -862,7 +862,7 @@ NativePath placement; final switch (location) { - case PlacementLocation.local: placement = m_rootPath; break; + case PlacementLocation.local: placement = m_rootPath ~ ".dub/packages/"; break; case PlacementLocation.user: placement = m_dirs.localRepository ~ "packages/"; break; case PlacementLocation.system: placement = m_dirs.systemSettings ~ "packages/"; break; } @@ -1201,7 +1201,6 @@ enforce(!vers.empty, "Failed to find any valid versions for a package name of '"~package_name~"'."); auto final_versions = vers.filter!(v => !v.isBranch && !v.isPreRelease).array; if (prefer_stable && final_versions.length) return final_versions[$-1]; - else if (vers[$-1].isBranch) return vers[$-1]; else return vers[$-1]; } @@ -1301,7 +1300,7 @@ } auto srcfile = m_project.rootPackage.recipePath; - auto srcext = srcfile.head.toString().extension; + auto srcext = srcfile.head.name.extension; if (srcext == "."~destination_file_ext) { logInfo("Package format is already %s.", destination_file_ext); return; diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index 971ce8f..5f54d4a 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -48,8 +48,6 @@ { scope (exit) cleanupTemporaries(); - auto dcl = settings.compiler; - void checkPkgRequirements(const(Package) pkg) { const tr = pkg.recipe.toolchainRequirements; @@ -86,7 +84,6 @@ NativePath[] additional_dep_files; auto bs = ti.buildSettings.dup; foreach (ldep; ti.linkDependencies) { - auto dbs = targets[ldep].buildSettings; if (bs.targetType != TargetType.staticLibrary && !(bs.options & BuildOption.syntaxOnly)) { bs.addSourceFiles(target_paths[ldep].toNativeString()); } else { @@ -194,9 +191,6 @@ return false; } - // determine basic build properties - auto generate_binary = !(buildsettings.options & BuildOption.syntaxOnly); - logInfo("%s %s: building configuration \"%s\"...", pack.name, pack.version_, config); if( buildsettings.preBuildCommands.length ){ @@ -284,9 +278,7 @@ private void performDirectBuild(GeneratorSettings settings, ref BuildSettings buildsettings, in Package pack, string config, out NativePath target_path) { auto cwd = NativePath(getcwd()); - auto generate_binary = !(buildsettings.options & BuildOption.syntaxOnly); - auto is_static_library = buildsettings.targetType == TargetType.staticLibrary || buildsettings.targetType == TargetType.library; // make file paths relative to shrink the command line foreach (ref f; buildsettings.sourceFiles) { @@ -396,7 +388,8 @@ foreach (p; packages) allfiles ~= (p.recipePath != NativePath.init ? p : p.basePackage).recipePath.toNativeString(); foreach (f; additional_dep_files) allfiles ~= f.toNativeString(); - if (main_pack is m_project.rootPackage && m_project.rootPackage.getAllDependencies().length > 0) + bool checkSelectedVersions = !settings.single; + if (checkSelectedVersions && main_pack is m_project.rootPackage && m_project.rootPackage.getAllDependencies().length > 0) allfiles ~= (main_pack.path ~ SelectedVersions.defaultFile).toNativeString(); foreach (file; allfiles.data) { @@ -449,7 +442,6 @@ auto generate_binary = !(buildsettings.options & BuildOption.syntaxOnly); auto is_static_library = buildsettings.targetType == TargetType.staticLibrary || buildsettings.targetType == TargetType.library; - NativePath target_file; scope (failure) { logDiagnostic("FAIL %s %s %s" , buildsettings.targetPath, buildsettings.targetName, buildsettings.targetType); auto tpath = getTargetPath(buildsettings, settings); @@ -631,7 +623,7 @@ auto desc = parseJsonString(`{"name": "test", "targetType": "library", "sourceFiles": ["foo.d", "`~libfile~`"]}`); auto pack = new Package(desc, NativePath("/tmp/fooproject")); - auto pman = new PackageManager(NativePath("/tmp/foo/"), NativePath("/tmp/foo/"), false); + auto pman = new PackageManager(pack.path, NativePath("/tmp/foo/"), NativePath("/tmp/foo/"), false); auto prj = new Project(pman, pack); final static class TestCompiler : GDCCompiler { @@ -643,8 +635,6 @@ } } - auto comp = new TestCompiler; - GeneratorSettings settings; settings.platform = BuildPlatform(determinePlatform(), ["x86"], "gdc", "test", 2075); settings.compiler = new TestCompiler; diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index 1d8990f..a971664 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -174,6 +174,8 @@ import std.algorithm : remove, sort; import std.range : repeat; + auto roottarget = &targets[rootPackage.name]; + // 0. do shallow configuration (not including dependencies) of all packages TargetType determineTargetType(const ref TargetInfo ti) { @@ -234,7 +236,7 @@ // add main source files to root executable { - auto bs = &targets[rootPackage.name].buildSettings; + auto bs = &roottarget.buildSettings; if (bs.targetType == TargetType.executable) bs.addSourceFiles(mainSourceFiles); } @@ -302,11 +304,8 @@ "Package with target type \"none\" must have dependencies to build."); } - collectDependencies(rootPackage, targets[rootPackage.name], targets); - static if (__VERSION__ > 2070) - visited.clear(); - else - destroy(visited); + collectDependencies(rootPackage, *roottarget, targets); + visited.clear(); // 1. downwards inherits versions, debugVersions, and inheritable build settings static void configureDependencies(in ref TargetInfo ti, TargetInfo[string] targets, size_t level = 0) @@ -322,7 +321,7 @@ } } - configureDependencies(targets[rootPackage.name], targets); + configureDependencies(*roottarget, targets); // 2. add Have_dependency_xyz for all direct dependencies of a target // (includes incorporated non-target dependencies and their dependencies) @@ -357,11 +356,8 @@ } } - configureDependents(targets[rootPackage.name], targets); - static if (__VERSION__ > 2070) - visited.clear(); - else - destroy(visited); + configureDependents(*roottarget, targets); + visited.clear(); // 4. Filter applicable version and debug version identifiers if (genSettings.filterVersions) @@ -383,36 +379,55 @@ } // 5. override string import files in dependencies - static void overrideStringImports(ref TargetInfo ti, TargetInfo[string] targets, string[] overrides) + static void overrideStringImports(ref TargetInfo target, + ref TargetInfo parent, TargetInfo[string] targets, string[] overrides) { + // Since string import paths are inherited from dependencies in the + // inheritance step above (step 3), it is guaranteed that all + // following dependencies will not have string import paths either, + // so we can skip the recursion here + if (!target.buildSettings.stringImportPaths.length) + return; + // do not use visited here as string imports can be overridden by *any* parent // // special support for overriding string imports in parent packages // this is a candidate for deprecation, once an alternative approach // has been found - if (ti.buildSettings.stringImportPaths.length) { - // override string import files (used for up to date checking) - foreach (ref f; ti.buildSettings.stringImportFiles) + bool any_override = false; + + // override string import files (used for up to date checking) + foreach (ref f; target.buildSettings.stringImportFiles) + { + foreach (o; overrides) { - foreach (o; overrides) - { - NativePath op; - if (f != o && NativePath(f).head == (op = NativePath(o)).head) { - logDebug("string import %s overridden by %s", f, o); - f = o; - ti.buildSettings.prependStringImportPaths(op.parentPath.toNativeString); - } + NativePath op; + if (f != o && NativePath(f).head == (op = NativePath(o)).head) { + logDebug("string import %s overridden by %s", f, o); + f = o; + any_override = true; } } } - // add to overrides for recursion - overrides ~= ti.buildSettings.stringImportFiles; - // override dependencies - foreach (depname; ti.dependencies) - overrideStringImports(targets[depname], targets, overrides); + + // override string import paths by prepending to the list, in + // case there is any overlapping file + if (any_override) + target.buildSettings.prependStringImportPaths(parent.buildSettings.stringImportPaths); + + // add all files to overrides for recursion + overrides ~= target.buildSettings.stringImportFiles; + + // recursively override all dependencies with the accumulated files/paths + foreach (depname; target.dependencies) + overrideStringImports(targets[depname], target, targets, overrides); } - overrideStringImports(targets[rootPackage.name], targets, null); + // push string import paths/files down to all direct and indirect + // dependencies, overriding their own + foreach (depname; roottarget.dependencies) + overrideStringImports(targets[depname], *roottarget, targets, + roottarget.buildSettings.stringImportFiles); // remove targets without output foreach (name; targets.keys) @@ -570,6 +585,10 @@ // only used for generator "build" bool run, force, direct, rdmd, tempBuild, parallelBuild; + + /// single file dub package + bool single; + string[] runArgs; void delegate(int status, string output) compileCallback; void delegate(int status, string output) linkCallback; @@ -794,7 +813,7 @@ auto depNames = proj.dependencies.map!((a) => a.name).array(); storeRecursiveInvokations(env, proj.rootPackage.name ~ depNames); - runCommands(commands, env); + runCommands(commands, env, pack.path().toString()); } private bool isRecursiveInvocation(string pack) diff --git a/source/dub/generators/sublimetext.d b/source/dub/generators/sublimetext.d index 9ac53c9..1bf2187 100644 --- a/source/dub/generators/sublimetext.d +++ b/source/dub/generators/sublimetext.d @@ -67,7 +67,7 @@ private Json buildSystems(BuildPlatform buildPlatform, string workingDiretory = getcwd()) { - enum BUILD_TYPES = [ + static immutable BUILD_TYPES = [ //"plain", "debug", "release", diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d index aa8bc59..9f9691a 100644 --- a/source/dub/generators/visuald.d +++ b/source/dub/generators/visuald.d @@ -104,7 +104,6 @@ const string[] sub = ["ActiveCfg", "Build.0"]; const string[] conf = [settings.buildType~"|"~settings.platform.architecture[0].vsArchitecture]; - auto projectUuid = guid(mainpack); foreach (t; targets.byKey) foreach (c; conf) foreach (s; sub) @@ -155,7 +154,6 @@ { import dub.compilers.utils : isLinkerFile; - int i = 0; auto ret = appender!(char[])(); auto project_file_dir = m_project.rootPackage.path ~ projFileName(packname).parentPath; @@ -219,7 +217,7 @@ foreach(unused; 0..decrease) ret.put("\n "); foreach(idx; 0..increase) - ret.formattedWrite("\n ", cur[same + idx].toString()); + ret.formattedWrite("\n ", cur[same + idx].name); lastFolder = cur; } ret.formattedWrite("\n ", source.build ? "" : "tool=\"None\" ", source.filePath.toNativeString()); diff --git a/source/dub/init.d b/source/dub/init.d index 98c98c4..d29b679 100644 --- a/source/dub/init.d +++ b/source/dub/init.d @@ -53,7 +53,7 @@ string username = getUserName(); PackageRecipe p; - p.name = root_path.head.toString().toLower(); + p.name = root_path.head.name.toLower(); p.authors ~= username; p.license = "proprietary"; foreach (pack, v; deps) { @@ -145,7 +145,6 @@ { import dub.compilers.buildsettings : TargetType; - auto name = root_path.head.toString().toLower(); p.description = format("Deimos Bindings for "~p.name~"."); p.buildSettings.importPaths[""] ~= "."; p.buildSettings.targetType = TargetType.sourceLibrary; diff --git a/source/dub/internal/git.d b/source/dub/internal/git.d new file mode 100644 index 0000000..50be963 --- /dev/null +++ b/source/dub/internal/git.d @@ -0,0 +1,103 @@ +module dub.internal.git; + +import dub.internal.vibecompat.core.file; +import dub.internal.vibecompat.core.log; +import std.file; +import std.string; + +version (Windows) +{ + import dub.internal.vibecompat.data.json; + + string determineVersionWithGit(NativePath path) + { + // On Windows, which is slow at running external processes, + // cache the version numbers that are determined using + // git to speed up the initialization phase. + import dub.internal.utils : jsonFromFile; + + // quickly determine head commit without invoking git + string head_commit; + auto hpath = (path ~ ".git/HEAD").toNativeString(); + if (exists(hpath)) { + auto head_ref = readText(hpath).strip(); + if (head_ref.startsWith("ref: ")) { + auto rpath = (path ~ (".git/"~head_ref[5 .. $])).toNativeString(); + if (exists(rpath)) + head_commit = readText(rpath).strip(); + } + } + + // return the last determined version for that commit + // not that this is not always correct, most notably when + // a tag gets added/removed/changed and changes the outcome + // of the full version detection computation + auto vcachepath = path ~ ".dub/version.json"; + if (existsFile(vcachepath)) { + auto ver = jsonFromFile(vcachepath); + if (head_commit == ver["commit"].opt!string) + return ver["version"].get!string; + } + + // if no cache file or the HEAD commit changed, perform full detection + auto ret = determineVersionWithGitTool(path); + + // update version cache file + if (head_commit.length) { + import dub.internal.utils : atomicWriteJsonFile; + + if (!existsFile(path ~".dub")) createDirectory(path ~ ".dub"); + atomicWriteJsonFile(vcachepath, Json(["commit": Json(head_commit), "version": Json(ret)])); + } + + return ret; + } +} +else +{ + string determineVersionWithGit(NativePath path) + { + return determineVersionWithGitTool(path); + } +} + +// determines the version of a package that is stored in a Git working copy +// by invoking the "git" executable +private string determineVersionWithGitTool(NativePath path) +{ + import dub.semver; + import std.algorithm : canFind; + import std.conv : to; + import std.process; + + auto git_dir = path ~ ".git"; + if (!existsFile(git_dir) || !isDir(git_dir.toNativeString)) return null; + auto git_dir_param = "--git-dir=" ~ git_dir.toNativeString(); + + static string exec(scope string[] params...) { + auto ret = executeShell(escapeShellCommand(params)); + if (ret.status == 0) return ret.output.strip; + logDebug("'%s' failed with exit code %s: %s", params.join(" "), ret.status, ret.output.strip); + return null; + } + + auto tag = exec("git", git_dir_param, "describe", "--long", "--tags"); + if (tag !is null) { + auto parts = tag.split("-"); + auto commit = parts[$-1]; + auto num = parts[$-2].to!int; + tag = parts[0 .. $-2].join("-"); + if (tag.startsWith("v") && isValidVersion(tag[1 .. $])) { + if (num == 0) return tag[1 .. $]; + else if (tag.canFind("+")) return format("%s.commit.%s.%s", tag[1 .. $], num, commit); + else return format("%s+commit.%s.%s", tag[1 .. $], num, commit); + } + } + + auto branch = exec("git", git_dir_param, "rev-parse", "--abbrev-ref", "HEAD"); + if (branch !is null) { + if (branch != "HEAD") return "~" ~ branch; + } + + return null; +} diff --git a/source/dub/internal/utils.d b/source/dub/internal/utils.d index 5879e79..9814e2f 100644 --- a/source/dub/internal/utils.d +++ b/source/dub/internal/utils.d @@ -26,7 +26,7 @@ version(DubUseCurl) { import std.net.curl; - static if (__VERSION__ > 2075) public import std.net.curl : HTTPStatusException; + public import std.net.curl : HTTPStatusException; } @@ -105,12 +105,6 @@ } } -bool isEmptyDir(NativePath p) { - foreach(DirEntry e; dirEntries(p.toNativeString(), SpanMode.shallow)) - return false; - return true; -} - bool isWritableDir(NativePath p, bool create_if_missing = false) { import std.random; @@ -154,7 +148,7 @@ foreach (ArchiveMember am; archive.directory) { auto path = NativePath(am.name).bySegment.array; foreach (fil; packageInfoFiles) { - if ((path.length == 1 && path[0] == fil.filename) || (path.length == 2 && path[$-1].toString == fil.filename)) { + if ((path.length == 1 && path[0] == fil.filename) || (path.length == 2 && path[$-1].name == fil.filename)) { fileName = fil.filename; return stripUTF8Bom(cast(string) archive.expand(archive.directory[am.name])); } @@ -163,17 +157,6 @@ throw new Exception("No package descriptor found"); } -Json jsonFromZip(NativePath zip, string filename) { - import std.zip : ZipArchive; - auto f = openFile(zip, FileMode.read); - ubyte[] b = new ubyte[cast(size_t)f.size]; - f.rawRead(b); - f.close(); - auto archive = new ZipArchive(b); - auto text = stripUTF8Bom(cast(string)archive.expand(archive.directory[filename])); - return parseJsonString(text, zip.toNativeString~"/"~filename); -} - void writeJsonFile(NativePath path, Json json) { auto f = openFile(path, FileMode.createTrunc); @@ -197,23 +180,18 @@ moveFile(tmppath, path); } -bool isPathFromZip(string p) { - enforce(p.length > 0); - return p[$-1] == '/'; -} - bool existsDirectory(NativePath path) { if( !existsFile(path) ) return false; auto fi = getFileInfo(path); return fi.isDirectory; } -void runCommand(string command, string[string] env = null) +void runCommand(string command, string[string] env = null, string workDir = null) { - runCommands((&command)[0 .. 1], env); + runCommands((&command)[0 .. 1], env, workDir); } -void runCommands(in string[] commands, string[string] env = null) +void runCommands(in string[] commands, string[string] env = null, string workDir = null) { import std.stdio : stdin, stdout, stderr, File; @@ -235,44 +213,15 @@ foreach(cmd; commands){ logDiagnostic("Running %s", cmd); Pid pid; - pid = spawnShell(cmd, stdin, childStdout, childStderr, env, config); + pid = spawnShell(cmd, stdin, childStdout, childStderr, env, config, workDir); auto exitcode = pid.wait(); enforce(exitcode == 0, "Command failed with exit code " ~ to!string(exitcode) ~ ": " ~ cmd); } } -version(DubUseCurl) { - /++ - Exception thrown on HTTP request failures, e.g. 404 Not Found. - +/ - static if (__VERSION__ <= 2075) class HTTPStatusException : CurlException - { - /++ - Params: - status = The HTTP status code. - msg = The message for the exception. - file = The file where the exception occurred. - line = The line number where the exception occurred. - next = The previous exception in the chain of exceptions, if any. - +/ - @safe pure nothrow - this( - int status, - string msg, - string file = __FILE__, - size_t line = __LINE__, - Throwable next = null) - { - this.status = status; - super(msg, file, line, next); - } - - int status; /// The HTTP status code - } -} else version (Have_vibe_d_http) { +version (Have_vibe_d_http) public import vibe.http.common : HTTPStatusException; -} /** Downloads a file from the specified URL. @@ -293,27 +242,13 @@ auto conn = HTTP(); setupHTTPClient(conn, timeout); logDebug("Storing %s...", url); - static if (__VERSION__ <= 2075) - { - try - std.net.curl.download(url, filename, conn); - catch (CurlException e) - { - if (e.msg.canFind("404")) - throw new HTTPStatusException(404, e.msg); - throw e; - } - } - else - { - std.net.curl.download(url, filename, conn); - // workaround https://issues.dlang.org/show_bug.cgi?id=18318 - auto sl = conn.statusLine; - logDebug("Download %s %s", url, sl); - if (sl.code / 100 != 2) - throw new HTTPStatusException(sl.code, - "Downloading %s failed with %d (%s).".format(url, sl.code, sl.reason)); - } + std.net.curl.download(url, filename, conn); + // workaround https://issues.dlang.org/show_bug.cgi?id=18318 + auto sl = conn.statusLine; + logDebug("Download %s %s", url, sl); + if (sl.code / 100 != 2) + throw new HTTPStatusException(sl.code, + "Downloading %s failed with %d (%s).".format(url, sl.code, sl.reason)); } else version (Have_vibe_d_http) { import vibe.inet.urltransfer; vibe.inet.urltransfer.download(url, filename); @@ -331,19 +266,7 @@ auto conn = HTTP(); setupHTTPClient(conn, timeout); logDebug("Getting %s...", url); - static if (__VERSION__ <= 2075) - { - try - return cast(ubyte[])get(url, conn); - catch (CurlException e) - { - if (e.msg.canFind("404")) - throw new HTTPStatusException(404, e.msg); - throw e; - } - } - else - return cast(ubyte[])get(url, conn); + return cast(ubyte[])get(url, conn); } else version (Have_vibe_d_http) { import vibe.inet.urltransfer; import vibe.stream.operations; @@ -689,7 +612,7 @@ //create module name from path foreach (i; 0 .. mpath.length) { import std.path; - auto p = mpath[i].toString(); + auto p = mpath[i].name; if (p == "package.d") break; if (i > 0) ret ~= "."; if (i+1 < mpath.length) ret ~= p; diff --git a/source/dub/internal/vibecompat/core/file.d b/source/dub/internal/vibecompat/core/file.d index 26321d4..f48176b 100644 --- a/source/dub/internal/vibecompat/core/file.d +++ b/source/dub/internal/vibecompat/core/file.d @@ -28,8 +28,8 @@ @safe: std.stdio.File file; - void put(in ubyte[] bytes) @trusted { file.rawWrite(bytes); } - void put(in char[] str) { put(cast(const(ubyte)[])str); } + void put(scope const ubyte[] bytes) @trusted { file.rawWrite(bytes); } + void put(scope const char[] str) { put(cast(const(ubyte)[])str); } void put(char ch) @trusted { put((&ch)[0 .. 1]); } void put(dchar ch) { char[4] chars; put(chars[0 .. encode(chars, ch)]); } diff --git a/source/dub/internal/vibecompat/data/utils.d b/source/dub/internal/vibecompat/data/utils.d index a967455..ace6a76 100644 --- a/source/dub/internal/vibecompat/data/utils.d +++ b/source/dub/internal/vibecompat/data/utils.d @@ -215,8 +215,8 @@ ref int someTempl()() { return i; } } - enum plainFields = ["i"]; - enum fields = ["i", "p1", "p4", "p5"]; + immutable plainFields = ["i"]; + immutable fields = ["i", "p1", "p4", "p5"]; foreach (mem; __traits(allMembers, S)) { static if (isRWField!(S, mem)) static assert(fields.canFind(mem), mem~" detected as field."); diff --git a/source/dub/internal/vibecompat/inet/path.d b/source/dub/internal/vibecompat/inet/path.d index 4ad987e..c25878a 100644 --- a/source/dub/internal/vibecompat/inet/path.d +++ b/source/dub/internal/vibecompat/inet/path.d @@ -221,7 +221,6 @@ ret.normalize(); // needed to avoid "."~".." become "" instead of ".." assert(!rhs.absolute, "Trying to append absolute path."); - size_t idx = m_nodes.length; foreach(folder; rhs.m_nodes){ switch(folder.toString()){ default: ret.m_nodes = ret.m_nodes ~ folder; break; diff --git a/source/dub/package_.d b/source/dub/package_.d index 88e3765..c7c7750 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -744,85 +744,11 @@ private string determineVersionFromSCM(NativePath path) { - // On Windows, which is slow at running external processes, - // cache the version numbers that are determined using - // GIT to speed up the initialization phase. - version (Windows) { - import std.file : exists, readText; + if (existsFile(path ~ ".git")) + { + import dub.internal.git : determineVersionWithGit; - // quickly determine head commit without invoking GIT - string head_commit; - auto hpath = (path ~ ".git/HEAD").toNativeString(); - if (exists(hpath)) { - auto head_ref = readText(hpath).strip(); - if (head_ref.startsWith("ref: ")) { - auto rpath = (path ~ (".git/"~head_ref[5 .. $])).toNativeString(); - if (exists(rpath)) - head_commit = readText(rpath).strip(); - } - } - - // return the last determined version for that commit - // not that this is not always correct, most notably when - // a tag gets added/removed/changed and changes the outcome - // of the full version detection computation - auto vcachepath = path ~ ".dub/version.json"; - if (existsFile(vcachepath)) { - auto ver = jsonFromFile(vcachepath); - if (head_commit == ver["commit"].opt!string) - return ver["version"].get!string; - } + return determineVersionWithGit(path); } - - // if no cache file or the HEAD commit changed, perform full detection - auto ret = determineVersionWithGIT(path); - - version (Windows) { - // update version cache file - if (head_commit.length) { - if (!existsFile(path ~".dub")) createDirectory(path ~ ".dub"); - atomicWriteJsonFile(vcachepath, Json(["commit": Json(head_commit), "version": Json(ret)])); - } - } - - return ret; -} - -// determines the version of a package that is stored in a GIT working copy -// by invoking the "git" executable -private string determineVersionWithGIT(NativePath path) -{ - import std.process; - import dub.semver; - - auto git_dir = path ~ ".git"; - if (!existsFile(git_dir) || !isDir(git_dir.toNativeString)) return null; - auto git_dir_param = "--git-dir=" ~ git_dir.toNativeString(); - - static string exec(scope string[] params...) { - auto ret = executeShell(escapeShellCommand(params)); - if (ret.status == 0) return ret.output.strip; - logDebug("'%s' failed with exit code %s: %s", params.join(" "), ret.status, ret.output.strip); - return null; - } - - auto tag = exec("git", git_dir_param, "describe", "--long", "--tags"); - if (tag !is null) { - auto parts = tag.split("-"); - auto commit = parts[$-1]; - auto num = parts[$-2].to!int; - tag = parts[0 .. $-2].join("-"); - if (tag.startsWith("v") && isValidVersion(tag[1 .. $])) { - if (num == 0) return tag[1 .. $]; - else if (tag.canFind("+")) return format("%s.commit.%s.%s", tag[1 .. $], num, commit); - else return format("%s+commit.%s.%s", tag[1 .. $], num, commit); - } - } - - auto branch = exec("git", git_dir_param, "rev-parse", "--abbrev-ref", "HEAD"); - if (branch !is null) { - if (branch != "HEAD") return "~" ~ branch; - } - return null; } diff --git a/source/dub/packagemanager.d b/source/dub/packagemanager.d index 13134b5..ae03dbf 100644 --- a/source/dub/packagemanager.d +++ b/source/dub/packagemanager.d @@ -39,9 +39,20 @@ this(NativePath user_path, NativePath system_path, bool refresh_packages = true) { - m_repositories.length = LocalPackageType.max+1; - m_repositories[LocalPackageType.user] = Repository(user_path ~ "packages/"); - m_repositories[LocalPackageType.system] = Repository(system_path ~ "packages/"); + m_repositories = [ + Repository(user_path ~ "packages/"), + Repository(system_path ~ "packages/")]; + + if (refresh_packages) refresh(true); + } + + this(NativePath package_path, NativePath user_path, NativePath system_path, bool refresh_packages = true) + { + m_repositories = [ + Repository(package_path ~ ".dub/packages/"), + Repository(user_path ~ "packages/"), + Repository(system_path ~ "packages/")]; + if (refresh_packages) refresh(true); } @@ -362,7 +373,6 @@ auto package_name = package_info["name"].get!string; auto package_version = package_info["version"].get!string; - auto clean_package_version = package_version[package_version.startsWith("~") ? 1 : 0 .. $]; logDebug("Placing package '%s' version '%s' to location '%s' from file '%s'", package_name, package_version, destination.toNativeString(), zip_file_path.toNativeString()); @@ -388,7 +398,7 @@ outer: foreach(ArchiveMember am; archive.directory) { auto path = NativePath(am.name).bySegment.array; foreach (fil; packageInfoFiles) - if (path.length == 2 && path[$-1].toString == fil.filename) { + if (path.length == 2 && path[$-1].name == fil.filename) { zip_prefix = path[0 .. $-1]; break outer; } @@ -616,6 +626,7 @@ } scanLocalPackages(LocalPackageType.system); scanLocalPackages(LocalPackageType.user); + scanLocalPackages(LocalPackageType.package_); auto old_packages = m_packages; @@ -682,6 +693,7 @@ } } } + loadOverrides(LocalPackageType.package_); loadOverrides(LocalPackageType.user); loadOverrides(LocalPackageType.system); } @@ -697,12 +709,12 @@ string[] ignored_files = []; SHA1 sha1; foreach(file; dirEntries(pack.path.toNativeString(), SpanMode.depth)) { - if(file.isDir && ignored_directories.canFind(NativePath(file.name).head.toString())) + if(file.isDir && ignored_directories.canFind(NativePath(file.name).head.name)) continue; - else if(ignored_files.canFind(NativePath(file.name).head.toString())) + else if(ignored_files.canFind(NativePath(file.name).head.name)) continue; - sha1.put(cast(ubyte[])NativePath(file.name).head.toString()); + sha1.put(cast(ubyte[])NativePath(file.name).head.name); if(file.isDir) { logDebug("Hashed directory name %s", NativePath(file.name).head); } @@ -814,6 +826,7 @@ } enum LocalPackageType { + package_, user, system } diff --git a/source/dub/packagesuppliers/filesystem.d b/source/dub/packagesuppliers/filesystem.d index 61b125c..e271510 100644 --- a/source/dub/packagesuppliers/filesystem.d +++ b/source/dub/packagesuppliers/filesystem.d @@ -30,7 +30,7 @@ NativePath p = NativePath(d.name); logDebug("Entry: %s", p); enforce(to!string(p.head)[$-4..$] == ".zip"); - auto vers = p.head.toString()[package_id.length+1..$-4]; + auto vers = p.head.name[package_id.length+1..$-4]; logDebug("Version: %s", vers); ret ~= Version(vers); } diff --git a/source/dub/project.d b/source/dub/project.d index 8a807a9..61a8dd5 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -239,7 +239,7 @@ string ret; ret ~= `Please modify the "name" field in %s accordingly.`.format(m_rootPackage.recipePath.toNativeString()); if (!m_rootPackage.recipe.buildSettings.targetName.length) { - if (m_rootPackage.recipePath.head.toString().endsWith(".sdl")) { + if (m_rootPackage.recipePath.head.name.endsWith(".sdl")) { ret ~= ` You can then add 'targetName "%s"' to keep the current executable name.`.format(m_rootPackage.name); } else { ret ~= ` You can then add '"targetName": "%s"' to keep the current executable name.`.format(m_rootPackage.name); @@ -1430,7 +1430,7 @@ import std.path : dirSeparator; - static Path woSlash(Path p) { p.endsWithSlash = false; return p; } + static NativePath woSlash(NativePath p) { p.endsWithSlash = false; return p; } // basic vars assert(processVars("Hello $PACKAGE_DIR", proj, pack, gsettings, !isPath) == "Hello "~woSlash(pack.path).toNativeString); assert(processVars("Hello $ROOT_PACKAGE_DIR", proj, pack, gsettings, !isPath) == "Hello "~woSlash(proj.rootPackage.path).toNativeString.chomp(dirSeparator)); diff --git a/source/dub/recipe/json.d b/source/dub/recipe/json.d index 354a1e6..791d485 100644 --- a/source/dub/recipe/json.d +++ b/source/dub/recipe/json.d @@ -149,8 +149,6 @@ } enforce(!config.name.empty, "Configuration is missing a name."); - - BuildSettingsTemplate bs; config.buildSettings.parseJson(json, package_name); } diff --git a/source/dub/recipe/sdl.d b/source/dub/recipe/sdl.d index 09e8b8d..7f3ad45 100644 --- a/source/dub/recipe/sdl.d +++ b/source/dub/recipe/sdl.d @@ -182,8 +182,6 @@ Dependency dep = Dependency.any; auto attrs = t.attributes; - auto pv = "version" in attrs; - if ("path" in attrs) { if ("version" in attrs) logDiagnostic("Ignoring version specification (%s) for path based dependency %s", attrs["version"][0].value.get!string, attrs["path"][0].value.get!string); @@ -355,7 +353,7 @@ { import std.string : format; if (!condition) { - throw new Exception(format("%s(%s): Error: %s", tag.location.file, tag.location.line, message), file, line); + throw new Exception(format("%s(%s): Error: %s", tag.location.file, tag.location.line + 1, message), file, line); } } diff --git a/test/issue103-single-file-package.sh b/test/issue103-single-file-package.sh index cce4674..671e518 100755 --- a/test/issue103-single-file-package.sh +++ b/test/issue103-single-file-package.sh @@ -19,6 +19,11 @@ die $LINENO 'Shebang invocation produced binary in current directory' fi +if ! { ${DUB} run --single issue103-single-file-package-w-dep.d --temp-build 2>&1 || true; } | grep -cF "To force a rebuild"; then + echo "Invocation triggered unnecessary rebuild." + exit 1 +fi + if ${DUB} "issue103-single-file-package-error.d" 2> /dev/null; then echo "Invalid package comment syntax did not trigger an error." exit 1 diff --git a/test/issue1180-local-cache-broken.sh b/test/issue1180-local-cache-broken.sh new file mode 100755 index 0000000..e46970a --- /dev/null +++ b/test/issue1180-local-cache-broken.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +DIR=$(dirname "${BASH_SOURCE[0]}") + +. "$DIR"/common.sh + +PORT=$(($$ + 1024)) # PID + 1024 +"$DUB" remove maven-dubpackage --root="$DIR/issue1180-local-cache-broken" --non-interactive --version=* 2>/dev/null || true + +"$DUB" build --single "$DIR"/test_registry.d +"$DIR"/test_registry --folder="$DIR/issue1416-maven-repo-pkg-supplier" --port=$PORT & +PID=$! +sleep 1 +trap 'kill $PID 2>/dev/null || true' exit + +echo "Trying to download maven-dubpackage (1.0.5)" +"$DUB" upgrade --root="$DIR/issue1180-local-cache-broken" --cache=local --skip-registry=all --registry=mvn+http://localhost:$PORT/maven/release/dubpackages + +if ! "$DUB" remove maven-dubpackage --root="$DIR/issue1180-local-cache-broken" --non-interactive --version=1.0.5 2>/dev/null; then + die 'DUB did not install package from maven registry.' +fi diff --git a/test/issue1180-local-cache-broken.sh.min_frontend b/test/issue1180-local-cache-broken.sh.min_frontend new file mode 100644 index 0000000..bb0a2e1 --- /dev/null +++ b/test/issue1180-local-cache-broken.sh.min_frontend @@ -0,0 +1 @@ +2.076 diff --git a/test/issue1180-local-cache-broken/.gitignore b/test/issue1180-local-cache-broken/.gitignore new file mode 100644 index 0000000..0fd9d37 --- /dev/null +++ b/test/issue1180-local-cache-broken/.gitignore @@ -0,0 +1,4 @@ +test +*.o +*.exe +.dub \ No newline at end of file diff --git a/test/issue1180-local-cache-broken/.no_build b/test/issue1180-local-cache-broken/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1180-local-cache-broken/.no_build diff --git a/test/issue1180-local-cache-broken/dub.json b/test/issue1180-local-cache-broken/dub.json new file mode 100644 index 0000000..495617d --- /dev/null +++ b/test/issue1180-local-cache-broken/dub.json @@ -0,0 +1,7 @@ +{ + "name": "test", + "dependencies": { + "maven-dubpackage": "1.0.5" + } + +} \ No newline at end of file diff --git a/test/issue1180-local-cache-broken/source/app.d b/test/issue1180-local-cache-broken/source/app.d new file mode 100644 index 0000000..ef93217 --- /dev/null +++ b/test/issue1180-local-cache-broken/source/app.d @@ -0,0 +1 @@ +void main(){} \ No newline at end of file diff --git a/test/issue1775/.no_run b/test/issue1775/.no_run new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1775/.no_run diff --git a/test/issue1775/.no_test b/test/issue1775/.no_test new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1775/.no_test diff --git a/test/issue1775/dub.json b/test/issue1775/dub.json new file mode 100644 index 0000000..5640e4a --- /dev/null +++ b/test/issue1775/dub.json @@ -0,0 +1,5 @@ +{ + "name": "test", + "targetName": "test-application", + "preBuildCommands": [ "[ -f issue1775.marker ]" ] +} diff --git a/test/issue1775/issue1775.marker b/test/issue1775/issue1775.marker new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1775/issue1775.marker diff --git a/test/issue1775/source/app.d b/test/issue1775/source/app.d new file mode 100644 index 0000000..ab73b3a --- /dev/null +++ b/test/issue1775/source/app.d @@ -0,0 +1 @@ +void main() {} diff --git a/test/issue1788-incomplete-string-import-override/b/dub.sdl b/test/issue1788-incomplete-string-import-override/b/dub.sdl new file mode 100644 index 0000000..ad65ed5 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/b/dub.sdl @@ -0,0 +1 @@ +name "b" diff --git a/test/issue1788-incomplete-string-import-override/b/source/b/foo.d b/test/issue1788-incomplete-string-import-override/b/source/b/foo.d new file mode 100644 index 0000000..e63ab6d --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/b/source/b/foo.d @@ -0,0 +1,9 @@ +module b.foo; + +string bar() +{ + static immutable l = import("layout.diet"); + pragma(msg, l); + static assert(l == "fancylayout.diet"); + return import(l); +} diff --git a/test/issue1788-incomplete-string-import-override/b/views/layout.diet b/test/issue1788-incomplete-string-import-override/b/views/layout.diet new file mode 100644 index 0000000..9d82715 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/b/views/layout.diet @@ -0,0 +1 @@ +not fancy \ No newline at end of file diff --git a/test/issue1788-incomplete-string-import-override/c/dub.sdl b/test/issue1788-incomplete-string-import-override/c/dub.sdl new file mode 100644 index 0000000..1ed791a --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/c/dub.sdl @@ -0,0 +1 @@ +name "c" diff --git a/test/issue1788-incomplete-string-import-override/c/source/dummy.d b/test/issue1788-incomplete-string-import-override/c/source/dummy.d new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/c/source/dummy.d diff --git a/test/issue1788-incomplete-string-import-override/c/views/fancylayout.diet b/test/issue1788-incomplete-string-import-override/c/views/fancylayout.diet new file mode 100644 index 0000000..e0e439d --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/c/views/fancylayout.diet @@ -0,0 +1 @@ +fancy \ No newline at end of file diff --git a/test/issue1788-incomplete-string-import-override/dub.sdl b/test/issue1788-incomplete-string-import-override/dub.sdl new file mode 100644 index 0000000..4199971 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/dub.sdl @@ -0,0 +1,4 @@ +name "a" + +dependency "b" path="b" +dependency "c" path="c" diff --git a/test/issue1788-incomplete-string-import-override/source/app.d b/test/issue1788-incomplete-string-import-override/source/app.d new file mode 100644 index 0000000..e9672cc --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/source/app.d @@ -0,0 +1,7 @@ +import b.foo; + +void main() +{ + static assert(import("layout.diet") == "fancylayout.diet"); + assert(bar() == "fancy"); +} diff --git a/test/issue1788-incomplete-string-import-override/views/layout.diet b/test/issue1788-incomplete-string-import-override/views/layout.diet new file mode 100644 index 0000000..0762db7 --- /dev/null +++ b/test/issue1788-incomplete-string-import-override/views/layout.diet @@ -0,0 +1 @@ +fancylayout.diet \ No newline at end of file diff --git a/test/issue674-concurrent-dub.sh b/test/issue674-concurrent-dub.sh index d49bdd3..8f59ab7 100755 --- a/test/issue674-concurrent-dub.sh +++ b/test/issue674-concurrent-dub.sh @@ -16,4 +16,4 @@ pid2=$! wait $pid1 wait $pid2 -[ -d ${TMPDIR}/bloom* ] +[ -d ${TMPDIR}/.dub/packages/bloom* ] \ No newline at end of file diff --git a/travis-ci.sh b/travis-ci.sh index 6297a31..c2ff925 100755 --- a/travis-ci.sh +++ b/travis-ci.sh @@ -10,6 +10,10 @@ dub test --compiler=${DC} -c library-nonet fi +if [ "$FRONTEND" \> 2.087.z ]; then + DFLAGS='-preview=dip1000 -w -g -debug' DMD="$(command -v $DMD)" ./build.sh +fi + function clean() { # Hard reset of the DUB local folder is necessary as some tests # currently don't properly clean themselves @@ -55,5 +59,6 @@ # check that the man page generation still works (only once) if [ "$COVERAGE" = true ]; then source $(~/dlang/install.sh dmd --activate) + source $(~/dlang/install.sh dub --activate) dub --single -v scripts/man/gen_man.d fi