diff options
author | hisham <hisham@9ca3f7c1-7366-0410-b1a3-b5c78f85698c> | 2009-10-11 04:47:08 +0000 |
---|---|---|
committer | hisham <hisham@9ca3f7c1-7366-0410-b1a3-b5c78f85698c> | 2009-10-11 04:47:08 +0000 |
commit | 01a0723c9dd08b86ac96b09c08b9ce16cafa2438 (patch) | |
tree | fae83a35c1c69b1f9aeb0ef31e54175d249bd320 /src | |
parent | 311287db133962862f03f01c02bb6debee429e3c (diff) | |
download | luarocks-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.lua | 30 | ||||
-rw-r--r-- | src/luarocks/manif.lua | 35 | ||||
-rw-r--r-- | src/luarocks/path.lua | 14 | ||||
-rw-r--r-- | src/luarocks/rep.lua | 122 | ||||
-rw-r--r-- | src/luarocks/require.lua | 6 |
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 |
90 | end | 90 | end |
91 | 91 | ||
92 | local function call_other_loaders(module, name, version, file) | 92 | local 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 |
145 | end | 137 | end |
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 | ||
157 | function luarocks_loader(module) | 149 | function 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 |
165 | end | 157 | end |
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) |
302 | end | 302 | end |
303 | 303 | ||
304 | --- Given a path of a deployed file, figure out which rock name and version | 304 | local 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. | ||
309 | function 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 | ||
336 | end | ||
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. | ||
343 | function 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("([^/]*)/([^/]*)") |
336 | end | 347 | end |
348 | |||
349 | function 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 | ||
357 | end | ||
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 |
264 | end | 264 | end |
265 | 265 | ||
266 | function versioned_name(file, name, version) | 266 | function 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) |
274 | end | ||
275 | |||
276 | function unversioned_name(file) | ||
277 | assert(type(file) == "string") | ||
278 | |||
279 | return dir.path(dir.dir_name(file), dir.base_name(file):match("^[^-]+-(.*)")) | ||
280 | end | 274 | end |
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, "", "") |
54 | end | 54 | end |
55 | 55 | ||
56 | local function store_package_data(result, name, sub, prefix) | 56 | local 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 |
70 | end | 70 | end |
71 | 71 | ||
72 | local 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 | ) | ||
81 | end | ||
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 |
98 | end | 101 | end |
99 | 102 | ||
@@ -181,16 +184,18 @@ local function install_binary(source, target) | |||
181 | return ok, err | 184 | return ok, err |
182 | end | 185 | end |
183 | 186 | ||
184 | local function resolve_conflict(name, version, target) | 187 | local 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 |
195 | end | 200 | end |
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. |
2 | local require = require | 2 | local require, pairs = require, pairs |
3 | module("luarocks.require") | 3 | module("luarocks.require") |
4 | require("luarocks.loader") | 4 | for k,v in pairs(require("luarocks.loader")) do |
5 | _M[k] = v | ||
6 | end | ||