diff --git a/source/dub/dub.d b/source/dub/dub.d index 861e060..8fc1f88 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -999,7 +999,7 @@ return; } - writePackageRecipe(srcfile[0 .. $-1] ~ ("dub."~destination_file_ext), m_project.rootPackage.recipe); + writePackageRecipe(srcfile[0 .. $-1] ~ ("dub."~destination_file_ext), m_project.rootPackage.rawRecipe); removeFile(srcfile); } diff --git a/source/dub/package_.d b/source/dub/package_.d index 0afcf55..08db442 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -63,6 +63,7 @@ Path m_path; Path m_infoFile; PackageRecipe m_info; + PackageRecipe m_rawRecipe; Package m_parentPackage; } @@ -89,6 +90,9 @@ /// ditto this(PackageRecipe recipe, Path root = Path(), Package parent = null, string version_override = "") { + // save the original recipe + m_rawRecipe = recipe.clone; + if (!version_override.empty) recipe.version_ = version_override; @@ -192,9 +196,24 @@ @property void version_(Version value) { assert(m_parentPackage is null); m_info.version_ = value.toString(); } /** Accesses the recipe contents of this package. + + The recipe contains any default values and configurations added by DUB. + To access the raw user recipe, use the `rawRecipe` property. + + See_Also: `rawRecipe` */ @property ref inout(PackageRecipe) recipe() inout { return m_info; } + /** Accesses the original package recipe. + + The returned recipe matches exactly the contents of the original package + recipe. For the effective package recipe, augmented with DUB generated + default settings and configurations, use the `recipe` property. + + See_Also: `recipe` + */ + @property ref const(PackageRecipe) rawRecipe() const { return m_rawRecipe; } + /** Returns the path to the package recipe file. Note that this can be empty for packages that are not stored in the diff --git a/source/dub/recipe/packagerecipe.d b/source/dub/recipe/packagerecipe.d index 300c584..3ab9c66 100644 --- a/source/dub/recipe/packagerecipe.d +++ b/source/dub/recipe/packagerecipe.d @@ -94,6 +94,10 @@ return c; throw new Exception("Unknown configuration: "~name); } + + /** Clones the package recipe recursively. + */ + PackageRecipe clone() const { return .clone(this); } } struct SubPackage @@ -255,3 +259,32 @@ } } } + +private T clone(T)(ref const(T) val) +{ + import std.traits : isSomeString, isDynamicArray, isAssociativeArray, isBasicType, ValueType; + + static if (is(T == immutable)) return val; + else static if (isBasicType!T) return val; + else static if (isDynamicArray!T) { + alias V = typeof(T.init[0]); + static if (is(V == immutable)) return val; + else { + T ret = new V[val.length]; + foreach (i, ref f; val) + ret[i] = clone!V(f); + return ret; + } + } else static if (isAssociativeArray!T) { + alias V = ValueType!T; + T ret; + foreach (k, ref f; val) + ret[k] = clone!V(f); + return ret; + } else static if (is(T == struct)) { + T ret; + foreach (i, M; typeof(T.tupleof)) + ret.tupleof[i] = clone!M(val.tupleof[i]); + return ret; + } else static assert(false, "Unsupported type: "~T.stringof); +} diff --git a/test/issue820-extra-fields-after-convert.sh b/test/issue820-extra-fields-after-convert.sh new file mode 100755 index 0000000..ec9e935 --- /dev/null +++ b/test/issue820-extra-fields-after-convert.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +cd ${CURR_DIR}/1-exec-simple + +cp dub.json dub.json.bak +${DUB} convert -f sdl + +if grep -c -e "version\|sourcePaths\|importPaths\|configuration" dub.sdl > /dev/null; then + echo "Conversion added extra fields." + mv dub.json.bak dub.json + rm dub.sdl + exit 1 +fi + +mv dub.json.bak dub.json +rm dub.sdl