aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhisham <hisham@9ca3f7c1-7366-0410-b1a3-b5c78f85698c>2009-10-11 04:47:08 +0000
committerhisham <hisham@9ca3f7c1-7366-0410-b1a3-b5c78f85698c>2009-10-11 04:47:08 +0000
commit01a0723c9dd08b86ac96b09c08b9ce16cafa2438 (patch)
treefae83a35c1c69b1f9aeb0ef31e54175d249bd320 /src
parent311287db133962862f03f01c02bb6debee429e3c (diff)
downloadluarocks-01a0723c9dd08b86ac96b09c08b9ce16cafa2438.tar.gz
luarocks-01a0723c9dd08b86ac96b09c08b9ce16cafa2438.tar.bz2
luarocks-01a0723c9dd08b86ac96b09c08b9ce16cafa2438.zip
Fix conflict resolution scheme using proper Lua 5.1 mechanism
git-svn-id: http://luarocks.org/svn/luarocks/trunk@76 9ca3f7c1-7366-0410-b1a3-b5c78f85698c
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/loader.lua30
-rw-r--r--src/luarocks/manif.lua35
-rw-r--r--src/luarocks/path.lua14
-rw-r--r--src/luarocks/rep.lua122
-rw-r--r--src/luarocks/require.lua6
5 files changed, 92 insertions, 115 deletions
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua
index 02e46085..f8880a58 100644
--- a/src/luarocks/loader.lua
+++ b/src/luarocks/loader.lua
@@ -89,12 +89,11 @@ local function sort_versions(a,b)
89 return a.version > b.version 89 return a.version > b.version
90end 90end
91 91
92local function call_other_loaders(module, name, version, file) 92local function call_other_loaders(module, name, version, module_name)
93 93
94 local actual_module = file:match(".*/(.*)%.[^.]+$")
95 for i, loader in pairs(package.loaders) do 94 for i, loader in pairs(package.loaders) do
96 if loader ~= luarocks_loader then 95 if loader ~= luarocks_loader then
97 local results = { loader(actual_module) } 96 local results = { loader(module_name) }
98 if type(results[1]) == "function" then 97 if type(results[1]) == "function" then
99 return unpack(results) 98 return unpack(results)
100 end 99 end
@@ -116,23 +115,16 @@ local function pick_module(module)
116 if entries then 115 if entries then
117 for i, entry in ipairs(entries) do 116 for i, entry in ipairs(entries) do
118 local name, version = entry:match("^([^/]*)/(.*)$") 117 local name, version = entry:match("^([^/]*)/(.*)$")
119 local file = tree.manifest.repository[name][version][1].modules[module] 118 local module_name = tree.manifest.repository[name][version][1].modules[module]
120 local deploy_dir 119 if i > 1 then
121 if file:match(cfg.lua_extension.."$") then 120 module_name = path.versioned_name(module_name, "", name, version)
122 deploy_dir = cfg.deploy_lua_dir
123 else
124 deploy_dir = cfg.deploy_bin_dir
125 end
126 if i == 1 then
127 file = deploy_dir.."/"..file
128 else
129 file = path.versioned_name(deploy_dir.."/"..file, name, version)
130 end 121 end
122 module_name = path.path_to_module(module_name)
131 if context[name] == version then 123 if context[name] == version then
132 return name, version, file 124 return name, version, module_name
133 end 125 end
134 version = deps.parse_version(version) 126 version = deps.parse_version(version)
135 table.insert(providers, {name = name, version = version, file = file}) 127 table.insert(providers, {name = name, version = version, module_name = module_name})
136 end 128 end
137 end 129 end
138 end 130 end
@@ -140,7 +132,7 @@ local function pick_module(module)
140 if next(providers) then 132 if next(providers) then
141 table.sort(providers, sort_versions) 133 table.sort(providers, sort_versions)
142 local first = providers[1] 134 local first = providers[1]
143 return first.name, first.version.string, first.file 135 return first.name, first.version.string, first.module_name
144 end 136 end
145end 137end
146 138
@@ -155,12 +147,12 @@ end
155-- in the Lua reference manual for details. 147-- in the Lua reference manual for details.
156 148
157function luarocks_loader(module) 149function luarocks_loader(module)
158 local name, version, file = pick_module(module) 150 local name, version, module_name = pick_module(module)
159 if not name then 151 if not name then
160 return nil, "No LuaRocks module found for "..module 152 return nil, "No LuaRocks module found for "..module
161 else 153 else
162 add_context(name, version) 154 add_context(name, version)
163 return call_other_loaders(module, name, version, file) 155 return call_other_loaders(module, name, version, module_name)
164 end 156 end
165end 157end
166 158
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua
index bdb691ab..6a0d637a 100644
--- a/src/luarocks/manif.lua
+++ b/src/luarocks/manif.lua
@@ -38,7 +38,7 @@ function load_rock_manifest(name, version)
38 if rock_manifest_cache[name_version] then 38 if rock_manifest_cache[name_version] then
39 return rock_manifest_cache[name_version].rock_manifest 39 return rock_manifest_cache[name_version].rock_manifest
40 end 40 end
41 local pathname = dir.rock_manifest_file(name, version) 41 local pathname = path.rock_manifest_file(name, version)
42 local rock_manifest = persist.load_into_table(pathname) 42 local rock_manifest = persist.load_into_table(pathname)
43 if not rock_manifest then return nil end 43 if not rock_manifest then return nil end
44 rock_manifest_cache[name_version] = rock_manifest 44 rock_manifest_cache[name_version] = rock_manifest
@@ -301,17 +301,15 @@ function update_manifest(name, version, repo)
301 return save_table(repo, "manifest", manifest) 301 return save_table(repo, "manifest", manifest)
302end 302end
303 303
304--- Given a path of a deployed file, figure out which rock name and version 304local function find_providers(file, root)
305-- correspond to it in the tree manifest.
306-- @param file string: The full path of a deployed file.
307-- @param root string or nil: A local root dir for a rocks tree. If not given, the default is used.
308-- @return string, string: name and version of the provider rock.
309function find_current_provider(file, root)
310 assert(type(file) == "string") 305 assert(type(file) == "string")
311 assert(type(root) == "string" or not root) 306 assert(type(root) == "string" or not root)
312 root = root or cfg.root_dir 307 root = root or cfg.root_dir
313 308
314 local manifest = manif_core.load_local_manifest(path.rocks_dir(root)) 309 local manifest = manif_core.load_local_manifest(path.rocks_dir(root))
310 if not manifest then
311 return nil, "manifest file is missing. Corrupted local rocks tree?"
312 end
315 local deploy_bin = path.deploy_bin_dir(root) 313 local deploy_bin = path.deploy_bin_dir(root)
316 local deploy_lua = path.deploy_lua_dir(root) 314 local deploy_lua = path.deploy_lua_dir(root)
317 local deploy_lib = path.deploy_lib_dir(root) 315 local deploy_lib = path.deploy_lib_dir(root)
@@ -326,11 +324,34 @@ function find_current_provider(file, root)
326 elseif file:match("^"..deploy_lib) then 324 elseif file:match("^"..deploy_lib) then
327 manifest_tbl = manifest.modules 325 manifest_tbl = manifest.modules
328 key = path.path_to_module(file:sub(#deploy_lib+1)) 326 key = path.path_to_module(file:sub(#deploy_lib+1))
327 else
328 assert(false, "Assertion failed: find_current_provider must operate on a deployed file.")
329 end 329 end
330 330
331 local providers = manifest_tbl[key] 331 local providers = manifest_tbl[key]
332 if not providers then 332 if not providers then
333 return nil, "File "..file.." is not tracked by LuaRocks." 333 return nil, "File "..file.." is not tracked by LuaRocks."
334 end 334 end
335 return providers
336end
337
338--- Given a path of a deployed file, figure out which rock name and version
339-- correspond to it in the tree manifest.
340-- @param file string: The full path of a deployed file.
341-- @param root string or nil: A local root dir for a rocks tree. If not given, the default is used.
342-- @return string, string: name and version of the provider rock.
343function find_current_provider(file, root)
344 local providers, err = find_providers(file, root)
345 if not providers then return nil, err end
335 return providers[1]:match("([^/]*)/([^/]*)") 346 return providers[1]:match("([^/]*)/([^/]*)")
336end 347end
348
349function find_next_provider(file, root)
350 local providers, err = find_providers(file, root)
351 if not providers then return nil, err end
352 if providers[2] then
353 return providers[2]:match("([^/]*)/([^/]*)")
354 else
355 return nil
356 end
357end
diff --git a/src/luarocks/path.lua b/src/luarocks/path.lua
index f2d02ded..8c5aa0da 100644
--- a/src/luarocks/path.lua
+++ b/src/luarocks/path.lua
@@ -263,18 +263,12 @@ function configure_paths(rockspec)
263 rockspec.variables = vars 263 rockspec.variables = vars
264end 264end
265 265
266function versioned_name(file, name, version) 266function versioned_name(file, prefix, name, version)
267 assert(type(file) == "string") 267 assert(type(file) == "string")
268 assert(type(name) == "string") 268 assert(type(name) == "string")
269 assert(type(version) == "string") 269 assert(type(version) == "string")
270 270
271 name = name:gsub("%-", "_") 271 local rest = file:gsub("^"..prefix.."/*", "")
272 version = version:gsub("%-", "_") 272 name_version = (name.."_"..version):gsub("%-", "_"):gsub("%.", "_")
273 return dir.path(dir.dir_name(file), name.."_"..version.."-"..dir.base_name(file)) 273 return dir.path(prefix, name_version.."-"..rest)
274end
275
276function unversioned_name(file)
277 assert(type(file) == "string")
278
279 return dir.path(dir.dir_name(file), dir.base_name(file):match("^[^-]+-(.*)"))
280end 274end
diff --git a/src/luarocks/rep.lua b/src/luarocks/rep.lua
index cabb83ef..8134a678 100644
--- a/src/luarocks/rep.lua
+++ b/src/luarocks/rep.lua
@@ -41,7 +41,7 @@ local function recurse_rock_manifest_tree(file_tree, action)
41 41
42 for file, sub in pairs(tree) do 42 for file, sub in pairs(tree) do
43 if type(sub) == "table" then 43 if type(sub) == "table" then
44 local ok, err = recurse_rock_manifest_tree(sub, parent_path..file.."/", parent_module..file..".", action) 44 local ok, err = do_recurse_rock_manifest_tree(sub, parent_path..file.."/", parent_module..file..".")
45 if not ok then return nil, err end 45 if not ok then return nil, err end
46 else 46 else
47 local ok, err = action(parent_path, parent_module, file) 47 local ok, err = action(parent_path, parent_module, file)
@@ -50,7 +50,7 @@ local function recurse_rock_manifest_tree(file_tree, action)
50 end 50 end
51 return true 51 return true
52 end 52 end
53 return do_recurse_rock_manifest_tree(file_tree, "", "", action) 53 return do_recurse_rock_manifest_tree(file_tree, "", "")
54end 54end
55 55
56local function store_package_data(result, name, sub, prefix) 56local function store_package_data(result, name, sub, prefix)
@@ -69,6 +69,17 @@ local function store_package_data(result, name, sub, prefix)
69 end 69 end
70end 70end
71 71
72local function store_package_data(result, name, file_tree)
73 if not file_tree then return end
74 return recurse_rock_manifest_tree(file_tree,
75 function(parent_path, parent_module, file)
76 local pathname = parent_path..file
77 result[path.path_to_module(pathname)] = pathname
78 return true
79 end
80 )
81end
82
72--- Obtain a list of modules within an installed package. 83--- Obtain a list of modules within an installed package.
73-- @param package string: The package name; for example "luasocket" 84-- @param package string: The package name; for example "luasocket"
74-- @param version string: The exact version number including revision; 85-- @param version string: The exact version number including revision;
@@ -84,16 +95,8 @@ function package_modules(package, version)
84 local result = {} 95 local result = {}
85 local rock_manifest = manif.load_rock_manifest(package, version) 96 local rock_manifest = manif.load_rock_manifest(package, version)
86 97
87 if rock_manifest.lib then 98 store_package_data(result, name, rock_manifest.lib)
88 for name,sub in pairs(rock_manifest.lib) do 99 store_package_data(result, name, rock_manifest.lua)
89 store_package_data(result, name, sub, "", "")
90 end
91 end
92 if rock_manifest.lua then
93 for name,sub in pairs(rock_manifest.lua) do
94 store_package_data(result, name, sub, "", "")
95 end
96 end
97 return result 100 return result
98end 101end
99 102
@@ -181,16 +184,18 @@ local function install_binary(source, target)
181 return ok, err 184 return ok, err
182end 185end
183 186
184local function resolve_conflict(name, version, target) 187local function resolve_conflict(target, deploy_dir, name, version)
185 local cname, cversion = manif.find_current_provider(target) 188 local cname, cversion = manif.find_current_provider(target)
186 if not cname then 189 if not cname then
187 return nil, cversion 190 return nil, cversion
188 end 191 end
189 if name ~= cname or deps.compare_versions(version, cversion) then 192 if name ~= cname or deps.compare_versions(version, cversion) then
190 fs.move(target, path.versioned_name(target, cname, cversion)) 193 local versioned = path.versioned_name(target, deploy_dir, cname, cversion)
194 fs.make_dir(dir.dir_name(versioned))
195 fs.move(target, versioned)
191 return target 196 return target
192 else 197 else
193 return path.versioned_name(target, name, version) 198 return path.versioned_name(target, deploy_dir, name, version)
194 end 199 end
195end 200end
196 201
@@ -198,68 +203,26 @@ function deploy_files(name, version)
198 assert(type(name) == "string") 203 assert(type(name) == "string")
199 assert(type(version) == "string") 204 assert(type(version) == "string")
200 205
201 local function deploy_file_tree(file_tree, deploy_dir, source_dir, move_fn)
202 return recurse_rock_manifest_tree(file_tree,
203 function(name, version, deploy_dir, parent_path, parent_module, file)
204
205 local versioned = path.versioned_name(dir.path(deploy_dir, file), name, version)
206 if fs.exists(versioned) then
207 fs.delete(versioned)
208 else
209 fs.delete(target)
210 end
211 return true
212
213 local source = dir.path(source_dir, file)
214 local target = dir.path(deploy_dir, file)
215 if type(sub) == "table" then
216 ok, err = deploy_file_tree(sub, source, target)
217 if not ok then return nil, err end
218 fs.remove_dir_if_empty(source)
219 else
220 if fs.exists(target) then
221 target, err = resolve_conflict(name, version, target)
222 if err then return nil, err.." Cannot install new version." end
223 end
224 ok, err = move_fn(source, target)
225 if not ok then return nil, err end
226 end
227
228 end
229 )
230 end
231
232 local function deploy_file_tree(file_tree, source_dir, deploy_dir, move_fn) 206 local function deploy_file_tree(file_tree, source_dir, deploy_dir, move_fn)
233 assert(type(file_tree) == "table") 207 if not move_fn then
234 assert(type(source_dir) == "string") 208 move_fn = fs.move
235 assert(type(deploy_dir) == "string")
236 assert(type(move_fn) == "function" or not move_fn)
237
238 if not move_fn then move_fn = fs.move end
239
240 local ok, err = fs.make_dir(deploy_dir)
241 if not ok then
242 return nil, "Could not create "..deploy_dir
243 end 209 end
244 for file, sub in pairs(file_tree) do 210 return recurse_rock_manifest_tree(file_tree,
245 local source = dir.path(source_dir, file) 211 function(parent_path, parent_module, file)
246 local target = dir.path(deploy_dir, file) 212 local source = dir.path(source_dir, parent_path, file)
247 if type(sub) == "table" then 213 local target = dir.path(deploy_dir, parent_path, file)
248 ok, err = deploy_file_tree(sub, source, target)
249 if not ok then return nil, err end
250 fs.remove_dir_if_empty(source)
251 else
252 if fs.exists(target) then 214 if fs.exists(target) then
253 target, err = resolve_conflict(name, version, target) 215 target, err = resolve_conflict(target, deploy_dir, name, version)
254 if err then return nil, err.." Cannot install new version." end 216 if err then return nil, err.." Cannot install new version." end
255 end 217 end
218 fs.make_dir(dir.dir_name(target))
256 ok, err = move_fn(source, target) 219 ok, err = move_fn(source, target)
257 if not ok then return nil, err end 220 if not ok then return nil, err end
221 return true
258 end 222 end
259 end 223 )
260 return true
261 end 224 end
262 225
263 local rock_manifest = manif.load_rock_manifest(name, version) 226 local rock_manifest = manif.load_rock_manifest(name, version)
264 227
265 local ok, err = true 228 local ok, err = true
@@ -283,18 +246,23 @@ function delete_version(name, version)
283 assert(type(name) == "string") 246 assert(type(name) == "string")
284 assert(type(version) == "string") 247 assert(type(version) == "string")
285 248
286 local function delete_deployed_file_tree(name, version, file_tree, deploy_dir) 249 local function delete_deployed_file_tree(file_tree, deploy_dir)
287 return recurse_rock_manifest_tree(name, version, file_tree, deploy_dir, "", "", 250 return recurse_rock_manifest_tree(file_tree,
288 function(name, version, deploy_dir, parent_path, parent_module, file) 251 function(parent_path, parent_module, file)
289 252 local target = dir.path(deploy_dir, parent_path, file)
290 local versioned = path.versioned_name(dir.path(deploy_dir, file), name, version) 253 local versioned = path.versioned_name(target, deploy_dir, name, version)
291 if fs.exists(versioned) then 254 if fs.exists(versioned) then
292 fs.delete(versioned) 255 fs.delete(versioned)
293 else 256 else
294 fs.delete(target) 257 fs.delete(target)
258 local next_name, next_version = manif.find_next_provider(target)
259 if next_name then
260 local versioned = path.versioned_name(target, deploy_dir, next_name, next_version)
261 fs.move(versioned, target)
262 fs.remove_dir_tree_if_empty(dir.dir_name(versioned))
263 end
295 end 264 end
296 return true 265 return true
297
298 end 266 end
299 ) 267 )
300 end 268 end
@@ -306,13 +274,13 @@ function delete_version(name, version)
306 274
307 local ok, err = true 275 local ok, err = true
308 if rock_manifest.bin then 276 if rock_manifest.bin then
309 ok, err = delete_deployed_file_tree(name, version, rock_manifest.bin, cfg.deploy_bin_dir) 277 ok, err = delete_deployed_file_tree(rock_manifest.bin, cfg.deploy_bin_dir)
310 end 278 end
311 if ok and rock_manifest.lua then 279 if ok and rock_manifest.lua then
312 ok, err = delete_deployed_file_tree(name, version, rock_manifest.lua, cfg.deploy_lua_dir) 280 ok, err = delete_deployed_file_tree(rock_manifest.lua, cfg.deploy_lua_dir)
313 end 281 end
314 if ok and rock_manifest.lib then 282 if ok and rock_manifest.lib then
315 ok, err = delete_deployed_file_tree(name, version, rock_manifest.lib, cfg.deploy_lib_dir) 283 ok, err = delete_deployed_file_tree(rock_manifest.lib, cfg.deploy_lib_dir)
316 end 284 end
317 if err then return nil, err end 285 if err then return nil, err end
318 286
diff --git a/src/luarocks/require.lua b/src/luarocks/require.lua
index 653597f9..99177700 100644
--- a/src/luarocks/require.lua
+++ b/src/luarocks/require.lua
@@ -1,4 +1,6 @@
1--- Retained for compatibility reasons only. Use luarocks.loader instead. 1--- Retained for compatibility reasons only. Use luarocks.loader instead.
2local require = require 2local require, pairs = require, pairs
3module("luarocks.require") 3module("luarocks.require")
4require("luarocks.loader") 4for k,v in pairs(require("luarocks.loader")) do
5 _M[k] = v
6end