parent
4f8551b7d0
commit
9f7ebdced2
@ -19,6 +19,7 @@
|
||||
"base/tools.lua",
|
||||
"base/tree.lua",
|
||||
"base/globals.lua",
|
||||
"base/semver.lua",
|
||||
|
||||
-- configuration data
|
||||
"base/field.lua",
|
||||
|
@ -10,6 +10,7 @@
|
||||
premake.modules = {}
|
||||
premake.extensions = premake.modules
|
||||
|
||||
local semver = dofile('semver.lua')
|
||||
local p = premake
|
||||
|
||||
|
||||
@ -113,7 +114,7 @@
|
||||
for i = 1, n do
|
||||
local fn = namespace[array[i]]
|
||||
if not fn then
|
||||
error(string.format("Unable to find function '%s'", array[i]))
|
||||
error(string.format("Unable to find function '%s'", array[i]))
|
||||
end
|
||||
fn(...)
|
||||
end
|
||||
@ -123,7 +124,7 @@
|
||||
|
||||
|
||||
---
|
||||
-- Compare a version string of the form "major.minor.patch.dev" against a
|
||||
-- Compare a version string that uses semver semantics against a
|
||||
-- version comparision string. Comparisions take the form of ">=5.0" (5.0 or
|
||||
-- later), "5.0" (5.0 or later), ">=5.0 <6.0" (5.0 or later but not 6.0 or
|
||||
-- later).
|
||||
@ -141,31 +142,14 @@
|
||||
return false
|
||||
end
|
||||
|
||||
local function parse(str)
|
||||
local major, minor, patch, dev = str:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$")
|
||||
major = tonumber(major) or 0
|
||||
minor = tonumber(minor) or 0
|
||||
patch = tonumber(patch) or 0
|
||||
dev = dev or ""
|
||||
return { major, minor, patch, dev }
|
||||
end
|
||||
|
||||
local function compare(a, b)
|
||||
for i=1,4 do
|
||||
if a[i] > b[i] then return 1 end
|
||||
if a[i] < b[i] then return -1 end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function eq(r) return r == 0 end
|
||||
local function le(r) return r <= 0 end
|
||||
local function lt(r) return r < 0 end
|
||||
local function ge(r) return r >= 0 end
|
||||
local function gt(r) return r > 0 end
|
||||
|
||||
version = parse(version)
|
||||
local function eq(a, b) return a == b end
|
||||
local function le(a, b) return a <= b end
|
||||
local function lt(a, b) return a < b end
|
||||
local function ge(a, b) return a >= b end
|
||||
local function gt(a, b) return a > b end
|
||||
local function compat(a, b) return a ^ b end
|
||||
|
||||
version = semver(version)
|
||||
checks = string.explode(checks, " ", true)
|
||||
for i = 1, #checks do
|
||||
local check = checks[i]
|
||||
@ -185,12 +169,15 @@
|
||||
elseif check:startswith("=") then
|
||||
func = eq
|
||||
check = check:sub(2)
|
||||
elseif check:startswith("^") then
|
||||
func = compat
|
||||
check = check:sub(2)
|
||||
else
|
||||
func = ge
|
||||
end
|
||||
|
||||
check = parse(check)
|
||||
if not func(compare(version, check)) then
|
||||
check = semver(check)
|
||||
if not func(version, check) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
206
src/base/semver.lua
Normal file
206
src/base/semver.lua
Normal file
@ -0,0 +1,206 @@
|
||||
local semver = {
|
||||
_VERSION = '1.2.0',
|
||||
_DESCRIPTION = 'semver for Lua',
|
||||
_URL = 'https://github.com/kikito/semver.lua',
|
||||
_LICENSE = [[
|
||||
MIT LICENSE
|
||||
|
||||
Copyright (c) 2015 Enrique García Cota
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of tother software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and tother permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
}
|
||||
|
||||
local function checkPositiveInteger(number, name)
|
||||
assert(number >= 0, name .. ' must be a valid positive number')
|
||||
assert(math.floor(number) == number, name .. ' must be an integer')
|
||||
end
|
||||
|
||||
local function present(value)
|
||||
return value and value ~= ''
|
||||
end
|
||||
|
||||
-- splitByDot("a.bbc.d") == {"a", "bbc", "d"}
|
||||
local function splitByDot(str)
|
||||
str = str or ""
|
||||
local t, count = {}, 0
|
||||
str:gsub("([^%.]+)", function(c)
|
||||
count = count + 1
|
||||
t[count] = c
|
||||
end)
|
||||
return t
|
||||
end
|
||||
|
||||
local function parsePrereleaseAndBuildWithSign(str)
|
||||
local prereleaseWithSign, buildWithSign = str:match("^(-[^+]+)(+.+)$")
|
||||
if not (prereleaseWithSign and buildWithSign) then
|
||||
prereleaseWithSign = str:match("^(-.+)$")
|
||||
buildWithSign = str:match("^(+.+)$")
|
||||
end
|
||||
assert(prereleaseWithSign or buildWithSign, ("The parameter %q must begin with + or - to denote a prerelease or a build"):format(str))
|
||||
return prereleaseWithSign, buildWithSign
|
||||
end
|
||||
|
||||
local function parsePrerelease(prereleaseWithSign)
|
||||
if prereleaseWithSign then
|
||||
local prerelease = prereleaseWithSign:match("^-(%w[%.%w-]*)$")
|
||||
assert(prerelease, ("The prerelease %q is not a slash followed by alphanumerics, dots and slashes"):format(prereleaseWithSign))
|
||||
return prerelease
|
||||
end
|
||||
end
|
||||
|
||||
local function parseBuild(buildWithSign)
|
||||
if buildWithSign then
|
||||
local build = buildWithSign:match("^%+(%w[%.%w-]*)$")
|
||||
assert(build, ("The build %q is not a + sign followed by alphanumerics, dots and slashes"):format(buildWithSign))
|
||||
return build
|
||||
end
|
||||
end
|
||||
|
||||
local function parsePrereleaseAndBuild(str)
|
||||
if not present(str) then return nil, nil end
|
||||
|
||||
local prereleaseWithSign, buildWithSign = parsePrereleaseAndBuildWithSign(str)
|
||||
|
||||
local prerelease = parsePrerelease(prereleaseWithSign)
|
||||
local build = parseBuild(buildWithSign)
|
||||
|
||||
return prerelease, build
|
||||
end
|
||||
|
||||
local function parseVersion(str)
|
||||
local sMajor, sMinor, sPatch, sPrereleaseAndBuild = str:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$")
|
||||
assert(type(sMajor) == 'string', ("Could not extract version number(s) from %q"):format(str))
|
||||
local major, minor, patch = tonumber(sMajor), tonumber(sMinor), tonumber(sPatch)
|
||||
local prerelease, build = parsePrereleaseAndBuild(sPrereleaseAndBuild)
|
||||
return major, minor, patch, prerelease, build
|
||||
end
|
||||
|
||||
|
||||
-- return 0 if a == b, -1 if a < b, and 1 if a > b
|
||||
local function compare(a,b)
|
||||
return a == b and 0 or a < b and -1 or 1
|
||||
end
|
||||
|
||||
local function compareIds(myId, otherId)
|
||||
if myId == otherId then return 0
|
||||
elseif not myId then return -1
|
||||
elseif not otherId then return 1
|
||||
end
|
||||
|
||||
local selfNumber, otherNumber = tonumber(myId), tonumber(otherId)
|
||||
|
||||
if selfNumber and otherNumber then -- numerical comparison
|
||||
return compare(selfNumber, otherNumber)
|
||||
-- numericals are always smaller than alphanums
|
||||
elseif selfNumber then
|
||||
return -1
|
||||
elseif otherNumber then
|
||||
return 1
|
||||
else
|
||||
return compare(myId, otherId) -- alphanumerical comparison
|
||||
end
|
||||
end
|
||||
|
||||
local function smallerIdList(myIds, otherIds)
|
||||
local myLength = #myIds
|
||||
local comparison
|
||||
|
||||
for i=1, myLength do
|
||||
comparison = compareIds(myIds[i], otherIds[i])
|
||||
if comparison ~= 0 then
|
||||
return comparison == -1
|
||||
end
|
||||
-- if comparison == 0, continue loop
|
||||
end
|
||||
|
||||
return myLength < #otherIds
|
||||
end
|
||||
|
||||
local function smallerPrerelease(mine, other)
|
||||
if mine == other or not mine then return false
|
||||
elseif not other then return true
|
||||
end
|
||||
|
||||
return smallerIdList(splitByDot(mine), splitByDot(other))
|
||||
end
|
||||
|
||||
local methods = {}
|
||||
|
||||
function methods:nextMajor()
|
||||
return semver(self.major + 1, 0, 0)
|
||||
end
|
||||
function methods:nextMinor()
|
||||
return semver(self.major, self.minor + 1, 0)
|
||||
end
|
||||
function methods:nextPatch()
|
||||
return semver(self.major, self.minor, self.patch + 1)
|
||||
end
|
||||
|
||||
local mt = { __index = methods }
|
||||
function mt:__eq(other)
|
||||
return self.major == other.major and
|
||||
self.minor == other.minor and
|
||||
self.patch == other.patch and
|
||||
self.prerelease == other.prerelease
|
||||
-- notice that build is ignored for precedence in semver 2.0.0
|
||||
end
|
||||
function mt:__lt(other)
|
||||
if self.major ~= other.major then return self.major < other.major end
|
||||
if self.minor ~= other.minor then return self.minor < other.minor end
|
||||
if self.patch ~= other.patch then return self.patch < other.patch end
|
||||
return smallerPrerelease(self.prerelease, other.prerelease)
|
||||
-- notice that build is ignored for precedence in semver 2.0.0
|
||||
end
|
||||
-- This works like the "pessimisstic operator" in Rubygems.
|
||||
-- if a and b are versions, a ^ b means "b is backwards-compatible with a"
|
||||
-- in other words, "it's safe to upgrade from a to b"
|
||||
function mt:__pow(other)
|
||||
return self.major == other.major and
|
||||
self.minor <= other.minor
|
||||
end
|
||||
function mt:__tostring()
|
||||
local buffer = { ("%d.%d.%d"):format(self.major, self.minor, self.patch) }
|
||||
if self.prerelease then table.insert(buffer, "-" .. self.prerelease) end
|
||||
if self.build then table.insert(buffer, "+" .. self.build) end
|
||||
return table.concat(buffer)
|
||||
end
|
||||
|
||||
local function new(major, minor, patch, prerelease, build)
|
||||
assert(major, "At least one parameter is needed")
|
||||
|
||||
if type(major) == 'string' then
|
||||
major,minor,patch,prerelease,build = parseVersion(major)
|
||||
end
|
||||
patch = patch or 0
|
||||
minor = minor or 0
|
||||
|
||||
checkPositiveInteger(major, "major")
|
||||
checkPositiveInteger(minor, "minor")
|
||||
checkPositiveInteger(patch, "patch")
|
||||
|
||||
local result = {major=major, minor=minor, patch=patch, prerelease=prerelease, build=build}
|
||||
return setmetatable(result, mt)
|
||||
end
|
||||
|
||||
setmetatable(semver, { __call = function(_, ...) return new(...) end })
|
||||
semver._VERSION= semver(semver._VERSION)
|
||||
|
||||
return semver
|
@ -29,14 +29,22 @@
|
||||
test.istrue(p.checkVersion("1.0.1", "1"))
|
||||
end
|
||||
|
||||
function suite.pass_majorOnly_alpha()
|
||||
test.istrue(p.checkVersion("1.0.0.alpha1", "1"))
|
||||
--
|
||||
-- prereleases should be fail against true release.
|
||||
--
|
||||
|
||||
function suite.fail_majorOnly_alpha()
|
||||
test.isfalse(p.checkVersion("1.0.0-alpha1", "1"))
|
||||
end
|
||||
|
||||
function suite.pass_majorOnly_dev()
|
||||
test.istrue(p.checkVersion("1.0.0.dev", "1"))
|
||||
function suite.fail_majorOnly_dev()
|
||||
test.isfalse(p.checkVersion("1.0.0-dev", "1"))
|
||||
end
|
||||
|
||||
--
|
||||
-- ealier versions should be fail against major release.
|
||||
--
|
||||
|
||||
function suite.fail_earlierMajor()
|
||||
test.isfalse(p.checkVersion("0.9.0", "1"))
|
||||
end
|
||||
@ -83,19 +91,19 @@
|
||||
--
|
||||
|
||||
function suite.pass_alphaBeforeBeta()
|
||||
test.istrue(p.checkVersion("1.0.0.beta1", "1.0.0.alpha1"))
|
||||
test.istrue(p.checkVersion("1.0.0-beta1", "1.0.0-alpha1"))
|
||||
end
|
||||
|
||||
function suite.fail_alphaBeforeBeta()
|
||||
test.isfalse(p.checkVersion("1.0.0.alpha1", "1.0.0.beta1"))
|
||||
test.isfalse(p.checkVersion("1.0.0-alpha1", "1.0.0-beta1"))
|
||||
end
|
||||
|
||||
function suite.pass_betaBeforeDev()
|
||||
test.istrue(p.checkVersion("1.0.0.dev", "1.0.0.beta1"))
|
||||
test.istrue(p.checkVersion("1.0.0-dev", "1.0.0-beta1"))
|
||||
end
|
||||
|
||||
function suite.fail_betaBeforeDev()
|
||||
test.isfalse(p.checkVersion("1.0.0.beta1", "1.0.0.dev"))
|
||||
test.isfalse(p.checkVersion("1.0.0-beta1", "1.0.0-dev"))
|
||||
end
|
||||
|
||||
|
||||
@ -162,11 +170,11 @@
|
||||
--
|
||||
|
||||
function suite.pass_onMultipleConditions()
|
||||
test.istrue(p.checkVersion("1.2.0.0", ">=1.0 <2.0"))
|
||||
test.istrue(p.checkVersion("1.2.0", ">=1.0 <2.0"))
|
||||
end
|
||||
|
||||
function suite.fail_onMultipleConditions()
|
||||
test.isfalse(p.checkVersion("2.2.0.0", ">=1.0 <2.0"))
|
||||
test.isfalse(p.checkVersion("2.2.0", ">=1.0 <2.0"))
|
||||
end
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user