aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2016-11-14 14:07:02 -0200
committerGitHub <noreply@github.com>2016-11-14 14:07:02 -0200
commit39fe27721f2ed6a4093fa79dd4219d61bdf48f3f (patch)
tree174929982a0954b3582fbce9bc13f4af4a9b5d0e
parent9f4fa981c5defaaf7b82b629ff68f1e3ec58650f (diff)
parent16c2001e0a25ec52354cd712b6d78742f1b8b597 (diff)
downloadluarocks-39fe27721f2ed6a4093fa79dd4219d61bdf48f3f.tar.gz
luarocks-39fe27721f2ed6a4093fa79dd4219d61bdf48f3f.tar.bz2
luarocks-39fe27721f2ed6a4093fa79dd4219d61bdf48f3f.zip
Merge pull request #654 from mpeterv/split-deps
Split out luarocks.vers from luarocks.deps
-rw-r--r--Makefile.setup.inc2
-rw-r--r--src/luarocks/cmd/list.lua8
-rw-r--r--src/luarocks/cmd/purge.lua6
-rw-r--r--src/luarocks/cmd/show.lua4
-rw-r--r--src/luarocks/cmd/write_rockspec.lua4
-rw-r--r--src/luarocks/core/type_check.lua4
-rw-r--r--src/luarocks/core/vers.lua (renamed from src/luarocks/core/deps.lua)19
-rw-r--r--src/luarocks/deps.lua152
-rw-r--r--src/luarocks/fetch.lua8
-rw-r--r--src/luarocks/fetch/git.lua8
-rw-r--r--src/luarocks/index.lua4
-rw-r--r--src/luarocks/loader.lua8
-rw-r--r--src/luarocks/manif/writer.lua9
-rw-r--r--src/luarocks/repos.lua4
-rw-r--r--src/luarocks/search.lua12
-rw-r--r--src/luarocks/util.lua4
-rw-r--r--src/luarocks/vers.lua138
17 files changed, 199 insertions, 195 deletions
diff --git a/Makefile.setup.inc b/Makefile.setup.inc
index c126a931..0a34429c 100644
--- a/Makefile.setup.inc
+++ b/Makefile.setup.inc
@@ -21,4 +21,4 @@ admin/cmd/make_manifest.lua admin/cmd/add.lua admin/cmd/remove.lua \
21admin/cmd/refresh_cache.lua remove.lua fetch/git_file.lua fetch/sscm.lua \ 21admin/cmd/refresh_cache.lua remove.lua fetch/git_file.lua fetch/sscm.lua \
22fetch/cvs.lua fetch/git_https.lua fetch/git_ssh.lua fetch/hg_http.lua \ 22fetch/cvs.lua fetch/git_https.lua fetch/git_ssh.lua fetch/hg_http.lua \
23fetch/git_http.lua fetch/svn.lua fetch/git.lua fetch/hg_ssh.lua \ 23fetch/git_http.lua fetch/svn.lua fetch/git.lua fetch/hg_ssh.lua \
24fetch/hg_https.lua fetch/hg.lua 24fetch/hg_https.lua fetch/hg.lua vers.lua core/vers.lua
diff --git a/src/luarocks/cmd/list.lua b/src/luarocks/cmd/list.lua
index 45f1a26f..9dff22ac 100644
--- a/src/luarocks/cmd/list.lua
+++ b/src/luarocks/cmd/list.lua
@@ -4,7 +4,7 @@
4local list = {} 4local list = {}
5 5
6local search = require("luarocks.search") 6local search = require("luarocks.search")
7local deps = require("luarocks.deps") 7local vers = require("luarocks.vers")
8local cfg = require("luarocks.core.cfg") 8local cfg = require("luarocks.core.cfg")
9local util = require("luarocks.util") 9local util = require("luarocks.util")
10local path = require("luarocks.path") 10local path = require("luarocks.path")
@@ -28,7 +28,7 @@ local function check_outdated(trees, query)
28 local outdated = {} 28 local outdated = {}
29 for name, versions in util.sortedpairs(results_installed) do 29 for name, versions in util.sortedpairs(results_installed) do
30 versions = util.keys(versions) 30 versions = util.keys(versions)
31 table.sort(versions, deps.compare_versions) 31 table.sort(versions, vers.compare_versions)
32 local latest_installed = versions[1] 32 local latest_installed = versions[1]
33 33
34 local query_available = search.make_query(name:lower()) 34 local query_available = search.make_query(name:lower())
@@ -37,11 +37,11 @@ local function check_outdated(trees, query)
37 37
38 if results_available[name] then 38 if results_available[name] then
39 local available_versions = util.keys(results_available[name]) 39 local available_versions = util.keys(results_available[name])
40 table.sort(available_versions, deps.compare_versions) 40 table.sort(available_versions, vers.compare_versions)
41 local latest_available = available_versions[1] 41 local latest_available = available_versions[1]
42 local latest_available_repo = results_available[name][latest_available][1].repo 42 local latest_available_repo = results_available[name][latest_available][1].repo
43 43
44 if deps.compare_versions(latest_available, latest_installed) then 44 if vers.compare_versions(latest_available, latest_installed) then
45 table.insert(outdated, { name = name, installed = latest_installed, available = latest_available, repo = latest_available_repo }) 45 table.insert(outdated, { name = name, installed = latest_installed, available = latest_available, repo = latest_available_repo })
46 end 46 end
47 end 47 end
diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua
index 50f290c8..bbce9f8c 100644
--- a/src/luarocks/cmd/purge.lua
+++ b/src/luarocks/cmd/purge.lua
@@ -7,7 +7,7 @@ local util = require("luarocks.util")
7local fs = require("luarocks.fs") 7local fs = require("luarocks.fs")
8local path = require("luarocks.path") 8local path = require("luarocks.path")
9local search = require("luarocks.search") 9local search = require("luarocks.search")
10local deps = require("luarocks.deps") 10local vers = require("luarocks.vers")
11local repos = require("luarocks.repos") 11local repos = require("luarocks.repos")
12local writer = require("luarocks.manif.writer") 12local writer = require("luarocks.manif.writer")
13local cfg = require("luarocks.core.cfg") 13local cfg = require("luarocks.core.cfg")
@@ -48,9 +48,9 @@ function purge.command(flags)
48 48
49 search.manifest_search(results, path.rocks_dir(tree), query) 49 search.manifest_search(results, path.rocks_dir(tree), query)
50 50
51 local sort = function(a,b) return deps.compare_versions(b,a) end 51 local sort = function(a,b) return vers.compare_versions(b,a) end
52 if flags["old-versions"] then 52 if flags["old-versions"] then
53 sort = deps.compare_versions 53 sort = vers.compare_versions
54 end 54 end
55 55
56 for package, versions in util.sortedpairs(results) do 56 for package, versions in util.sortedpairs(results) do
diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua
index ad48b153..16c8d34e 100644
--- a/src/luarocks/cmd/show.lua
+++ b/src/luarocks/cmd/show.lua
@@ -6,7 +6,7 @@ local search = require("luarocks.search")
6local cfg = require("luarocks.core.cfg") 6local cfg = require("luarocks.core.cfg")
7local util = require("luarocks.util") 7local util = require("luarocks.util")
8local path = require("luarocks.path") 8local path = require("luarocks.path")
9local deps = require("luarocks.deps") 9local vers = require("luarocks.vers")
10local fetch = require("luarocks.fetch") 10local fetch = require("luarocks.fetch")
11local manif = require("luarocks.manif") 11local manif = require("luarocks.manif")
12local repos = require("luarocks.repos") 12local repos = require("luarocks.repos")
@@ -147,7 +147,7 @@ function show.command(flags, name, version)
147 util.printout("Depends on:") 147 util.printout("Depends on:")
148 for _, dep in ipairs(rockspec.dependencies) do 148 for _, dep in ipairs(rockspec.dependencies) do
149 direct_deps[dep.name] = true 149 direct_deps[dep.name] = true
150 util.printout("\t"..deps.show_dep(dep).." "..installed_rock_label(dep.name, flags["tree"])) 150 util.printout("\t"..vers.show_dep(dep).." "..installed_rock_label(dep.name, flags["tree"]))
151 end 151 end
152 end 152 end
153 local has_indirect_deps 153 local has_indirect_deps
diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua
index be563eaa..73010f08 100644
--- a/src/luarocks/cmd/write_rockspec.lua
+++ b/src/luarocks/cmd/write_rockspec.lua
@@ -9,7 +9,7 @@ local path = require("luarocks.path")
9local persist = require("luarocks.persist") 9local persist = require("luarocks.persist")
10local type_check = require("luarocks.type_check") 10local type_check = require("luarocks.type_check")
11local util = require("luarocks.util") 11local util = require("luarocks.util")
12local deps = require("luarocks.deps") 12local vers = require("luarocks.vers")
13 13
14write_rockspec.help_summary = "Write a template for a rockspec file." 14write_rockspec.help_summary = "Write a template for a rockspec file."
15write_rockspec.help_arguments = "[--output=<file> ...] [<name>] [<version>] [<url>|<path>]" 15write_rockspec.help_arguments = "[--output=<file> ...] [<name>] [<version>] [<url>|<path>]"
@@ -285,7 +285,7 @@ function write_rockspec.command(flags, name, version, url_or_dir)
285 } 285 }
286 path.configure_paths(rockspec) 286 path.configure_paths(rockspec)
287 rockspec.source.protocol = protocol 287 rockspec.source.protocol = protocol
288 rockspec.format_is_at_least = deps.format_is_at_least 288 rockspec.format_is_at_least = vers.format_is_at_least
289 289
290 configure_lua_version(rockspec, flags["lua-version"]) 290 configure_lua_version(rockspec, flags["lua-version"])
291 291
diff --git a/src/luarocks/core/type_check.lua b/src/luarocks/core/type_check.lua
index 1822312b..343b7154 100644
--- a/src/luarocks/core/type_check.lua
+++ b/src/luarocks/core/type_check.lua
@@ -2,7 +2,7 @@
2local type_check = {} 2local type_check = {}
3 3
4local cfg = require("luarocks.core.cfg") 4local cfg = require("luarocks.core.cfg")
5local deps = require("luarocks.core.deps") 5local vers = require("luarocks.core.vers")
6local require = nil 6local require = nil
7-------------------------------------------------------------------------------- 7--------------------------------------------------------------------------------
8 8
@@ -74,7 +74,7 @@ local manifest_types = {
74 74
75local function check_version(version, typetbl, context) 75local function check_version(version, typetbl, context)
76 local typetbl_version = typetbl._version or "1.0" 76 local typetbl_version = typetbl._version or "1.0"
77 if deps.compare_versions(typetbl_version, version) then 77 if vers.compare_versions(typetbl_version, version) then
78 if context == "" then 78 if context == "" then
79 return nil, "Invalid rockspec_format version number in rockspec? Please fix rockspec accordingly." 79 return nil, "Invalid rockspec_format version number in rockspec? Please fix rockspec accordingly."
80 else 80 else
diff --git a/src/luarocks/core/deps.lua b/src/luarocks/core/vers.lua
index 6d539eb8..2a765b9b 100644
--- a/src/luarocks/core/deps.lua
+++ b/src/luarocks/core/vers.lua
@@ -1,5 +1,5 @@
1 1
2local deps = {} 2local vers = {}
3 3
4local util = require("luarocks.core.util") 4local util = require("luarocks.core.util")
5local require = nil 5local require = nil
@@ -73,7 +73,7 @@ setmetatable(version_cache, {
73-- @param vstring string: A version number in string format. 73-- @param vstring string: A version number in string format.
74-- @return table or nil: A version table or nil 74-- @return table or nil: A version table or nil
75-- if the input string contains invalid characters. 75-- if the input string contains invalid characters.
76function deps.parse_version(vstring) 76function vers.parse_version(vstring)
77 if not vstring then return nil end 77 if not vstring then return nil end
78 assert(type(vstring) == "string") 78 assert(type(vstring) == "string")
79 79
@@ -125,8 +125,8 @@ end
125-- @param a string: one version. 125-- @param a string: one version.
126-- @param b string: another version. 126-- @param b string: another version.
127-- @return boolean: True if a > b. 127-- @return boolean: True if a > b.
128function deps.compare_versions(a, b) 128function vers.compare_versions(a, b)
129 return deps.parse_version(a) > deps.parse_version(b) 129 return vers.parse_version(a) > vers.parse_version(b)
130end 130end
131 131
132--- A more lenient check for equivalence between versions. 132--- A more lenient check for equivalence between versions.
@@ -145,8 +145,8 @@ local function partial_match(version, requested)
145 assert(type(version) == "string" or type(version) == "table") 145 assert(type(version) == "string" or type(version) == "table")
146 assert(type(requested) == "string" or type(version) == "table") 146 assert(type(requested) == "string" or type(version) == "table")
147 147
148 if type(version) ~= "table" then version = deps.parse_version(version) end 148 if type(version) ~= "table" then version = vers.parse_version(version) end
149 if type(requested) ~= "table" then requested = deps.parse_version(requested) end 149 if type(requested) ~= "table" then requested = vers.parse_version(requested) end
150 if not version or not requested then return false end 150 if not version or not requested then return false end
151 151
152 for i, ri in ipairs(requested) do 152 for i, ri in ipairs(requested) do
@@ -164,14 +164,14 @@ end
164-- @param constraints table: An array of constraints in table format. 164-- @param constraints table: An array of constraints in table format.
165-- @return boolean: True if version satisfies all constraints, 165-- @return boolean: True if version satisfies all constraints,
166-- false otherwise. 166-- false otherwise.
167function deps.match_constraints(version, constraints) 167function vers.match_constraints(version, constraints)
168 assert(type(version) == "table") 168 assert(type(version) == "table")
169 assert(type(constraints) == "table") 169 assert(type(constraints) == "table")
170 local ok = true 170 local ok = true
171 setmetatable(version, version_mt) 171 setmetatable(version, version_mt)
172 for _, constr in pairs(constraints) do 172 for _, constr in pairs(constraints) do
173 if type(constr.version) == "string" then 173 if type(constr.version) == "string" then
174 constr.version = deps.parse_version(constr.version) 174 constr.version = vers.parse_version(constr.version)
175 end 175 end
176 local constr_version, constr_op = constr.version, constr.op 176 local constr_version, constr_op = constr.version, constr.op
177 setmetatable(constr_version, version_mt) 177 setmetatable(constr_version, version_mt)
@@ -188,5 +188,4 @@ function deps.match_constraints(version, constraints)
188 return ok 188 return ok
189end 189end
190 190
191return deps 191return vers
192
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua
index 1c75a694..015e2527 100644
--- a/src/luarocks/deps.lua
+++ b/src/luarocks/deps.lua
@@ -1,147 +1,13 @@
1 1
2--- Dependency handling functions. 2--- High-level dependency related functions.
3-- Dependencies are represented in LuaRocks through strings with
4-- a package name followed by a comma-separated list of constraints.
5-- Each constraint consists of an operator and a version number.
6-- In this string format, version numbers are represented as
7-- naturally as possible, like they are used by upstream projects
8-- (e.g. "2.0beta3"). Internally, LuaRocks converts them to a purely
9-- numeric representation, allowing comparison following some
10-- "common sense" heuristics. The precise specification of the
11-- comparison criteria is the source code of this module, but the
12-- test/test_deps.lua file included with LuaRocks provides some
13-- insights on what these criteria are.
14local deps = {} 3local deps = {}
15setmetatable(deps, { __index = require("luarocks.core.deps") })
16 4
17local cfg = require("luarocks.core.cfg") 5local cfg = require("luarocks.core.cfg")
18local manif = require("luarocks.core.manif") 6local manif = require("luarocks.manif")
19local path = require("luarocks.path") 7local path = require("luarocks.path")
20local dir = require("luarocks.dir") 8local dir = require("luarocks.dir")
21local util = require("luarocks.util") 9local util = require("luarocks.util")
22 10local vers = require("luarocks.vers")
23--- Check if rockspec format version satisfies version requirement.
24-- @param rockspec table: The rockspec table.
25-- @param version string: required version.
26-- @return boolean: true if rockspec format matches version or is newer, false otherwise.
27function deps.format_is_at_least(rockspec, version)
28 local rockspec_format = rockspec.rockspec_format or "1.0"
29 return deps.parse_version(rockspec_format) >= deps.parse_version(version)
30end
31
32local operators = {
33 ["=="] = "==",
34 ["~="] = "~=",
35 [">"] = ">",
36 ["<"] = "<",
37 [">="] = ">=",
38 ["<="] = "<=",
39 ["~>"] = "~>",
40 -- plus some convenience translations
41 [""] = "==",
42 ["="] = "==",
43 ["!="] = "~="
44}
45
46--- Consumes a constraint from a string, converting it to table format.
47-- For example, a string ">= 1.0, > 2.0" is converted to a table in the
48-- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned
49-- back to the caller.
50-- @param input string: A list of constraints in string format.
51-- @return (table, string) or nil: A table representing the same
52-- constraints and the string with the unused input, or nil if the
53-- input string is invalid.
54local function parse_constraint(input)
55 assert(type(input) == "string")
56
57 local no_upgrade, op, version, rest = input:match("^(@?)([<>=~!]*)%s*([%w%.%_%-]+)[%s,]*(.*)")
58 local _op = operators[op]
59 version = deps.parse_version(version)
60 if not _op then
61 return nil, "Encountered bad constraint operator: '"..tostring(op).."' in '"..input.."'"
62 end
63 if not version then
64 return nil, "Could not parse version from constraint: '"..input.."'"
65 end
66 return { op = _op, version = version, no_upgrade = no_upgrade=="@" and true or nil }, rest
67end
68
69--- Convert a list of constraints from string to table format.
70-- For example, a string ">= 1.0, < 2.0" is converted to a table in the format
71-- {{op = ">=", version={1,0}}, {op = "<", version={2,0}}}.
72-- Version tables use a metatable allowing later comparison through
73-- relational operators.
74-- @param input string: A list of constraints in string format.
75-- @return table or nil: A table representing the same constraints,
76-- or nil if the input string is invalid.
77function deps.parse_constraints(input)
78 assert(type(input) == "string")
79
80 local constraints, oinput, constraint = {}, input
81 while #input > 0 do
82 constraint, input = parse_constraint(input)
83 if constraint then
84 table.insert(constraints, constraint)
85 else
86 return nil, "Failed to parse constraint '"..tostring(oinput).."' with error: ".. input
87 end
88 end
89 return constraints
90end
91
92--- Convert a dependency from string to table format.
93-- For example, a string "foo >= 1.0, < 2.0"
94-- is converted to a table in the format
95-- {name = "foo", constraints = {{op = ">=", version={1,0}},
96-- {op = "<", version={2,0}}}}. Version tables use a metatable
97-- allowing later comparison through relational operators.
98-- @param dep string: A dependency in string format
99-- as entered in rockspec files.
100-- @return table or nil: A table representing the same dependency relation,
101-- or nil if the input string is invalid.
102function deps.parse_dep(dep)
103 assert(type(dep) == "string")
104
105 local name, rest = dep:match("^%s*([a-zA-Z0-9][a-zA-Z0-9%.%-%_]*)%s*(.*)")
106 if not name then return nil, "failed to extract dependency name from '"..tostring(dep).."'" end
107 local constraints, err = deps.parse_constraints(rest)
108 if not constraints then return nil, err end
109 return { name = name, constraints = constraints }
110end
111
112--- Convert a version table to a string.
113-- @param v table: The version table
114-- @param internal boolean or nil: Whether to display versions in their
115-- internal representation format or how they were specified.
116-- @return string: The dependency information pretty-printed as a string.
117function deps.show_version(v, internal)
118 assert(type(v) == "table")
119 assert(type(internal) == "boolean" or not internal)
120
121 return (internal
122 and table.concat(v, ":")..(v.revision and tostring(v.revision) or "")
123 or v.string)
124end
125
126--- Convert a dependency in table format to a string.
127-- @param dep table: The dependency in table format
128-- @param internal boolean or nil: Whether to display versions in their
129-- internal representation format or how they were specified.
130-- @return string: The dependency information pretty-printed as a string.
131function deps.show_dep(dep, internal)
132 assert(type(dep) == "table")
133 assert(type(internal) == "boolean" or not internal)
134
135 if #dep.constraints > 0 then
136 local pretty = {}
137 for _, c in ipairs(dep.constraints) do
138 table.insert(pretty, c.op .. " " .. deps.show_version(c.version, internal))
139 end
140 return dep.name.." "..table.concat(pretty, ", ")
141 else
142 return dep.name
143 end
144end
145 11
146--- Attempt to match a dependency to an installed rock. 12--- Attempt to match a dependency to an installed rock.
147-- @param dep table: A dependency parsed in table format. 13-- @param dep table: A dependency parsed in table format.
@@ -167,8 +33,8 @@ local function match_dep(dep, blacklist, deps_mode, rocks_provided)
167 local latest_version 33 local latest_version
168 for _, vstring in ipairs(versions) do 34 for _, vstring in ipairs(versions) do
169 if not blacklist or not blacklist[vstring] then 35 if not blacklist or not blacklist[vstring] then
170 local version = deps.parse_version(vstring) 36 local version = vers.parse_version(vstring)
171 if deps.match_constraints(version, dep.constraints) then 37 if vers.match_constraints(version, dep.constraints) then
172 if not latest_version or version > latest_version then 38 if not latest_version or version > latest_version then
173 latest_version = version 39 latest_version = version
174 end 40 end
@@ -249,7 +115,7 @@ function deps.report_missing_dependencies(name, version, dependencies, deps_mode
249 first_missing_dep = false 115 first_missing_dep = false
250 end 116 end
251 117
252 util.printout((" %s (%s)"):format(deps.show_dep(dep), rock_status(dep.name, deps_mode, rocks_provided))) 118 util.printout((" %s (%s)"):format(vers.show_dep(dep), rock_status(dep.name, deps_mode, rocks_provided)))
253 end 119 end
254 end 120 end
255end 121end
@@ -306,11 +172,11 @@ function deps.fulfill_dependencies(rockspec, deps_mode)
306 end 172 end
307 173
308 util.printout(("%s %s depends on %s (%s)"):format( 174 util.printout(("%s %s depends on %s (%s)"):format(
309 rockspec.name, rockspec.version, deps.show_dep(dep), rock_status(dep.name, deps_mode, rockspec.rocks_provided))) 175 rockspec.name, rockspec.version, vers.show_dep(dep), rock_status(dep.name, deps_mode, rockspec.rocks_provided)))
310 176
311 if dep.constraints[1] and dep.constraints[1].no_upgrade then 177 if dep.constraints[1] and dep.constraints[1].no_upgrade then
312 util.printerr("This version of "..rockspec.name.." is designed for use with") 178 util.printerr("This version of "..rockspec.name.." is designed for use with")
313 util.printerr(deps.show_dep(dep)..", but is configured to avoid upgrading it") 179 util.printerr(vers.show_dep(dep)..", but is configured to avoid upgrading it")
314 util.printerr("automatically. Please upgrade "..dep.name.." with") 180 util.printerr("automatically. Please upgrade "..dep.name.." with")
315 util.printerr(" luarocks install "..dep.name) 181 util.printerr(" luarocks install "..dep.name)
316 util.printerr("or choose an older version of "..rockspec.name.." with") 182 util.printerr("or choose an older version of "..rockspec.name.." with")
@@ -320,7 +186,7 @@ function deps.fulfill_dependencies(rockspec, deps_mode)
320 186
321 local url, search_err = search.find_suitable_rock(dep) 187 local url, search_err = search.find_suitable_rock(dep)
322 if not url then 188 if not url then
323 return nil, "Could not satisfy dependency "..deps.show_dep(dep)..": "..search_err 189 return nil, "Could not satisfy dependency "..vers.show_dep(dep)..": "..search_err
324 end 190 end
325 util.printout("Installing "..url) 191 util.printout("Installing "..url)
326 local ok, install_err, errcode = install.command({deps_mode = deps_mode}, url) 192 local ok, install_err, errcode = install.command({deps_mode = deps_mode}, url)
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua
index d03de1c6..2cad3df2 100644
--- a/src/luarocks/fetch.lua
+++ b/src/luarocks/fetch.lua
@@ -6,7 +6,7 @@ local fs = require("luarocks.fs")
6local dir = require("luarocks.dir") 6local dir = require("luarocks.dir")
7local type_check = require("luarocks.type_check") 7local type_check = require("luarocks.type_check")
8local path = require("luarocks.path") 8local path = require("luarocks.path")
9local deps = require("luarocks.deps") 9local vers = require("luarocks.vers")
10local persist = require("luarocks.persist") 10local persist = require("luarocks.persist")
11local util = require("luarocks.util") 11local util = require("luarocks.util")
12local cfg = require("luarocks.core.cfg") 12local cfg = require("luarocks.core.cfg")
@@ -197,7 +197,7 @@ function fetch.load_local_rockspec(filename, quick)
197 local globals = err 197 local globals = err
198 198
199 if rockspec.rockspec_format then 199 if rockspec.rockspec_format then
200 if deps.compare_versions(rockspec.rockspec_format, type_check.rockspec_format) then 200 if vers.compare_versions(rockspec.rockspec_format, type_check.rockspec_format) then
201 return nil, "Rockspec format "..rockspec.rockspec_format.." is not supported, please upgrade LuaRocks." 201 return nil, "Rockspec format "..rockspec.rockspec_format.." is not supported, please upgrade LuaRocks."
202 end 202 end
203 end 203 end
@@ -209,7 +209,7 @@ function fetch.load_local_rockspec(filename, quick)
209 end 209 end
210 end 210 end
211 211
212 rockspec.format_is_at_least = deps.format_is_at_least 212 rockspec.format_is_at_least = vers.format_is_at_least
213 213
214 util.platform_overrides(rockspec.build) 214 util.platform_overrides(rockspec.build)
215 util.platform_overrides(rockspec.dependencies) 215 util.platform_overrides(rockspec.dependencies)
@@ -260,7 +260,7 @@ function fetch.load_local_rockspec(filename, quick)
260 260
261 if rockspec.dependencies then 261 if rockspec.dependencies then
262 for i = 1, #rockspec.dependencies do 262 for i = 1, #rockspec.dependencies do
263 local parsed, err = deps.parse_dep(rockspec.dependencies[i]) 263 local parsed, err = vers.parse_dep(rockspec.dependencies[i])
264 if not parsed then 264 if not parsed then
265 return nil, "Parse error processing dependency '"..rockspec.dependencies[i].."': "..tostring(err) 265 return nil, "Parse error processing dependency '"..rockspec.dependencies[i].."': "..tostring(err)
266 end 266 end
diff --git a/src/luarocks/fetch/git.lua b/src/luarocks/fetch/git.lua
index 72da4974..edc11762 100644
--- a/src/luarocks/fetch/git.lua
+++ b/src/luarocks/fetch/git.lua
@@ -6,19 +6,19 @@ local unpack = unpack or table.unpack
6 6
7local fs = require("luarocks.fs") 7local fs = require("luarocks.fs")
8local dir = require("luarocks.dir") 8local dir = require("luarocks.dir")
9local deps = require("luarocks.deps") 9local vers = require("luarocks.vers")
10local util = require("luarocks.util") 10local util = require("luarocks.util")
11 11
12local cached_git_version 12local cached_git_version
13 13
14--- Get git version. 14--- Get git version.
15-- @param git_cmd string: name of git command. 15-- @param git_cmd string: name of git command.
16-- @return table: git version as returned by luarocks.deps.parse_version. 16-- @return table: git version as returned by luarocks.vers.parse_version.
17local function git_version(git_cmd) 17local function git_version(git_cmd)
18 if not cached_git_version then 18 if not cached_git_version then
19 local version_line = io.popen(fs.Q(git_cmd)..' --version'):read() 19 local version_line = io.popen(fs.Q(git_cmd)..' --version'):read()
20 local version_string = version_line:match('%d-%.%d+%.?%d*') 20 local version_string = version_line:match('%d-%.%d+%.?%d*')
21 cached_git_version = deps.parse_version(version_string) 21 cached_git_version = vers.parse_version(version_string)
22 end 22 end
23 23
24 return cached_git_version 24 return cached_git_version
@@ -29,7 +29,7 @@ end
29-- @param version string: required version. 29-- @param version string: required version.
30-- @return boolean: true if git matches version or is newer, false otherwise. 30-- @return boolean: true if git matches version or is newer, false otherwise.
31local function git_is_at_least(git_cmd, version) 31local function git_is_at_least(git_cmd, version)
32 return git_version(git_cmd) >= deps.parse_version(version) 32 return git_version(git_cmd) >= vers.parse_version(version)
33end 33end
34 34
35--- Git >= 1.7.10 can clone a branch **or tag**, < 1.7.10 by branch only. We 35--- Git >= 1.7.10 can clone a branch **or tag**, < 1.7.10 by branch only. We
diff --git a/src/luarocks/index.lua b/src/luarocks/index.lua
index 468f5cf8..80371151 100644
--- a/src/luarocks/index.lua
+++ b/src/luarocks/index.lua
@@ -4,7 +4,7 @@ local index = {}
4 4
5local util = require("luarocks.util") 5local util = require("luarocks.util")
6local fs = require("luarocks.fs") 6local fs = require("luarocks.fs")
7local deps = require("luarocks.deps") 7local vers = require("luarocks.vers")
8local persist = require("luarocks.persist") 8local persist = require("luarocks.persist")
9local dir = require("luarocks.dir") 9local dir = require("luarocks.dir")
10local manif = require("luarocks.manif") 10local manif = require("luarocks.manif")
@@ -134,7 +134,7 @@ function index.make_index(repo)
134 for package, version_list in util.sortedpairs(manifest.repository) do 134 for package, version_list in util.sortedpairs(manifest.repository) do
135 local latest_rockspec = nil 135 local latest_rockspec = nil
136 local output = index_package_begin 136 local output = index_package_begin
137 for version, data in util.sortedpairs(version_list, deps.compare_versions) do 137 for version, data in util.sortedpairs(version_list, vers.compare_versions) do
138 local versions = {} 138 local versions = {}
139 output = output..version..':&nbsp;' 139 output = output..version..':&nbsp;'
140 table.sort(data, function(a,b) return a.arch < b.arch end) 140 table.sort(data, function(a,b) return a.arch < b.arch end)
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua
index b8072110..a41cec58 100644
--- a/src/luarocks/loader.lua
+++ b/src/luarocks/loader.lua
@@ -20,7 +20,7 @@ cfg.init_package_paths()
20 20
21local path = require("luarocks.core.path") 21local path = require("luarocks.core.path")
22local manif = require("luarocks.core.manif") 22local manif = require("luarocks.core.manif")
23local deps = require("luarocks.core.deps") 23local vers = require("luarocks.core.vers")
24local util = require("luarocks.core.util") 24local util = require("luarocks.core.util")
25local require = nil 25local require = nil
26-------------------------------------------------------------------------------- 26--------------------------------------------------------------------------------
@@ -112,8 +112,8 @@ function loader.add_context(name, version)
112 for _, tree in ipairs(loader.rocks_trees) do 112 for _, tree in ipairs(loader.rocks_trees) do
113 local entries = tree.manifest.repository[pkg] 113 local entries = tree.manifest.repository[pkg]
114 if entries then 114 if entries then
115 for version, pkgs in util.sortedpairs(entries, deps.compare_versions) do 115 for version, pkgs in util.sortedpairs(entries, vers.compare_versions) do
116 if (not constraints) or deps.match_constraints(deps.parse_version(version), constraints) then 116 if (not constraints) or vers.match_constraints(vers.parse_version(version), constraints) then
117 loader.add_context(pkg, version) 117 loader.add_context(pkg, version)
118 end 118 end
119 end 119 end
@@ -190,7 +190,7 @@ local function select_module(module, filter_file_name)
190 if loader.context[name] == version then 190 if loader.context[name] == version then
191 return name, version, file_name 191 return name, version, file_name
192 end 192 end
193 version = deps.parse_version(version) 193 version = vers.parse_version(version)
194 table.insert(providers, {name = name, version = version, module_name = file_name, tree = tree}) 194 table.insert(providers, {name = name, version = version, module_name = file_name, tree = tree})
195 end 195 end
196 end 196 end
diff --git a/src/luarocks/manif/writer.lua b/src/luarocks/manif/writer.lua
index 5ab3917b..0a4a1a96 100644
--- a/src/luarocks/manif/writer.lua
+++ b/src/luarocks/manif/writer.lua
@@ -5,6 +5,7 @@ local cfg = require("luarocks.core.cfg")
5local search = require("luarocks.search") 5local search = require("luarocks.search")
6local repos = require("luarocks.repos") 6local repos = require("luarocks.repos")
7local deps = require("luarocks.deps") 7local deps = require("luarocks.deps")
8local vers = require("luarocks.vers")
8local fs = require("luarocks.fs") 9local fs = require("luarocks.fs")
9local util = require("luarocks.util") 10local util = require("luarocks.util")
10local dir = require("luarocks.dir") 11local dir = require("luarocks.dir")
@@ -109,7 +110,7 @@ local function sort_pkgs(a, b)
109 local na, va = a:match("(.*)/(.*)$") 110 local na, va = a:match("(.*)/(.*)$")
110 local nb, vb = b:match("(.*)/(.*)$") 111 local nb, vb = b:match("(.*)/(.*)$")
111 112
112 return (na == nb) and deps.compare_versions(va, vb) or na < nb 113 return (na == nb) and vers.compare_versions(va, vb) or na < nb
113end 114end
114 115
115--- Sort items of a package matching table by version number (higher versions first). 116--- Sort items of a package matching table by version number (higher versions first).
@@ -151,7 +152,7 @@ local function filter_by_lua_version(manifest, lua_version, repodir, cache)
151 assert((not cache) or type(cache) == "table") 152 assert((not cache) or type(cache) == "table")
152 153
153 cache = cache or {} 154 cache = cache or {}
154 lua_version = deps.parse_version(lua_version) 155 lua_version = vers.parse_version(lua_version)
155 for pkg, versions in pairs(manifest.repository) do 156 for pkg, versions in pairs(manifest.repository) do
156 local to_remove = {} 157 local to_remove = {}
157 for version, repositories in pairs(versions) do 158 for version, repositories in pairs(versions) do
@@ -166,7 +167,7 @@ local function filter_by_lua_version(manifest, lua_version, repodir, cache)
166 cache[pathname] = rockspec 167 cache[pathname] = rockspec
167 for _, dep in ipairs(rockspec.dependencies) do 168 for _, dep in ipairs(rockspec.dependencies) do
168 if dep.name == "lua" then 169 if dep.name == "lua" then
169 if not deps.match_constraints(lua_version, dep.constraints) then 170 if not vers.match_constraints(lua_version, dep.constraints) then
170 table.insert(to_remove, version) 171 table.insert(to_remove, version)
171 end 172 end
172 break 173 break
@@ -423,7 +424,7 @@ function writer.check_dependencies(repo, deps_mode)
423 end 424 end
424 425
425 for name, versions in util.sortedpairs(manifest.repository) do 426 for name, versions in util.sortedpairs(manifest.repository) do
426 for version, version_entries in util.sortedpairs(versions, deps.compare_versions) do 427 for version, version_entries in util.sortedpairs(versions, vers.compare_versions) do
427 for _, entry in ipairs(version_entries) do 428 for _, entry in ipairs(version_entries) do
428 if entry.arch == "installed" then 429 if entry.arch == "installed" then
429 if manifest.dependencies[name] and manifest.dependencies[name][version] then 430 if manifest.dependencies[name] and manifest.dependencies[name][version] then
diff --git a/src/luarocks/repos.lua b/src/luarocks/repos.lua
index 5d5dedd6..14c26313 100644
--- a/src/luarocks/repos.lua
+++ b/src/luarocks/repos.lua
@@ -8,7 +8,7 @@ local cfg = require("luarocks.core.cfg")
8local util = require("luarocks.util") 8local util = require("luarocks.util")
9local dir = require("luarocks.dir") 9local dir = require("luarocks.dir")
10local manif = require("luarocks.manif") 10local manif = require("luarocks.manif")
11local deps = require("luarocks.deps") 11local vers = require("luarocks.vers")
12 12
13-- Tree of files installed by a package are stored 13-- Tree of files installed by a package are stored
14-- in its rock manifest. Some of these files have to 14-- in its rock manifest. Some of these files have to
@@ -246,7 +246,7 @@ local function prepare_target(name, version, deploy_type, file_path, suffix)
246 246
247 if not cur_name then 247 if not cur_name then
248 return non_versioned 248 return non_versioned
249 elseif name < cur_name or (name == cur_name and deps.compare_versions(version, cur_version)) then 249 elseif name < cur_name or (name == cur_name and vers.compare_versions(version, cur_version)) then
250 -- New version has priority. Move currently provided version back using versioned name. 250 -- New version has priority. Move currently provided version back using versioned name.
251 local cur_deploy_type, cur_file_path = manif.get_providing_file(cur_name, cur_version, item_type, item_name) 251 local cur_deploy_type, cur_file_path = manif.get_providing_file(cur_name, cur_version, item_type, item_name)
252 local cur_non_versioned, cur_versioned = get_deploy_paths(cur_name, cur_version, cur_deploy_type, cur_file_path) 252 local cur_non_versioned, cur_versioned = get_deploy_paths(cur_name, cur_version, cur_deploy_type, cur_file_path)
diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua
index c59f9534..35010c2b 100644
--- a/src/luarocks/search.lua
+++ b/src/luarocks/search.lua
@@ -3,7 +3,7 @@ local search = {}
3local dir = require("luarocks.dir") 3local dir = require("luarocks.dir")
4local path = require("luarocks.path") 4local path = require("luarocks.path")
5local manif = require("luarocks.manif") 5local manif = require("luarocks.manif")
6local deps = require("luarocks.deps") 6local vers = require("luarocks.vers")
7local cfg = require("luarocks.core.cfg") 7local cfg = require("luarocks.core.cfg")
8local util = require("luarocks.util") 8local util = require("luarocks.util")
9 9
@@ -92,7 +92,7 @@ end
92local function store_if_match(results, repo, name, version, arch, query) 92local function store_if_match(results, repo, name, version, arch, query)
93 if match_name(query, name) then 93 if match_name(query, name) then
94 if query.arch[arch] or query.arch["any"] then 94 if query.arch[arch] or query.arch["any"] then
95 if deps.match_constraints(deps.parse_version(version), query.constraints) then 95 if vers.match_constraints(vers.parse_version(version), query.constraints) then
96 search.store_result(results, name, version, arch, repo) 96 search.store_result(results, name, version, arch, repo)
97 end 97 end
98 end 98 end
@@ -229,7 +229,7 @@ function search.make_query(name, version)
229 constraints = {} 229 constraints = {}
230 } 230 }
231 if version then 231 if version then
232 table.insert(query.constraints, { op = "==", version = deps.parse_version(version)}) 232 table.insert(query.constraints, { op = "==", version = vers.parse_version(version)})
233 end 233 end
234 return query 234 return query
235end 235end
@@ -246,7 +246,7 @@ local function pick_latest_version(name, versions)
246 246
247 local vtables = {} 247 local vtables = {}
248 for v, _ in pairs(versions) do 248 for v, _ in pairs(versions) do
249 table.insert(vtables, deps.parse_version(v)) 249 table.insert(vtables, vers.parse_version(v))
250 end 250 end
251 table.sort(vtables) 251 table.sort(vtables)
252 local version = vtables[#vtables].string 252 local version = vtables[#vtables].string
@@ -339,7 +339,7 @@ function search.print_results(results, porcelain)
339 if not porcelain then 339 if not porcelain then
340 util.printout(package) 340 util.printout(package)
341 end 341 end
342 for version, repos in util.sortedpairs(versions, deps.compare_versions) do 342 for version, repos in util.sortedpairs(versions, vers.compare_versions) do
343 for _, repo in ipairs(repos) do 343 for _, repo in ipairs(repos) do
344 repo.repo = dir.normalize(repo.repo) 344 repo.repo = dir.normalize(repo.repo)
345 if porcelain then 345 if porcelain then
@@ -402,7 +402,7 @@ function search.pick_installed_rock(name, version, given_tree)
402 local package, versions = util.sortedpairs(results)() 402 local package, versions = util.sortedpairs(results)()
403 --question: what do we do about multiple versions? This should 403 --question: what do we do about multiple versions? This should
404 --give us the latest version on the last repo (which is usually the global one) 404 --give us the latest version on the last repo (which is usually the global one)
405 for vs, repositories in util.sortedpairs(versions, deps.compare_versions) do 405 for vs, repositories in util.sortedpairs(versions, vers.compare_versions) do
406 if not version then version = vs end 406 if not version then version = vs end
407 for _, rp in ipairs(repositories) do repo_url = rp.repo end 407 for _, rp in ipairs(repositories) do repo_url = rp.repo end
408 end 408 end
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua
index b23f4fab..2c4724f4 100644
--- a/src/luarocks/util.lua
+++ b/src/luarocks/util.lua
@@ -387,7 +387,7 @@ local function collect_rockspecs(versions, paths, unnamed_paths, subdir)
387 local fs = require("luarocks.fs") 387 local fs = require("luarocks.fs")
388 local dir = require("luarocks.dir") 388 local dir = require("luarocks.dir")
389 local path = require("luarocks.path") 389 local path = require("luarocks.path")
390 local deps = require("luarocks.deps") 390 local vers = require("luarocks.vers")
391 391
392 if fs.is_dir(subdir) then 392 if fs.is_dir(subdir) then
393 for file in fs.dir(subdir) do 393 for file in fs.dir(subdir) do
@@ -397,7 +397,7 @@ local function collect_rockspecs(versions, paths, unnamed_paths, subdir)
397 local rock, version = path.parse_name(file) 397 local rock, version = path.parse_name(file)
398 398
399 if rock then 399 if rock then
400 if not versions[rock] or deps.compare_versions(version, versions[rock]) then 400 if not versions[rock] or vers.compare_versions(version, versions[rock]) then
401 versions[rock] = version 401 versions[rock] = version
402 paths[rock] = file 402 paths[rock] = file
403 end 403 end
diff --git a/src/luarocks/vers.lua b/src/luarocks/vers.lua
new file mode 100644
index 00000000..6ce5d738
--- /dev/null
+++ b/src/luarocks/vers.lua
@@ -0,0 +1,138 @@
1
2--- Dependency format handling functions.
3-- Dependencies are represented in LuaRocks through strings with
4-- a package name followed by a comma-separated list of constraints.
5-- Each constraint consists of an operator and a version number.
6-- In this string format, version numbers are represented as
7-- naturally as possible, like they are used by upstream projects
8-- (e.g. "2.0beta3"). Internally, LuaRocks converts them to a purely
9-- numeric representation, allowing comparison following some
10-- "common sense" heuristics. The precise specification of the
11-- comparison criteria is the source code of this module.
12local vers = {}
13setmetatable(vers, { __index = require("luarocks.core.vers") })
14
15--- Check if rockspec format version satisfies version requirement.
16-- @param rockspec table: The rockspec table.
17-- @param version string: required version.
18-- @return boolean: true if rockspec format matches version or is newer, false otherwise.
19function vers.format_is_at_least(rockspec, version)
20 local rockspec_format = rockspec.rockspec_format or "1.0"
21 return vers.parse_version(rockspec_format) >= vers.parse_version(version)
22end
23
24local operators = {
25 ["=="] = "==",
26 ["~="] = "~=",
27 [">"] = ">",
28 ["<"] = "<",
29 [">="] = ">=",
30 ["<="] = "<=",
31 ["~>"] = "~>",
32 -- plus some convenience translations
33 [""] = "==",
34 ["="] = "==",
35 ["!="] = "~="
36}
37
38--- Consumes a constraint from a string, converting it to table format.
39-- For example, a string ">= 1.0, > 2.0" is converted to a table in the
40-- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned
41-- back to the caller.
42-- @param input string: A list of constraints in string format.
43-- @return (table, string) or nil: A table representing the same
44-- constraints and the string with the unused input, or nil if the
45-- input string is invalid.
46local function parse_constraint(input)
47 assert(type(input) == "string")
48
49 local no_upgrade, op, version, rest = input:match("^(@?)([<>=~!]*)%s*([%w%.%_%-]+)[%s,]*(.*)")
50 local _op = operators[op]
51 version = vers.parse_version(version)
52 if not _op then
53 return nil, "Encountered bad constraint operator: '"..tostring(op).."' in '"..input.."'"
54 end
55 if not version then
56 return nil, "Could not parse version from constraint: '"..input.."'"
57 end
58 return { op = _op, version = version, no_upgrade = no_upgrade=="@" and true or nil }, rest
59end
60
61--- Convert a list of constraints from string to table format.
62-- For example, a string ">= 1.0, < 2.0" is converted to a table in the format
63-- {{op = ">=", version={1,0}}, {op = "<", version={2,0}}}.
64-- Version tables use a metatable allowing later comparison through
65-- relational operators.
66-- @param input string: A list of constraints in string format.
67-- @return table or nil: A table representing the same constraints,
68-- or nil if the input string is invalid.
69function vers.parse_constraints(input)
70 assert(type(input) == "string")
71
72 local constraints, oinput, constraint = {}, input
73 while #input > 0 do
74 constraint, input = parse_constraint(input)
75 if constraint then
76 table.insert(constraints, constraint)
77 else
78 return nil, "Failed to parse constraint '"..tostring(oinput).."' with error: ".. input
79 end
80 end
81 return constraints
82end
83
84--- Convert a dependency from string to table format.
85-- For example, a string "foo >= 1.0, < 2.0"
86-- is converted to a table in the format
87-- {name = "foo", constraints = {{op = ">=", version={1,0}},
88-- {op = "<", version={2,0}}}}. Version tables use a metatable
89-- allowing later comparison through relational operators.
90-- @param dep string: A dependency in string format
91-- as entered in rockspec files.
92-- @return table or nil: A table representing the same dependency relation,
93-- or nil if the input string is invalid.
94function vers.parse_dep(dep)
95 assert(type(dep) == "string")
96
97 local name, rest = dep:match("^%s*([a-zA-Z0-9][a-zA-Z0-9%.%-%_]*)%s*(.*)")
98 if not name then return nil, "failed to extract dependency name from '"..tostring(dep).."'" end
99 local constraints, err = vers.parse_constraints(rest)
100 if not constraints then return nil, err end
101 return { name = name, constraints = constraints }
102end
103
104--- Convert a version table to a string.
105-- @param v table: The version table
106-- @param internal boolean or nil: Whether to display versions in their
107-- internal representation format or how they were specified.
108-- @return string: The dependency information pretty-printed as a string.
109function vers.show_version(v, internal)
110 assert(type(v) == "table")
111 assert(type(internal) == "boolean" or not internal)
112
113 return (internal
114 and table.concat(v, ":")..(v.revision and tostring(v.revision) or "")
115 or v.string)
116end
117
118--- Convert a dependency in table format to a string.
119-- @param dep table: The dependency in table format
120-- @param internal boolean or nil: Whether to display versions in their
121-- internal representation format or how they were specified.
122-- @return string: The dependency information pretty-printed as a string.
123function vers.show_dep(dep, internal)
124 assert(type(dep) == "table")
125 assert(type(internal) == "boolean" or not internal)
126
127 if #dep.constraints > 0 then
128 local pretty = {}
129 for _, c in ipairs(dep.constraints) do
130 table.insert(pretty, c.op .. " " .. vers.show_version(c.version, internal))
131 end
132 return dep.name.." "..table.concat(pretty, ", ")
133 else
134 return dep.name
135 end
136end
137
138return vers