aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/build.lua30
-rw-r--r--src/luarocks/build/cmake.lua22
-rw-r--r--src/luarocks/cfg.lua12
-rw-r--r--src/luarocks/deps.lua34
-rw-r--r--src/luarocks/fetch.lua10
-rw-r--r--src/luarocks/fetch/git.lua57
-rw-r--r--src/luarocks/tools/tar.lua6
-rw-r--r--src/luarocks/type_check.lua2
-rw-r--r--src/luarocks/util.lua14
9 files changed, 157 insertions, 30 deletions
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua
index 68f20264..dd0b4441 100644
--- a/src/luarocks/build.lua
+++ b/src/luarocks/build.lua
@@ -149,6 +149,31 @@ local function install_default_docs(name, version)
149 end 149 end
150end 150end
151 151
152local function check_macosx_deployment_target(rockspec)
153 local target = rockspec.build.macosx_deployment_target
154 local function minor(version)
155 return tonumber(version and version:match("^[^.]+%.([^.]+)"))
156 end
157 local function patch_variable(var, target)
158 if rockspec.variables[var]:match("MACOSX_DEPLOYMENT_TARGET") then
159 rockspec.variables[var] = (rockspec.variables[var]):gsub("MACOSX_DEPLOYMENT_TARGET=[^ ]*", "MACOSX_DEPLOYMENT_TARGET="..target)
160 else
161 rockspec.variables[var] = "env MACOSX_DEPLOYMENT_TARGET="..target.." "..rockspec.variables[var]
162 end
163 end
164 if cfg.platforms.macosx and deps.format_is_at_least(rockspec, "3.0") and target then
165 local version = util.popen_read("sw_vers -productVersion")
166 local versionminor = minor(version)
167 local targetminor = minor(target)
168 if targetminor > versionminor then
169 return nil, ("This rock requires Mac OSX 10.%d, and you are running 10.%d."):format(targetminor, versionminor)
170 end
171 patch_variable("CC", target)
172 patch_variable("LD", target)
173 end
174 return true
175end
176
152--- Build and install a rock given a rockspec. 177--- Build and install a rock given a rockspec.
153-- @param rockspec_file string: local or remote filename of a rockspec. 178-- @param rockspec_file string: local or remote filename of a rockspec.
154-- @param need_to_fetch boolean: true if sources need to be fetched, 179-- @param need_to_fetch boolean: true if sources need to be fetched,
@@ -244,6 +269,11 @@ function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_m
244 end 269 end
245 end 270 end
246 271
272 ok, err = check_macosx_deployment_target(rockspec)
273 if not ok then
274 return nil, err
275 end
276
247 if build_spec.type ~= "none" then 277 if build_spec.type ~= "none" then
248 278
249 -- Temporary compatibility 279 -- Temporary compatibility
diff --git a/src/luarocks/build/cmake.lua b/src/luarocks/build/cmake.lua
index 7b16fa51..34f6ada0 100644
--- a/src/luarocks/build/cmake.lua
+++ b/src/luarocks/build/cmake.lua
@@ -6,6 +6,7 @@ local cmake = {}
6local fs = require("luarocks.fs") 6local fs = require("luarocks.fs")
7local util = require("luarocks.util") 7local util = require("luarocks.util")
8local cfg = require("luarocks.cfg") 8local cfg = require("luarocks.cfg")
9local deps = require("luarocks.deps")
9 10
10--- Driver function for the "cmake" build back-end. 11--- Driver function for the "cmake" build back-end.
11-- @param rockspec table: the loaded rockspec. 12-- @param rockspec table: the loaded rockspec.
@@ -53,13 +54,26 @@ function cmake.run(rockspec)
53 return nil, "Failed cmake." 54 return nil, "Failed cmake."
54 end 55 end
55 56
56 if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --config Release") then 57 local do_build, do_install
57 return nil, "Failed building." 58 if deps.format_is_at_least(rockspec, "3.0") then
59 do_build = (build.build_pass == nil) and true or build.build_pass
60 do_install = (build.install_pass == nil) and true or build.install_pass
61 else
62 do_build = true
63 do_install = true
58 end 64 end
59 65
60 if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --target install --config Release") then 66 if do_build then
61 return nil, "Failed installing." 67 if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --config Release") then
68 return nil, "Failed building."
69 end
62 end 70 end
71 if do_install then
72 if not fs.execute_string(rockspec.variables.CMAKE.." --build build.luarocks --target install --config Release") then
73 return nil, "Failed installing."
74 end
75 end
76
63 return true 77 return true
64end 78end
65 79
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua
index 898b0854..aa298b07 100644
--- a/src/luarocks/cfg.lua
+++ b/src/luarocks/cfg.lua
@@ -76,8 +76,8 @@ end
76-- so that this detection does not run every time. When it is 76-- so that this detection does not run every time. When it is
77-- performed, we use the Unix way to identify the system, 77-- performed, we use the Unix way to identify the system,
78-- even on Windows (assuming UnxUtils or Cygwin). 78-- even on Windows (assuming UnxUtils or Cygwin).
79local system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") 79local system = site_config.LUAROCKS_UNAME_S or util.popen_read("uname -s")
80local proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") 80local proc = site_config.LUAROCKS_UNAME_M or util.popen_read("uname -m")
81if proc:match("i[%d]86") then 81if proc:match("i[%d]86") then
82 cfg.target_cpu = "x86" 82 cfg.target_cpu = "x86"
83elseif proc:match("amd64") or proc:match("x86_64") then 83elseif proc:match("amd64") or proc:match("x86_64") then
@@ -398,7 +398,8 @@ local defaults = {
398 include = "include" 398 include = "include"
399 }, 399 },
400 400
401 rocks_provided = {} 401 rocks_provided = {},
402 rocks_provided_3_0 = {},
402} 403}
403 404
404if cfg.platforms.windows then 405if cfg.platforms.windows then
@@ -564,7 +565,7 @@ if cfg.platforms.macosx then
564 defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" 565 defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load"
565 defaults.variables.STAT = "/usr/bin/stat" 566 defaults.variables.STAT = "/usr/bin/stat"
566 defaults.variables.STATFLAG = "-f '%A'" 567 defaults.variables.STATFLAG = "-f '%A'"
567 local version = io.popen("sw_vers -productVersion"):read("*l") 568 local version = util.popen_read("sw_vers -productVersion")
568 version = tonumber(version and version:match("^[^.]+%.([^.]+)")) or 3 569 version = tonumber(version and version:match("^[^.]+%.([^.]+)")) or 3
569 if version >= 10 then 570 if version >= 10 then
570 version = 8 571 version = 8
@@ -623,8 +624,8 @@ end
623if package.loaded.jit then 624if package.loaded.jit then
624 -- LuaJIT 625 -- LuaJIT
625 local lj_version = package.loaded.jit.version:match("LuaJIT (.*)"):gsub("%-","") 626 local lj_version = package.loaded.jit.version:match("LuaJIT (.*)"):gsub("%-","")
626 --defaults.rocks_provided["luajit"] = lj_version.."-1"
627 defaults.rocks_provided["luabitop"] = lj_version.."-1" 627 defaults.rocks_provided["luabitop"] = lj_version.."-1"
628 defaults.rocks_provided_3_0["luajit"] = lj_version.."-1"
628end 629end
629 630
630-- Use defaults: 631-- Use defaults:
@@ -641,6 +642,7 @@ for _, entry in ipairs({"variables", "rocks_provided"}) do
641 end 642 end
642 end 643 end
643end 644end
645setmetatable(defaults.rocks_provided_3_0, { __index = cfg.rocks_provided })
644 646
645-- For values not set in the config file, use values from the 'defaults' table. 647-- For values not set in the config file, use values from the 'defaults' table.
646local cfg_mt = { 648local cfg_mt = {
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua
index 812e6d18..2a458b23 100644
--- a/src/luarocks/deps.lua
+++ b/src/luarocks/deps.lua
@@ -159,6 +159,15 @@ function deps.compare_versions(a, b)
159 return deps.parse_version(a) > deps.parse_version(b) 159 return deps.parse_version(a) > deps.parse_version(b)
160end 160end
161 161
162--- Check if rockspec format version satisfies version requirement.
163-- @param rockspec table: The rockspec table.
164-- @param version string: required version.
165-- @return boolean: true if rockspec format matches version or is newer, false otherwise.
166function deps.format_is_at_least(rockspec, version)
167 local rockspec_format = rockspec.rockspec_format or "1.0"
168 return deps.parse_version(rockspec_format) >= deps.parse_version(version)
169end
170
162--- Consumes a constraint from a string, converting it to table format. 171--- Consumes a constraint from a string, converting it to table format.
163-- For example, a string ">= 1.0, > 2.0" is converted to a table in the 172-- For example, a string ">= 1.0, > 2.0" is converted to a table in the
164-- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned 173-- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned
@@ -322,16 +331,20 @@ end
322-- @param dep table: A dependency parsed in table format. 331-- @param dep table: A dependency parsed in table format.
323-- @param blacklist table: Versions that can't be accepted. Table where keys 332-- @param blacklist table: Versions that can't be accepted. Table where keys
324-- are program versions and values are 'true'. 333-- are program versions and values are 'true'.
334-- @param provided table: A table of auto-dependencies provided
335-- by this Lua implementation for the given dependency.
325-- @return table or nil: A table containing fields 'name' and 'version' 336-- @return table or nil: A table containing fields 'name' and 'version'
326-- representing an installed rock which matches the given dependency, 337-- representing an installed rock which matches the given dependency,
327-- or nil if it could not be matched. 338-- or nil if it could not be matched.
328local function match_dep(dep, blacklist, deps_mode) 339local function match_dep(dep, blacklist, deps_mode, rocks_provided)
329 assert(type(dep) == "table") 340 assert(type(dep) == "table")
330 341 assert(type(rocks_provided) == "table")
331 local versions = cfg.rocks_provided[dep.name] 342
332 if cfg.rocks_provided[dep.name] then 343 local versions
344 local provided = rocks_provided[dep.name]
345 if provided then
333 -- provided rocks have higher priority than manifest's rocks 346 -- provided rocks have higher priority than manifest's rocks
334 versions = { cfg.rocks_provided[dep.name] } 347 versions = { provided }
335 else 348 else
336 versions = manif_core.get_versions(dep.name, deps_mode) 349 versions = manif_core.get_versions(dep.name, deps_mode)
337 end 350 end
@@ -383,9 +396,9 @@ function deps.match_deps(rockspec, blacklist, deps_mode)
383 local matched, missing, no_upgrade = {}, {}, {} 396 local matched, missing, no_upgrade = {}, {}, {}
384 397
385 for _, dep in ipairs(rockspec.dependencies) do 398 for _, dep in ipairs(rockspec.dependencies) do
386 local found = match_dep(dep, blacklist and blacklist[dep.name] or nil, deps_mode) 399 local found = match_dep(dep, blacklist and blacklist[dep.name] or nil, deps_mode, rockspec.rocks_provided)
387 if found then 400 if found then
388 if not cfg.rocks_provided[dep.name] then 401 if not rockspec.rocks_provided[dep.name] then
389 matched[dep] = found 402 matched[dep] = found
390 end 403 end
391 else 404 else
@@ -483,7 +496,7 @@ function deps.fulfill_dependencies(rockspec, deps_mode)
483 496
484 for _, dep in pairs(missing) do 497 for _, dep in pairs(missing) do
485 -- Double-check in case dependency was filled during recursion. 498 -- Double-check in case dependency was filled during recursion.
486 if not match_dep(dep, nil, deps_mode) then 499 if not match_dep(dep, nil, deps_mode, rockspec.rocks_provided) then
487 local url, err = search.find_suitable_rock(dep) 500 local url, err = search.find_suitable_rock(dep)
488 if not url then 501 if not url then
489 return nil, "Could not satisfy dependency "..deps.show_dep(dep)..": "..err 502 return nil, "Could not satisfy dependency "..deps.show_dep(dep)..": "..err
@@ -718,7 +731,10 @@ function deps.scan_deps(results, missing, manifest, name, version, deps_mode)
718 end 731 end
719 dependencies_name[version] = rockspec.dependencies 732 dependencies_name[version] = rockspec.dependencies
720 else 733 else
721 rockspec = { dependencies = deplist } 734 rockspec = {
735 dependencies = deplist,
736 rocks_provided = setmetatable({}, { __index = cfg.rocks_provided_3_0 })
737 }
722 end 738 end
723 local matched, failures = deps.match_deps(rockspec, nil, deps_mode) 739 local matched, failures = deps.match_deps(rockspec, nil, deps_mode)
724 results[name] = results 740 results[name] = results
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua
index 2c028771..d8fc84cc 100644
--- a/src/luarocks/fetch.lua
+++ b/src/luarocks/fetch.lua
@@ -247,8 +247,16 @@ function fetch.load_local_rockspec(filename, quick)
247 local base = fetch.url_to_base_dir(filebase) 247 local base = fetch.url_to_base_dir(filebase)
248 rockspec.source.dir = rockspec.source.dir 248 rockspec.source.dir = rockspec.source.dir
249 or rockspec.source.module 249 or rockspec.source.module
250 or ((filebase:match("%.lua$") or filebase:match("%.c$")) and ".") 250 or ( (filebase:match("%.lua$") or filebase:match("%.c$"))
251 and (deps.format_is_at_least(rockspec, "3.0")
252 and (fetch.is_basic_protocol(protocol) and "." or base)
253 or ".") )
251 or base 254 or base
255
256 rockspec.rocks_provided = (deps.format_is_at_least(rockspec, "3.0")
257 and cfg.rocks_provided_3_0
258 or cfg.rocks_provided)
259
252 if rockspec.dependencies then 260 if rockspec.dependencies then
253 for i = 1, #rockspec.dependencies do 261 for i = 1, #rockspec.dependencies do
254 local parsed, err = deps.parse_dep(rockspec.dependencies[i]) 262 local parsed, err = deps.parse_dep(rockspec.dependencies[i])
diff --git a/src/luarocks/fetch/git.lua b/src/luarocks/fetch/git.lua
index a635f190..aa735b3f 100644
--- a/src/luarocks/fetch/git.lua
+++ b/src/luarocks/fetch/git.lua
@@ -7,20 +7,48 @@ local unpack = unpack or table.unpack
7 7
8local fs = require("luarocks.fs") 8local fs = require("luarocks.fs")
9local dir = require("luarocks.dir") 9local dir = require("luarocks.dir")
10local deps = require("luarocks.deps")
10local util = require("luarocks.util") 11local util = require("luarocks.util")
11 12
13local cached_git_version
14
15--- Get git version.
16-- @param git_cmd string: name of git command.
17-- @return table: git version as returned by luarocks.deps.parse_version.
18local function git_version(git_cmd)
19 if not cached_git_version then
20 local version_line = io.popen(fs.Q(git_cmd)..' --version'):read()
21 local version_string = version_line:match('%d-%.%d+%.?%d*')
22 cached_git_version = deps.parse_version(version_string)
23 end
24
25 return cached_git_version
26end
27
28--- Check if git satisfies version requirement.
29-- @param git_cmd string: name of git command.
30-- @param version string: required version.
31-- @return boolean: true if git matches version or is newer, false otherwise.
32local function git_is_at_least(git_cmd, version)
33 return git_version(git_cmd) >= deps.parse_version(version)
34end
35
12--- Git >= 1.7.10 can clone a branch **or tag**, < 1.7.10 by branch only. We 36--- Git >= 1.7.10 can clone a branch **or tag**, < 1.7.10 by branch only. We
13-- need to know this in order to build the appropriate command; if we can't 37-- need to know this in order to build the appropriate command; if we can't
14-- clone by tag then we'll have to issue a subsequent command to check out the 38-- clone by tag then we'll have to issue a subsequent command to check out the
15-- given tag. 39-- given tag.
40-- @param git_cmd string: name of git command.
16-- @return boolean: Whether Git can clone by tag. 41-- @return boolean: Whether Git can clone by tag.
17local function git_can_clone_by_tag(git_cmd) 42local function git_can_clone_by_tag(git_cmd)
18 local version_string = io.popen(fs.Q(git_cmd)..' --version'):read() 43 return git_is_at_least(git_cmd, "1.7.10")
19 local major, minor, tiny = version_string:match('(%d-)%.(%d+)%.?(%d*)') 44end
20 major, minor, tiny = tonumber(major), tonumber(minor), tonumber(tiny) or 0 45
21 local value = major > 1 or (major == 1 and (minor > 7 or (minor == 7 and tiny >= 10))) 46--- Git >= 1.8.4 can fetch submodules shallowly, saving bandwidth and time for
22 git_can_clone_by_tag = function() return value end 47-- submodules with large history.
23 return value 48-- @param git_cmd string: name of git command.
49-- @return boolean: Whether Git can fetch submodules shallowly.
50local function git_supports_shallow_submodules(git_cmd)
51 return git_is_at_least(git_cmd, "1.8.4")
24end 52end
25 53
26--- Download sources for building a rock, using git. 54--- Download sources for building a rock, using git.
@@ -77,12 +105,25 @@ function git.get_sources(rockspec, extract, dest_dir, depth)
77 ok, err = fs.change_dir(module) 105 ok, err = fs.change_dir(module)
78 if not ok then return nil, err end 106 if not ok then return nil, err end
79 if tag_or_branch and not git_can_clone_by_tag() then 107 if tag_or_branch and not git_can_clone_by_tag() then
80 local checkout_command = {fs.Q(git_cmd), "checkout", tag_or_branch} 108 if not fs.execute(fs.Q(git_cmd), "checkout", tag_or_branch) then
81 if not fs.execute(unpack(checkout_command)) then
82 return nil, 'Failed to check out the "' .. tag_or_branch ..'" tag or branch.' 109 return nil, 'Failed to check out the "' .. tag_or_branch ..'" tag or branch.'
83 end 110 end
84 end 111 end
85 112
113 -- Fetching git submodules is supported only when rockspec format is >= 3.0.
114 if deps.format_is_at_least(rockspec, "3.0") then
115 command = {fs.Q(git_cmd), "submodule", "update", "--init", "--recursive"}
116
117 if git_supports_shallow_submodules(git_cmd) then
118 -- Fetch only the last commit of each submodule.
119 table.insert(command, 5, "--depth=1")
120 end
121
122 if not fs.execute(unpack(command)) then
123 return nil, 'Failed to fetch submodules.'
124 end
125 end
126
86 fs.delete(dir.path(store_dir, module, ".git")) 127 fs.delete(dir.path(store_dir, module, ".git"))
87 fs.delete(dir.path(store_dir, module, ".gitignore")) 128 fs.delete(dir.path(store_dir, module, ".gitignore"))
88 fs.pop_dir() 129 fs.pop_dir()
diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.lua
index b2bd930a..cedcceee 100644
--- a/src/luarocks/tools/tar.lua
+++ b/src/luarocks/tools/tar.lua
@@ -57,10 +57,11 @@ end
57local function read_header_block(block) 57local function read_header_block(block)
58 local header = {} 58 local header = {}
59 header.name = nullterm(block:sub(1,100)) 59 header.name = nullterm(block:sub(1,100))
60 header.mode = nullterm(block:sub(101,108)) 60 header.mode = nullterm(block:sub(101,108)):gsub(" ", "")
61 header.uid = octal_to_number(nullterm(block:sub(109,116))) 61 header.uid = octal_to_number(nullterm(block:sub(109,116)))
62 header.gid = octal_to_number(nullterm(block:sub(117,124))) 62 header.gid = octal_to_number(nullterm(block:sub(117,124)))
63 header.size = octal_to_number(nullterm(block:sub(125,136))) 63 header.size = octal_to_number(nullterm(block:sub(125,136)))
64print("{"..block:sub(125,136).."}", "{"..nullterm(block:sub(125,136)).."}", "{"..octal_to_number(nullterm(block:sub(125,136))).."}", header.size)
64 header.mtime = octal_to_number(nullterm(block:sub(137,148))) 65 header.mtime = octal_to_number(nullterm(block:sub(137,148)))
65 header.chksum = octal_to_number(nullterm(block:sub(149,156))) 66 header.chksum = octal_to_number(nullterm(block:sub(149,156)))
66 header.typeflag = get_typeflag(block:sub(157,157)) 67 header.typeflag = get_typeflag(block:sub(157,157))
@@ -94,13 +95,14 @@ function tar.untar(filename, destdir)
94 local long_name, long_link_name 95 local long_name, long_link_name
95 while true do 96 while true do
96 local block 97 local block
97 repeat 98 repeat
98 block = tar_handle:read(blocksize) 99 block = tar_handle:read(blocksize)
99 until (not block) or checksum_header(block) > 256 100 until (not block) or checksum_header(block) > 256
100 if not block then break end 101 if not block then break end
101 local header, err = read_header_block(block) 102 local header, err = read_header_block(block)
102 if not header then 103 if not header then
103 util.printerr(err) 104 util.printerr(err)
105 return nil, err
104 end 106 end
105 107
106 local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size) 108 local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size)
diff --git a/src/luarocks/type_check.lua b/src/luarocks/type_check.lua
index 65b4fc15..83091a29 100644
--- a/src/luarocks/type_check.lua
+++ b/src/luarocks/type_check.lua
@@ -8,7 +8,7 @@ package.loaded["luarocks.type_check"] = type_check
8local cfg = require("luarocks.cfg") 8local cfg = require("luarocks.cfg")
9local deps = require("luarocks.deps") 9local deps = require("luarocks.deps")
10 10
11type_check.rockspec_format = "1.1" 11type_check.rockspec_format = "3.0"
12 12
13local string_1 = { _type = "string" } 13local string_1 = { _type = "string" }
14local number_1 = { _type = "number" } 14local number_1 = { _type = "number" }
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua
index c06c8354..fc45c9f4 100644
--- a/src/luarocks/util.lua
+++ b/src/luarocks/util.lua
@@ -9,6 +9,20 @@ local util = {}
9 9
10local unpack = unpack or table.unpack 10local unpack = unpack or table.unpack
11 11
12--- Run a process and read a its output.
13-- Equivalent to io.popen(cmd):read("*l"), except that it
14-- closes the fd right away.
15-- @param cmd string: The command to execute
16-- @param spec string: "*l" by default, to read a single line.
17-- May be used to read more, passing, for instance, "*a".
18-- @return string: the output of the program.
19function util.popen_read(cmd, spec)
20 local fd = io.popen(cmd)
21 local out = fd:read(spec or "*l")
22 fd:close()
23 return out
24end
25
12local scheduled_functions = {} 26local scheduled_functions = {}
13local debug = require("debug") 27local debug = require("debug")
14 28