diff --git a/cmake-d/UseDub.cmake b/cmake-d/UseDub.cmake index aa085bf..ea8a053 100644 --- a/cmake-d/UseDub.cmake +++ b/cmake-d/UseDub.cmake @@ -27,7 +27,10 @@ if(NOT EXISTS ${DUB_DIRECTORY}/CMakeTmp/DubUrl OR 1) find_file(DUB_GET_PACKAGE_URL_D_SRC "DubUrl.d" PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH PATH_SUFFIXES "UseDub") - execute_process(COMMAND ${CMAKE_D_COMPILER} ${DUB_GET_PACKAGE_URL_D_SRC} + find_file(SEMVER_SRC "semver.d" + PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH + PATH_SUFFIXES "UseDub") + execute_process(COMMAND ${CMAKE_D_COMPILER} ${DUB_GET_PACKAGE_URL_D_SRC} ${SEMVER_SRC} WORKING_DIRECTORY ${DUB_DIRECTORY}/CMakeTmp) unset(DUB_GET_PACKAGE_URL_D_SRC CACHE) endif(NOT EXISTS ${DUB_DIRECTORY}/CMakeTmp/DubUrl OR 1) diff --git a/cmake-d/UseDub/DubUrl.d b/cmake-d/UseDub/DubUrl.d index b2f4d40..6c6e839 100644 --- a/cmake-d/UseDub/DubUrl.d +++ b/cmake-d/UseDub/DubUrl.d @@ -5,16 +5,7 @@ import std.getopt; import std.json; import std.stdio; import std.string; - - -struct Version -{ - uint major; - uint minor; - uint patch; - - this(string ) -} +import semver; /** * Finds the best match of $(D range) in $(D choices) versions list. @@ -88,11 +79,15 @@ int main(string[] args) if (packageVersion.empty) { - node = root["versions"][0]; + packageVersion = "*"; } - else + + auto versionRange = SemVerRange(packageVersion); + + if (!versionRange.valid) { - auto range = root["versions"].array.find!"a[\"version\"].str == b"(packageVersion); + // try exact string match + auto range = root["versions"].array.find!`a["version"].str == b`(packageVersion); if (!range.empty) { node = range[0]; @@ -103,6 +98,23 @@ int main(string[] args) return -1; } } + else + { + auto nodes = root["versions"].array.filter!(a => SemVer(a["version"].str).valid).array; + auto maxVersion = nodes.map!(a => SemVer(a["version"].str)).array.maxSatisfying(versionRange); + + if (maxVersion.valid) + { + auto range = nodes.find!((a, b) => SemVer(a["version"].str) == b)(maxVersion); + assert(!range.empty); + node = range[0]; + } + else + { + stderr.writefln("No version '%s' found.", versionRange); + return -1; + } + } if (registryFile.endsWith(".json")) { diff --git a/cmake-d/UseDub/semver.d b/cmake-d/UseDub/semver.d index e994f03..36c648f 100644 --- a/cmake-d/UseDub/semver.d +++ b/cmake-d/UseDub/semver.d @@ -217,8 +217,6 @@ struct SemVerRange ranges = [SimpleRange[].init]; - writeln(semVerRange); - while (!semVerRange.stripLeft.empty) { auto m = semVerRange.matchFirst(re); @@ -274,10 +272,12 @@ struct SemVerRange } break; case "<": + ranges[$-1] ~= SimpleRange(operator, semVer.appendPrerelease0); + break; case "<=": case ">=": case ">": - if (operator == "<" || wildcard < ReleaseType.PRERELEASE) + if (wildcard < ReleaseType.PRERELEASE) semVer.appendPrerelease0; ranges[$-1] ~= SimpleRange(operator, semVer); break; @@ -458,7 +458,7 @@ in } body { - auto found = semVers.sort.find!(a => satisfies(a, semVerRange)); + auto found = semVers.sort!"a > b".find!(a => satisfies(a, semVerRange)); return found.empty ? SemVer("invalid") : found[0]; } @@ -522,6 +522,7 @@ unittest assert(SemVer("1.0.12").satisfies(SemVerRange("~1.0.3"))); assert(SemVer("1.0.0").satisfies(SemVerRange(">=1"))); assert(SemVer("1.1.1").satisfies(SemVerRange("<1.2"))); + assert(SemVer("1.1.9").satisfies(SemVerRange("<=1.2"))); assert(SemVer("1.0.0-bet").satisfies(SemVerRange("1"))); assert(SemVer("0.5.5").satisfies(SemVerRange("~v0.5.4-pre"))); assert(SemVer("0.5.4").satisfies(SemVerRange("~v0.5.4-pre"))); @@ -590,6 +591,7 @@ unittest assert(!SemVer("1.1.0").satisfies(SemVerRange("~1.0"))); assert(!SemVer("1.0.0").satisfies(SemVerRange("<1"))); assert(!SemVer("1.1.1").satisfies(SemVerRange(">=1.2"))); + assert(!SemVer("1.3.0").satisfies(SemVerRange("<=1.2"))); assert(!SemVer("2.0.0-beta").satisfies(SemVerRange("1"))); assert(!SemVer("0.5.4-alpha").satisfies(SemVerRange("~v0.5.4-beta"))); assert(!SemVer("1.0.0-beta").satisfies(SemVerRange("<1"))); @@ -603,4 +605,8 @@ unittest assert(!SemVer("1.2.2").satisfies(SemVerRange("^1.2.3"))); assert(!SemVer("1.1.9").satisfies(SemVerRange("^1.2"))); assert(!SemVer("2.0.0-pre").satisfies(SemVerRange("^1.2.3"))); + + auto semVers = [SemVer("0.8.0"), SemVer("1.0.0"), SemVer("1.1.0")]; + assert(semVers.maxSatisfying(SemVerRange("<=1.0.0")) == SemVer("1.0.0")); + assert(semVers.maxSatisfying(SemVerRange(">=1.0")) == SemVer("1.1.0")); }