diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2018-07-01 20:14:59 -0300 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2018-07-01 22:54:08 -0300 |
commit | d5eae550c9368bd07008104bdecbcc5eb28814e2 (patch) | |
tree | 441a44a5b8a636d898f20b64d1cb1e938c481bcb /src | |
parent | fbf60599a04cddab512e5e95165fe875d8c01303 (diff) | |
download | luarocks-d5eae550c9368bd07008104bdecbcc5eb28814e2.tar.gz luarocks-d5eae550c9368bd07008104bdecbcc5eb28814e2.tar.bz2 luarocks-d5eae550c9368bd07008104bdecbcc5eb28814e2.zip |
rockspec: fix handling of rockspec_format versions
* luarocks/type_check.lua:
* fix expansion of platforms
* luarocks/type/rockspec.lua:
* when a version fails checking, try with a later
version to produce a hint in the error message.
See #823.
Diffstat (limited to 'src')
-rw-r--r-- | src/luarocks/type/rockspec.lua | 50 | ||||
-rw-r--r-- | src/luarocks/type_check.lua | 37 |
2 files changed, 56 insertions, 31 deletions
diff --git a/src/luarocks/type/rockspec.lua b/src/luarocks/type/rockspec.lua index 8b2bdffa..8214516e 100644 --- a/src/luarocks/type/rockspec.lua +++ b/src/luarocks/type/rockspec.lua | |||
@@ -17,7 +17,7 @@ type_rockspec.rockspec_format = "3.0" | |||
17 | -- _more (boolean) indicates that the table accepts unspecified keys and does not type-check them. | 17 | -- _more (boolean) indicates that the table accepts unspecified keys and does not type-check them. |
18 | -- Any other string keys that don't start with an underscore represent known keys and are type-checking tables, recursively checked. | 18 | -- Any other string keys that don't start with an underscore represent known keys and are type-checking tables, recursively checked. |
19 | 19 | ||
20 | local rockspec_formats = type_check.declare_schemas({ | 20 | local rockspec_formats, versions = type_check.declare_schemas({ |
21 | ["1.0"] = { | 21 | ["1.0"] = { |
22 | rockspec_format = { _type = "string" }, | 22 | rockspec_format = { _type = "string" }, |
23 | package = { _type = "string", _mandatory = true }, | 23 | package = { _type = "string", _mandatory = true }, |
@@ -143,6 +143,22 @@ type_rockspec.order = {"rockspec_format", "package", "version", | |||
143 | "test_dependencies", { "test", {"type"} }, | 143 | "test_dependencies", { "test", {"type"} }, |
144 | "hooks"} | 144 | "hooks"} |
145 | 145 | ||
146 | local function check_rockspec_using_version(rockspec, globals, version) | ||
147 | local schema = rockspec_formats[version] | ||
148 | if not schema then | ||
149 | return nil, "unknown rockspec format " .. version | ||
150 | end | ||
151 | local ok, err = type_check.check_undeclared_globals(globals, schema) | ||
152 | if ok then | ||
153 | ok, err = type_check.type_check_table(version, rockspec, schema, "") | ||
154 | end | ||
155 | if ok then | ||
156 | return true | ||
157 | else | ||
158 | return nil, err | ||
159 | end | ||
160 | end | ||
161 | |||
146 | --- Type check a rockspec table. | 162 | --- Type check a rockspec table. |
147 | -- Verify the correctness of elements from a | 163 | -- Verify the correctness of elements from a |
148 | -- rockspec table, reporting on unknown fields and type | 164 | -- rockspec table, reporting on unknown fields and type |
@@ -151,19 +167,33 @@ type_rockspec.order = {"rockspec_format", "package", "version", | |||
151 | -- succeeded, or nil and an error message if it failed. | 167 | -- succeeded, or nil and an error message if it failed. |
152 | function type_rockspec.check(rockspec, globals) | 168 | function type_rockspec.check(rockspec, globals) |
153 | assert(type(rockspec) == "table") | 169 | assert(type(rockspec) == "table") |
170 | |||
154 | local version = rockspec.rockspec_format or "1.0" | 171 | local version = rockspec.rockspec_format or "1.0" |
155 | local schema = rockspec_formats[version] | 172 | local ok, err = check_rockspec_using_version(rockspec, globals, version) |
156 | if not schema then | ||
157 | return nil, "unknown rockspec format " .. version | ||
158 | end | ||
159 | local ok, err = type_check.check_undeclared_globals(globals, schema) | ||
160 | if ok then | ||
161 | ok, err = type_check.type_check_table(version, rockspec, schema, "") | ||
162 | end | ||
163 | if ok then | 173 | if ok then |
164 | return true | 174 | return true |
165 | end | 175 | end |
166 | return nil, err .. " (rockspec format " .. version .. ")" | 176 | |
177 | -- Rockspec parsing failed. | ||
178 | -- Let's see if it would pass using a later version. | ||
179 | |||
180 | local found = false | ||
181 | for _, v in ipairs(versions) do | ||
182 | if not found then | ||
183 | if v == version then | ||
184 | found = true | ||
185 | end | ||
186 | else | ||
187 | local v_ok, v_err = check_rockspec_using_version(rockspec, globals, v) | ||
188 | if v_ok then | ||
189 | return nil, err .. " (using rockspec format " .. version .. " -- " .. | ||
190 | [[adding 'rockspec_format = "]] .. v .. [["' to the rockspec ]] .. | ||
191 | [[will fix this)]] | ||
192 | end | ||
193 | end | ||
194 | end | ||
195 | |||
196 | return nil, err .. " (using rockspec format " .. version .. ")" | ||
167 | end | 197 | end |
168 | 198 | ||
169 | return type_rockspec | 199 | return type_rockspec |
diff --git a/src/luarocks/type_check.lua b/src/luarocks/type_check.lua index b204f5ee..bdf8ecc8 100644 --- a/src/luarocks/type_check.lua +++ b/src/luarocks/type_check.lua | |||
@@ -2,11 +2,14 @@ | |||
2 | local type_check = {} | 2 | local type_check = {} |
3 | 3 | ||
4 | local cfg = require("luarocks.core.cfg") | 4 | local cfg = require("luarocks.core.cfg") |
5 | local vers = require("luarocks.core.vers") | 5 | local fun = require("luarocks.fun") |
6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
7 | local vers = require("luarocks.core.vers") | ||
7 | -------------------------------------------------------------------------------- | 8 | -------------------------------------------------------------------------------- |
8 | 9 | ||
9 | type_check.MAGIC_PLATFORMS = {} | 10 | -- A magic constant that is not used anywhere in a schema definition |
11 | -- and retains equality when the table is deep-copied. | ||
12 | type_check.MAGIC_PLATFORMS = 0xEBABEFAC | ||
10 | 13 | ||
11 | do | 14 | do |
12 | local function fill_in_version(tbl, version) | 15 | local function fill_in_version(tbl, version) |
@@ -26,7 +29,7 @@ do | |||
26 | tbl[k] = { | 29 | tbl[k] = { |
27 | _any = util.deep_copy(tbl) | 30 | _any = util.deep_copy(tbl) |
28 | } | 31 | } |
29 | tbl[k]._any[v] = nil | 32 | tbl[k]._any[k] = nil |
30 | elseif type(v) == "table" then | 33 | elseif type(v) == "table" then |
31 | expand_magic_platforms(v) | 34 | expand_magic_platforms(v) |
32 | end | 35 | end |
@@ -38,34 +41,26 @@ do | |||
38 | -- and the value is a schema specification. Schema versions are considered | 41 | -- and the value is a schema specification. Schema versions are considered |
39 | -- incremental: version "2.0" only needs to specify what's new/changed from | 42 | -- incremental: version "2.0" only needs to specify what's new/changed from |
40 | -- version "1.0". | 43 | -- version "1.0". |
41 | function type_check.declare_schemas(versions) | 44 | function type_check.declare_schemas(inputs) |
42 | local schemas = {} | 45 | local schemas = {} |
43 | local parent_version | 46 | local parent_version |
44 | 47 | ||
45 | local version_list = {} | 48 | local versions = fun.reverse_in(fun.sort_in(util.keys(inputs), vers.compare_versions)) |
46 | -- FIXME sorting lexicographically! "1.9" > "1.10" | 49 | |
47 | for version, schema in util.sortedpairs(versions) do | 50 | for _, version in ipairs(versions) do |
48 | table.insert(version_list, version) | 51 | local schema = inputs[version] |
49 | if parent_version ~= nil then | 52 | if parent_version ~= nil then |
50 | local copy = util.deep_copy(schemas[parent_version]) | 53 | local copy = util.deep_copy(schemas[parent_version]) |
51 | util.deep_merge(copy, schema) | 54 | util.deep_merge(copy, schema) |
52 | schemas[version] = copy | 55 | schema = copy |
53 | else | ||
54 | schemas[version] = schema | ||
55 | end | 56 | end |
56 | fill_in_version(schemas[version], version) | 57 | fill_in_version(schema, version) |
57 | expand_magic_platforms(schemas[version]) | 58 | expand_magic_platforms(schema) |
58 | parent_version = version | 59 | parent_version = version |
59 | end | 60 | schemas[version] = schema |
60 | |||
61 | -- Merge future versions as fallbacks under the old versions, | ||
62 | -- so that error messages can inform users when they try | ||
63 | -- to use new features without bumping rockspec_format in their rockspecs. | ||
64 | for i = #version_list, 2, -1 do | ||
65 | util.deep_merge_under(schemas[version_list[i - 1]], schemas[version_list[i]]) | ||
66 | end | 61 | end |
67 | 62 | ||
68 | return schemas | 63 | return schemas, versions |
69 | end | 64 | end |
70 | end | 65 | end |
71 | 66 | ||