Mercurial > repo
comparison share/lua/5.2/luarocks/pack.lua @ 1132:d137f631bad5
<GreyKnight> (cd luabuild/luarocks-2.0.12; make install)
author | HackBot |
---|---|
date | Fri, 14 Dec 2012 22:24:27 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1131:ff65dfb63263 | 1132:d137f631bad5 |
---|---|
1 | |
2 --- Module implementing the LuaRocks "pack" command. | |
3 -- Creates a rock, packing sources or binaries. | |
4 module("luarocks.pack", package.seeall) | |
5 | |
6 local path = require("luarocks.path") | |
7 local repos = require("luarocks.repos") | |
8 local fetch = require("luarocks.fetch") | |
9 local fs = require("luarocks.fs") | |
10 local cfg = require("luarocks.cfg") | |
11 local util = require("luarocks.util") | |
12 local dir = require("luarocks.dir") | |
13 local manif = require("luarocks.manif") | |
14 local search = require("luarocks.search") | |
15 | |
16 help_summary = "Create a rock, packing sources or binaries." | |
17 help_arguments = "{<rockspec>|<name> [<version>]}" | |
18 help = [[ | |
19 Argument may be a rockspec file, for creating a source rock, | |
20 or the name of an installed package, for creating a binary rock. | |
21 In the latter case, the app version may be given as a second | |
22 argument. | |
23 ]] | |
24 | |
25 --- Create a source rock. | |
26 -- Packages a rockspec and its required source files in a rock | |
27 -- file with the .src.rock extension, which can later be built and | |
28 -- installed with the "build" command. | |
29 -- @param rockspec_file string: An URL or pathname for a rockspec file. | |
30 -- @return string or (nil, string): The filename of the resulting | |
31 -- .src.rock file; or nil and an error message. | |
32 local function pack_source_rock(rockspec_file) | |
33 assert(type(rockspec_file) == "string") | |
34 | |
35 local rockspec, err = fetch.load_rockspec(rockspec_file) | |
36 if err then | |
37 return nil, "Error loading rockspec: "..err | |
38 end | |
39 rockspec_file = rockspec.local_filename | |
40 | |
41 local name_version = rockspec.name .. "-" .. rockspec.version | |
42 local rock_file = fs.absolute_name(name_version .. ".src.rock") | |
43 | |
44 local source_file, source_dir = fetch.fetch_sources(rockspec, false) | |
45 if not source_file then | |
46 return nil, source_dir | |
47 end | |
48 fs.change_dir(source_dir) | |
49 | |
50 fs.delete(rock_file) | |
51 fs.copy(rockspec_file, source_dir) | |
52 if not fs.zip(rock_file, dir.base_name(rockspec_file), dir.base_name(source_file)) then | |
53 return nil, "Failed packing "..rock_file | |
54 end | |
55 fs.pop_dir() | |
56 | |
57 return rock_file | |
58 end | |
59 | |
60 local function copy_back_files(name, version, file_tree, deploy_dir, pack_dir) | |
61 fs.make_dir(pack_dir) | |
62 for file, sub in pairs(file_tree) do | |
63 local source = dir.path(deploy_dir, file) | |
64 local target = dir.path(pack_dir, file) | |
65 if type(sub) == "table" then | |
66 local ok, err = copy_back_files(name, version, sub, source, target) | |
67 else | |
68 local versioned = path.versioned_name(source, deploy_dir, name, version) | |
69 if fs.exists(versioned) then | |
70 fs.copy(versioned, target) | |
71 else | |
72 fs.copy(source, target) | |
73 end | |
74 end | |
75 end | |
76 return true | |
77 end | |
78 | |
79 -- @param name string: Name of package to pack. | |
80 -- @param version string or nil: A version number may also be passed. | |
81 -- @return string or (nil, string): The filename of the resulting | |
82 -- .src.rock file; or nil and an error message. | |
83 local function do_pack_binary_rock(name, version) | |
84 assert(type(name) == "string") | |
85 assert(type(version) == "string" or not version) | |
86 | |
87 local query = search.make_query(name, version) | |
88 query.exact_name = true | |
89 local results = {} | |
90 | |
91 search.manifest_search(results, cfg.rocks_dir, query) | |
92 | |
93 if not next(results) then | |
94 return nil, "'"..name.."' does not seem to be an installed rock." | |
95 end | |
96 | |
97 local versions = results[name] | |
98 | |
99 if not version then | |
100 local first = next(versions) | |
101 if next(versions, first) then | |
102 return nil, "Please specify which version of '"..name.."' to pack." | |
103 end | |
104 version = first | |
105 end | |
106 if not version:match("[^-]+%-%d+") then | |
107 return nil, "Expected version "..version.." in version-revision format." | |
108 end | |
109 | |
110 local info = versions[version][1] | |
111 | |
112 local root = path.root_dir(info.repo) | |
113 local prefix = path.install_dir(name, version, root) | |
114 | |
115 if not fs.exists(prefix) then | |
116 return nil, "'"..name.." "..version.."' does not seem to be an installed rock." | |
117 end | |
118 | |
119 local rock_manifest = manif.load_rock_manifest(name, version, root) | |
120 if not rock_manifest then | |
121 return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks 2 tree?" | |
122 end | |
123 | |
124 local name_version = name .. "-" .. version | |
125 local rock_file = fs.absolute_name(name_version .. "."..cfg.arch..".rock") | |
126 | |
127 local temp_dir = fs.make_temp_dir("pack") | |
128 fs.copy_contents(prefix, temp_dir) | |
129 | |
130 local is_binary = false | |
131 if rock_manifest.lib then | |
132 copy_back_files(name, version, rock_manifest.lib, path.deploy_lib_dir(root), dir.path(temp_dir, "lib")) | |
133 is_binary = true | |
134 end | |
135 if rock_manifest.lua then | |
136 copy_back_files(name, version, rock_manifest.lua, path.deploy_lua_dir(root), dir.path(temp_dir, "lua")) | |
137 end | |
138 | |
139 fs.change_dir(temp_dir) | |
140 if not is_binary and not repos.has_binaries(name, version) then | |
141 rock_file = rock_file:gsub("%."..cfg.arch:gsub("%-","%%-").."%.", ".all.") | |
142 end | |
143 fs.delete(rock_file) | |
144 if not fs.zip(rock_file, unpack(fs.list_dir())) then | |
145 return nil, "Failed packing "..rock_file | |
146 end | |
147 fs.pop_dir() | |
148 fs.delete(temp_dir) | |
149 return rock_file | |
150 end | |
151 | |
152 function pack_binary_rock(name, version, cmd, ...) | |
153 | |
154 -- The --pack-binary-rock option for "luarocks build" basically performs | |
155 -- "luarocks build" on a temporary tree and then "luarocks pack". The | |
156 -- alternative would require refactoring parts of luarocks.build and | |
157 -- luarocks.pack, which would save a few file operations: the idea would be | |
158 -- to shave off the final deploy steps from the build phase and the initial | |
159 -- collect steps from the pack phase. | |
160 | |
161 local temp_dir = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name)) | |
162 if not temp_dir then | |
163 return nil, "Failed creating temporary directory." | |
164 end | |
165 util.schedule_function(fs.delete, temp_dir) | |
166 | |
167 path.use_tree(temp_dir) | |
168 local ok, err = cmd(...) | |
169 if not ok then | |
170 return nil, err | |
171 end | |
172 local rname, rversion = path.parse_name(name) | |
173 if not rname then | |
174 rname, rversion = name, version | |
175 end | |
176 return do_pack_binary_rock(rname, rversion) | |
177 end | |
178 | |
179 --- Driver function for the "pack" command. | |
180 -- @param arg string: may be a rockspec file, for creating a source rock, | |
181 -- or the name of an installed package, for creating a binary rock. | |
182 -- @param version string or nil: if the name of a package is given, a | |
183 -- version may also be passed. | |
184 -- @return boolean or (nil, string): true if successful or nil followed | |
185 -- by an error message. | |
186 function run(...) | |
187 local flags, arg, version = util.parse_flags(...) | |
188 assert(type(version) == "string" or not version) | |
189 if type(arg) ~= "string" then | |
190 return nil, "Argument missing, see help." | |
191 end | |
192 | |
193 local file, err | |
194 if arg:match(".*%.rockspec") then | |
195 file, err = pack_source_rock(arg) | |
196 else | |
197 file, err = do_pack_binary_rock(arg, version) | |
198 end | |
199 if err then | |
200 return nil, err | |
201 else | |
202 util.printout("Packed: "..file) | |
203 return true | |
204 end | |
205 end |