diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2019-03-20 12:18:03 -0400 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2019-04-01 17:32:53 -0400 |
commit | 12562d320a83e3f8f60d78a366793d474b522c55 (patch) | |
tree | d3700d6c919d1ab2584769754ccce5214b57afd5 | |
parent | b46978faaebeb5954d57b13ff786fea789ab775c (diff) | |
download | luarocks-12562d320a83e3f8f60d78a366793d474b522c55.tar.gz luarocks-12562d320a83e3f8f60d78a366793d474b522c55.tar.bz2 luarocks-12562d320a83e3f8f60d78a366793d474b522c55.zip |
install, build, make: add --verify and --sign options
The --verify options of build and make check the signature of
rockspec and src.rock files; the --sign option is meant to
be used alongside --pack-binary-rock.
-rw-r--r-- | src/luarocks/build.lua | 5 | ||||
-rw-r--r-- | src/luarocks/cmd/build.lua | 32 | ||||
-rw-r--r-- | src/luarocks/cmd/install.lua | 108 | ||||
-rw-r--r-- | src/luarocks/cmd/make.lua | 18 | ||||
-rw-r--r-- | src/luarocks/cmd/pack.lua | 18 | ||||
-rw-r--r-- | src/luarocks/deps.lua | 23 | ||||
-rw-r--r-- | src/luarocks/fetch.lua | 69 | ||||
-rw-r--r-- | src/luarocks/pack.lua | 25 | ||||
-rw-r--r-- | src/luarocks/signing.lua | 32 | ||||
-rw-r--r-- | src/luarocks/util.lua | 1 |
10 files changed, 236 insertions, 95 deletions
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 130ccd3a..14d699e5 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua | |||
@@ -19,6 +19,7 @@ build.opts = util.opts_table("build.opts", { | |||
19 | build_only_deps = "boolean", | 19 | build_only_deps = "boolean", |
20 | namespace = "string?", | 20 | namespace = "string?", |
21 | branch = "boolean", | 21 | branch = "boolean", |
22 | verify = "boolean", | ||
22 | }) | 23 | }) |
23 | 24 | ||
24 | do | 25 | do |
@@ -104,13 +105,13 @@ local function process_dependencies(rockspec, opts) | |||
104 | end | 105 | end |
105 | if not opts.build_only_deps then | 106 | if not opts.build_only_deps then |
106 | if next(rockspec.build_dependencies) then | 107 | if next(rockspec.build_dependencies) then |
107 | local ok, err, errcode = deps.fulfill_dependencies(rockspec, "build_dependencies", opts.deps_mode) | 108 | local ok, err, errcode = deps.fulfill_dependencies(rockspec, "build_dependencies", opts.deps_mode, opts.verify) |
108 | if err then | 109 | if err then |
109 | return nil, err, errcode | 110 | return nil, err, errcode |
110 | end | 111 | end |
111 | end | 112 | end |
112 | end | 113 | end |
113 | local ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", opts.deps_mode) | 114 | local ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", opts.deps_mode, opts.verify) |
114 | if err then | 115 | if err then |
115 | return nil, err, errcode | 116 | return nil, err, errcode |
116 | end | 117 | end |
diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 29b1bd6e..e6dc8a88 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua | |||
@@ -19,7 +19,7 @@ local make = require("luarocks.cmd.make") | |||
19 | local cmd = require("luarocks.cmd") | 19 | local cmd = require("luarocks.cmd") |
20 | 20 | ||
21 | cmd_build.help_summary = "build/compile a rock." | 21 | cmd_build.help_summary = "build/compile a rock." |
22 | cmd_build.help_arguments = "[--pack-binary-rock] [--keep] {<rockspec>|<rock>|<name> [<version>]}" | 22 | cmd_build.help_arguments = "[<flags...>] {<rockspec>|<rock>|<name> [<version>]}" |
23 | cmd_build.help = [[ | 23 | cmd_build.help = [[ |
24 | Build and install a rock, compiling its C parts if any. | 24 | Build and install a rock, compiling its C parts if any. |
25 | Argument may be a rockspec file, a source rock file | 25 | Argument may be a rockspec file, a source rock file |
@@ -40,17 +40,22 @@ or the name of a rock to be fetched from a repository. | |||
40 | 40 | ||
41 | --only-deps Installs only the dependencies of the rock. | 41 | --only-deps Installs only the dependencies of the rock. |
42 | 42 | ||
43 | --verify Verify signature of the rockspec or src.rock being | ||
44 | built. If the rockspec or src.rock is being downloaded, | ||
45 | LuaRocks will attempt to download the signature as well. | ||
46 | Otherwise, the signature file should be already | ||
47 | available locally in the same directory. | ||
48 | You need the signer’s public key in your local | ||
49 | keyring for this option to work properly. | ||
50 | |||
51 | --sign To be used with --pack-binary-rock. Also produce | ||
52 | a signature file for the generated .rock file. | ||
53 | |||
43 | ]]..util.deps_mode_help() | 54 | ]]..util.deps_mode_help() |
44 | 55 | ||
45 | --- Build and install a rock. | 56 | --- Build and install a rock. |
46 | -- @param rock_filename string: local or remote filename of a rock. | 57 | -- @param rock_filename string: local or remote filename of a rock. |
47 | -- @param need_to_fetch boolean: true if sources need to be fetched, | 58 | -- @param opts table: build options |
48 | -- false if the rockspec was obtained from inside a source rock. | ||
49 | -- @param deps_mode: string: Which trees to check dependencies for: | ||
50 | -- "one" for the current default tree, "all" for all trees, | ||
51 | -- "order" for all trees with priority >= the current default, "none" for no trees. | ||
52 | -- @param build_only_deps boolean: true to build the listed dependencies only. | ||
53 | -- @param namespace string?: an optional namespace | ||
54 | -- @return boolean or (nil, string, [string]): True if build was successful, | 59 | -- @return boolean or (nil, string, [string]): True if build was successful, |
55 | -- or false and an error message and an optional error code. | 60 | -- or false and an error message and an optional error code. |
56 | local function build_rock(rock_filename, opts) | 61 | local function build_rock(rock_filename, opts) |
@@ -60,7 +65,7 @@ local function build_rock(rock_filename, opts) | |||
60 | local ok, err, errcode | 65 | local ok, err, errcode |
61 | 66 | ||
62 | local unpack_dir | 67 | local unpack_dir |
63 | unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_filename) | 68 | unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_filename, nil, opts.verify) |
64 | if not unpack_dir then | 69 | if not unpack_dir then |
65 | return nil, err, errcode | 70 | return nil, err, errcode |
66 | end | 71 | end |
@@ -100,7 +105,7 @@ local function do_build(ns_name, version, opts) | |||
100 | end | 105 | end |
101 | 106 | ||
102 | if url:match("%.rockspec$") then | 107 | if url:match("%.rockspec$") then |
103 | local rockspec, err, errcode = fetch.load_rockspec(url) | 108 | local rockspec, err, errcode = fetch.load_rockspec(url, nil, opts.verify) |
104 | if not rockspec then | 109 | if not rockspec then |
105 | return nil, err, errcode | 110 | return nil, err, errcode |
106 | end | 111 | end |
@@ -151,10 +156,15 @@ function cmd_build.command(flags, name, version) | |||
151 | build_only_deps = not not flags["only-deps"], | 156 | build_only_deps = not not flags["only-deps"], |
152 | namespace = flags["namespace"], | 157 | namespace = flags["namespace"], |
153 | branch = not not flags["branch"], | 158 | branch = not not flags["branch"], |
159 | verify = not not flags["verify"], | ||
154 | }) | 160 | }) |
155 | 161 | ||
162 | if flags["sign"] and not flags["pack-binary-rock"] then | ||
163 | return nil, "In the build command, --sign is meant to be used only with --pack-binary-rock" | ||
164 | end | ||
165 | |||
156 | if flags["pack-binary-rock"] then | 166 | if flags["pack-binary-rock"] then |
157 | return pack.pack_binary_rock(name, version, function() | 167 | return pack.pack_binary_rock(name, version, flags["sign"], function() |
158 | opts.build_only_deps = false | 168 | opts.build_only_deps = false |
159 | local status, err, errcode = do_build(name, version, opts) | 169 | local status, err, errcode = do_build(name, version, opts) |
160 | if status and flags["no-doc"] then | 170 | if status and flags["no-doc"] then |
diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index 97c693d9..647dbdfd 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua | |||
@@ -14,6 +14,7 @@ local search = require("luarocks.search") | |||
14 | local queries = require("luarocks.queries") | 14 | local queries = require("luarocks.queries") |
15 | local cfg = require("luarocks.core.cfg") | 15 | local cfg = require("luarocks.core.cfg") |
16 | local cmd = require("luarocks.cmd") | 16 | local cmd = require("luarocks.cmd") |
17 | local dir = require("luarocks.dir") | ||
17 | 18 | ||
18 | install.help_summary = "Install a rock." | 19 | install.help_summary = "Install a rock." |
19 | 20 | ||
@@ -29,22 +30,40 @@ or a filename of a locally available rock. | |||
29 | in the configuration file. | 30 | in the configuration file. |
30 | 31 | ||
31 | --only-deps Installs only the dependencies of the rock. | 32 | --only-deps Installs only the dependencies of the rock. |
33 | |||
32 | --no-doc Installs the rock without its documentation. | 34 | --no-doc Installs the rock without its documentation. |
35 | |||
36 | --verify Verify signature of the rock being installed. | ||
37 | If rock is being downloaded, LuaRocks will attempt | ||
38 | to download the signature as well. If the rock is | ||
39 | local, the signature file should be in the same | ||
40 | directory. | ||
41 | You need the signer’s public key in your local | ||
42 | keyring for this option to work properly. | ||
43 | |||
33 | ]]..util.deps_mode_help() | 44 | ]]..util.deps_mode_help() |
34 | 45 | ||
46 | install.opts = util.opts_table("install.opts", { | ||
47 | namespace = "string?", | ||
48 | keep = "boolean", | ||
49 | force = "boolean", | ||
50 | force_fast = "boolean", | ||
51 | no_doc = "boolean", | ||
52 | deps_mode = "string", | ||
53 | verify = "boolean", | ||
54 | }) | ||
35 | 55 | ||
36 | --- Install a binary rock. | 56 | --- Install a binary rock. |
37 | -- @param rock_file string: local or remote filename of a rock. | 57 | -- @param rock_file string: local or remote filename of a rock. |
38 | -- @param deps_mode: string: Which trees to check dependencies for: | 58 | -- @param opts table: installation options |
39 | -- "one" for the current default tree, "all" for all trees, | ||
40 | -- "order" for all trees with priority >= the current default, "none" for no trees. | ||
41 | -- @param namespace: string?: an optional namespace. | ||
42 | -- @return (string, string) or (nil, string, [string]): Name and version of | 59 | -- @return (string, string) or (nil, string, [string]): Name and version of |
43 | -- installed rock if succeeded or nil and an error message followed by an error code. | 60 | -- installed rock if succeeded or nil and an error message followed by an error code. |
44 | function install.install_binary_rock(rock_file, deps_mode, namespace) | 61 | function install.install_binary_rock(rock_file, opts) |
45 | assert(type(rock_file) == "string") | 62 | assert(type(rock_file) == "string") |
46 | assert(type(deps_mode) == "string") | 63 | assert(opts:type() == "install.opts") |
47 | assert(type(namespace) == "string" or namespace == nil) | 64 | |
65 | local namespace = opts.namespace | ||
66 | local deps_mode = opts.deps_mode | ||
48 | 67 | ||
49 | local name, version, arch = path.parse_name(rock_file) | 68 | local name, version, arch = path.parse_name(rock_file) |
50 | if not name then | 69 | if not name then |
@@ -55,23 +74,25 @@ function install.install_binary_rock(rock_file, deps_mode, namespace) | |||
55 | return nil, "Incompatible architecture "..arch, "arch" | 74 | return nil, "Incompatible architecture "..arch, "arch" |
56 | end | 75 | end |
57 | if repos.is_installed(name, version) then | 76 | if repos.is_installed(name, version) then |
58 | repos.delete_version(name, version, deps_mode) | 77 | repos.delete_version(name, version, opts.deps_mode) |
59 | end | 78 | end |
60 | 79 | ||
80 | local install_dir = path.install_dir(name, version) | ||
81 | |||
61 | local rollback = util.schedule_function(function() | 82 | local rollback = util.schedule_function(function() |
62 | fs.delete(path.install_dir(name, version)) | 83 | fs.delete(install_dir) |
63 | fs.remove_dir_if_empty(path.versions_dir(name)) | 84 | fs.remove_dir_if_empty(path.versions_dir(name)) |
64 | end) | 85 | end) |
65 | 86 | ||
66 | local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, path.install_dir(name, version)) | 87 | local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, install_dir, opts.verify) |
67 | if not ok then return nil, err, errcode end | 88 | if not ok then return nil, err, errcode end |
68 | 89 | ||
69 | local rockspec, err, errcode = fetch.load_rockspec(path.rockspec_file(name, version)) | 90 | local rockspec, err = fetch.load_rockspec(path.rockspec_file(name, version)) |
70 | if err then | 91 | if err then |
71 | return nil, "Failed loading rockspec for installed package: "..err, errcode | 92 | return nil, "Failed loading rockspec for installed package: "..err, errcode |
72 | end | 93 | end |
73 | 94 | ||
74 | if deps_mode == "none" then | 95 | if opts.deps_mode == "none" then |
75 | util.warning("skipping dependency checks.") | 96 | util.warning("skipping dependency checks.") |
76 | else | 97 | else |
77 | ok, err, errcode = deps.check_external_deps(rockspec, "install") | 98 | ok, err, errcode = deps.check_external_deps(rockspec, "install") |
@@ -90,7 +111,7 @@ function install.install_binary_rock(rock_file, deps_mode, namespace) | |||
90 | end | 111 | end |
91 | 112 | ||
92 | if deps_mode ~= "none" then | 113 | if deps_mode ~= "none" then |
93 | ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", deps_mode) | 114 | ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", deps_mode, opts.verify) |
94 | if err then return nil, err, errcode end | 115 | if err then return nil, err, errcode end |
95 | end | 116 | end |
96 | 117 | ||
@@ -112,14 +133,13 @@ end | |||
112 | 133 | ||
113 | --- Installs the dependencies of a binary rock. | 134 | --- Installs the dependencies of a binary rock. |
114 | -- @param rock_file string: local or remote filename of a rock. | 135 | -- @param rock_file string: local or remote filename of a rock. |
115 | -- @param deps_mode: string: Which trees to check dependencies for: | 136 | -- @param opts table: installation options |
116 | -- "one" for the current default tree, "all" for all trees, | ||
117 | -- "order" for all trees with priority >= the current default, "none" for no trees. | ||
118 | -- @return (string, string) or (nil, string, [string]): Name and version of | 137 | -- @return (string, string) or (nil, string, [string]): Name and version of |
119 | -- the rock whose dependencies were installed if succeeded or nil and an error message | 138 | -- the rock whose dependencies were installed if succeeded or nil and an error message |
120 | -- followed by an error code. | 139 | -- followed by an error code. |
121 | function install.install_binary_rock_deps(rock_file, deps_mode) | 140 | function install.install_binary_rock_deps(rock_file, opts) |
122 | assert(type(rock_file) == "string") | 141 | assert(type(rock_file) == "string") |
142 | assert(opts:type() == "install.opts") | ||
123 | 143 | ||
124 | local name, version, arch = path.parse_name(rock_file) | 144 | local name, version, arch = path.parse_name(rock_file) |
125 | if not name then | 145 | if not name then |
@@ -130,15 +150,17 @@ function install.install_binary_rock_deps(rock_file, deps_mode) | |||
130 | return nil, "Incompatible architecture "..arch, "arch" | 150 | return nil, "Incompatible architecture "..arch, "arch" |
131 | end | 151 | end |
132 | 152 | ||
133 | local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, path.install_dir(name, version)) | 153 | local install_dir = path.install_dir(name, version) |
154 | |||
155 | local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, install_dir, opts.verify) | ||
134 | if not ok then return nil, err, errcode end | 156 | if not ok then return nil, err, errcode end |
135 | 157 | ||
136 | local rockspec, err, errcode = fetch.load_rockspec(path.rockspec_file(name, version)) | 158 | local rockspec, err = fetch.load_rockspec(path.rockspec_file(name, version)) |
137 | if err then | 159 | if err then |
138 | return nil, "Failed loading rockspec for installed package: "..err, errcode | 160 | return nil, "Failed loading rockspec for installed package: "..err, errcode |
139 | end | 161 | end |
140 | 162 | ||
141 | ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", deps_mode) | 163 | ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", opts.deps_mode, opts.verify) |
142 | if err then return nil, err, errcode end | 164 | if err then return nil, err, errcode end |
143 | 165 | ||
144 | util.printout() | 166 | util.printout() |
@@ -147,27 +169,24 @@ function install.install_binary_rock_deps(rock_file, deps_mode) | |||
147 | return name, version | 169 | return name, version |
148 | end | 170 | end |
149 | 171 | ||
150 | local function install_rock_file_deps(filename, deps_mode) | 172 | local function install_rock_file_deps(filename, opts) |
151 | local name, version = install.install_binary_rock_deps(filename, deps_mode) | 173 | assert(opts:type() == "install.opts") |
174 | |||
175 | local name, version = install.install_binary_rock_deps(filename, opts) | ||
152 | if not name then return nil, version end | 176 | if not name then return nil, version end |
153 | 177 | ||
154 | writer.check_dependencies(nil, deps_mode) | 178 | writer.check_dependencies(nil, opts.deps_mode) |
155 | return name, version | 179 | return name, version |
156 | end | 180 | end |
157 | 181 | ||
158 | local function install_rock_file(filename, namespace, deps_mode, keep, force, force_fast, no_doc) | 182 | local function install_rock_file(filename, opts) |
159 | assert(type(filename) == "string") | 183 | assert(type(filename) == "string") |
160 | assert(type(namespace) == "string" or namespace == nil) | 184 | assert(opts:type() == "install.opts") |
161 | assert(type(deps_mode) == "string") | 185 | |
162 | assert(type(keep) == "boolean" or keep == nil) | 186 | local name, version = install.install_binary_rock(filename, opts) |
163 | assert(type(force) == "boolean" or force == nil) | ||
164 | assert(type(force_fast) == "boolean" or force_fast == nil) | ||
165 | assert(type(no_doc) == "boolean" or no_doc == nil) | ||
166 | |||
167 | local name, version = install.install_binary_rock(filename, deps_mode, namespace) | ||
168 | if not name then return nil, version end | 187 | if not name then return nil, version end |
169 | 188 | ||
170 | if no_doc then | 189 | if opts.no_doc then |
171 | local install_dir = path.install_dir(name, version) | 190 | local install_dir = path.install_dir(name, version) |
172 | for _, f in ipairs(fs.list_dir(install_dir)) do | 191 | for _, f in ipairs(fs.list_dir(install_dir)) do |
173 | local doc_dirs = { "doc", "docs" } | 192 | local doc_dirs = { "doc", "docs" } |
@@ -179,12 +198,12 @@ local function install_rock_file(filename, namespace, deps_mode, keep, force, fo | |||
179 | end | 198 | end |
180 | end | 199 | end |
181 | 200 | ||
182 | if (not keep) and not cfg.keep_other_versions then | 201 | if (not opts.keep) and not cfg.keep_other_versions then |
183 | local ok, err = remove.remove_other_versions(name, version, force, force_fast) | 202 | local ok, err = remove.remove_other_versions(name, version, opts.force, opts.force_fast) |
184 | if not ok then util.printerr(err) end | 203 | if not ok then util.printerr(err) end |
185 | end | 204 | end |
186 | 205 | ||
187 | writer.check_dependencies(nil, deps_mode) | 206 | writer.check_dependencies(nil, opts.deps_mode) |
188 | return name, version | 207 | return name, version |
189 | end | 208 | end |
190 | 209 | ||
@@ -213,10 +232,19 @@ function install.command(flags, name, version) | |||
213 | return build.command(flags, name) | 232 | return build.command(flags, name) |
214 | elseif name:match("%.rock$") then | 233 | elseif name:match("%.rock$") then |
215 | local deps_mode = deps.get_deps_mode(flags) | 234 | local deps_mode = deps.get_deps_mode(flags) |
235 | local opts = install.opts({ | ||
236 | namespace = flags["namespace"], | ||
237 | keep = not not flags["keep"], | ||
238 | force = not not flags["force"], | ||
239 | force_fast = not not flags["force-fast"], | ||
240 | no_doc = not not flags["no-doc"], | ||
241 | deps_mode = deps_mode, | ||
242 | verify = not not flags["verify"], | ||
243 | }) | ||
216 | if flags["only-deps"] then | 244 | if flags["only-deps"] then |
217 | return install_rock_file_deps(name, deps_mode) | 245 | return install_rock_file_deps(name, opts) |
218 | else | 246 | else |
219 | return install_rock_file(name, flags["namespace"], deps_mode, flags["keep"], flags["force"], flags["force-fast"], flags["no-doc"]) | 247 | return install_rock_file(name, opts) |
220 | end | 248 | end |
221 | else | 249 | else |
222 | local url, err = search.find_suitable_rock(queries.new(name:lower(), version)) | 250 | local url, err = search.find_suitable_rock(queries.new(name:lower(), version)) |
diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index 90d4f336..4d813864 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua | |||
@@ -48,6 +48,17 @@ only dependencies of the rockspec (see `luarocks help install`). | |||
48 | rockspec. Allows to specify a different branch to | 48 | rockspec. Allows to specify a different branch to |
49 | fetch. Particularly for "dev" rocks. | 49 | fetch. Particularly for "dev" rocks. |
50 | 50 | ||
51 | --verify Verify signature of the rockspec or src.rock being | ||
52 | built. If the rockspec or src.rock is being downloaded, | ||
53 | LuaRocks will attempt to download the signature as well. | ||
54 | Otherwise, the signature file should be already | ||
55 | available locally in the same directory. | ||
56 | You need the signer’s public key in your local | ||
57 | keyring for this option to work properly. | ||
58 | |||
59 | --sign To be used with --pack-binary-rock. Also produce | ||
60 | a signature file for the generated .rock file. | ||
61 | |||
51 | ]] | 62 | ]] |
52 | 63 | ||
53 | --- Driver function for "make" command. | 64 | --- Driver function for "make" command. |
@@ -82,10 +93,15 @@ function make.command(flags, rockspec_filename) | |||
82 | build_only_deps = false, | 93 | build_only_deps = false, |
83 | namespace = flags["namespace"], | 94 | namespace = flags["namespace"], |
84 | branch = not not flags["branch"], | 95 | branch = not not flags["branch"], |
96 | verify = not not flags["verify"], | ||
85 | }) | 97 | }) |
86 | 98 | ||
99 | if flags["sign"] and not flags["pack-binary-rock"] then | ||
100 | return nil, "In the make command, --sign is meant to be used only with --pack-binary-rock" | ||
101 | end | ||
102 | |||
87 | if flags["pack-binary-rock"] then | 103 | if flags["pack-binary-rock"] then |
88 | return pack.pack_binary_rock(name, rockspec.version, function() | 104 | return pack.pack_binary_rock(name, rockspec.version, flags["sign"], function() |
89 | return build.build_rockspec(rockspec, opts) | 105 | return build.build_rockspec(rockspec, opts) |
90 | end) | 106 | end) |
91 | else | 107 | else |
diff --git a/src/luarocks/cmd/pack.lua b/src/luarocks/cmd/pack.lua index 02e554d9..7781a3bd 100644 --- a/src/luarocks/cmd/pack.lua +++ b/src/luarocks/cmd/pack.lua | |||
@@ -40,23 +40,7 @@ function cmd_pack.command(flags, arg, version) | |||
40 | local query = queries.new(name, version) | 40 | local query = queries.new(name, version) |
41 | file, err = pack.pack_installed_rock(query, flags["tree"]) | 41 | file, err = pack.pack_installed_rock(query, flags["tree"]) |
42 | end | 42 | end |
43 | if err then | 43 | return pack.report_and_sign_local_file(file, err, flags["sign"]) |
44 | return nil, err | ||
45 | else | ||
46 | local sigfile | ||
47 | if flags["sign"] then | ||
48 | sigfile, err = signing.sign_file(file) | ||
49 | util.printout() | ||
50 | end | ||
51 | util.printout("Packed: "..file) | ||
52 | if sigfile then | ||
53 | util.printout("Sigature stored in: "..sigfile) | ||
54 | end | ||
55 | if err then | ||
56 | return nil, err | ||
57 | end | ||
58 | return true | ||
59 | end | ||
60 | end | 44 | end |
61 | 45 | ||
62 | return cmd_pack | 46 | return cmd_pack |
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index d9a88c2b..c2f6ab96 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua | |||
@@ -129,12 +129,13 @@ function deps.report_missing_dependencies(name, version, dependencies, deps_mode | |||
129 | end | 129 | end |
130 | end | 130 | end |
131 | 131 | ||
132 | function deps.fulfill_dependency(dep, deps_mode, name, version, rocks_provided) | 132 | function deps.fulfill_dependency(dep, deps_mode, name, version, rocks_provided, verify) |
133 | assert(dep:type() == "query") | 133 | assert(dep:type() == "query") |
134 | assert(type(deps_mode) == "string" or deps_mode == nil) | 134 | assert(type(deps_mode) == "string" or deps_mode == nil) |
135 | assert(type(name) == "string" or name == nil) | 135 | assert(type(name) == "string" or name == nil) |
136 | assert(type(version) == "string" or version == nil) | 136 | assert(type(version) == "string" or version == nil) |
137 | assert(type(rocks_provided) == "table" or rocks_provided == nil) | 137 | assert(type(rocks_provided) == "table" or rocks_provided == nil) |
138 | assert(type(verify) == "boolean" or verify == nil) | ||
138 | deps_mode = deps_mode or "all" | 139 | deps_mode = deps_mode or "all" |
139 | rocks_provided = rocks_provided or {} | 140 | rocks_provided = rocks_provided or {} |
140 | 141 | ||
@@ -169,7 +170,12 @@ function deps.fulfill_dependency(dep, deps_mode, name, version, rocks_provided) | |||
169 | return nil, "Could not satisfy dependency "..tostring(dep)..": "..search_err | 170 | return nil, "Could not satisfy dependency "..tostring(dep)..": "..search_err |
170 | end | 171 | end |
171 | util.printout("Installing "..url) | 172 | util.printout("Installing "..url) |
172 | local ok, install_err, errcode = install.command({deps_mode = deps_mode, namespace = dep.namespace}, url) | 173 | local install_flags = { |
174 | deps_mode = deps_mode, | ||
175 | namespace = dep.namespace, | ||
176 | verify = verify, | ||
177 | } | ||
178 | local ok, install_err, errcode = install.command(install_flags, url) | ||
173 | if not ok then | 179 | if not ok then |
174 | return nil, "Failed installing dependency: "..url.." - "..install_err, errcode | 180 | return nil, "Failed installing dependency: "..url.." - "..install_err, errcode |
175 | end | 181 | end |
@@ -183,11 +189,18 @@ end | |||
183 | -- Packages are installed using the LuaRocks "install" command. | 189 | -- Packages are installed using the LuaRocks "install" command. |
184 | -- Aborts the program if a dependency could not be fulfilled. | 190 | -- Aborts the program if a dependency could not be fulfilled. |
185 | -- @param rockspec table: A rockspec in table format. | 191 | -- @param rockspec table: A rockspec in table format. |
186 | -- @param depskey table: Rockspec key to fetch to get dependency table. | 192 | -- @param depskey string: Rockspec key to fetch to get dependency table. |
193 | -- @param deps_mode string | ||
194 | -- @param verify boolean | ||
187 | -- @return boolean or (nil, string, [string]): True if no errors occurred, or | 195 | -- @return boolean or (nil, string, [string]): True if no errors occurred, or |
188 | -- nil and an error message if any test failed, followed by an optional | 196 | -- nil and an error message if any test failed, followed by an optional |
189 | -- error code. | 197 | -- error code. |
190 | function deps.fulfill_dependencies(rockspec, depskey, deps_mode) | 198 | function deps.fulfill_dependencies(rockspec, depskey, deps_mode, verify) |
199 | assert(type(rockspec) == "table") | ||
200 | assert(type(depskey) == "string") | ||
201 | assert(type(deps_mode) == "string") | ||
202 | assert(type(verify) == "boolean" or verify == nil) | ||
203 | |||
191 | if rockspec.supported_platforms and next(rockspec.supported_platforms) then | 204 | if rockspec.supported_platforms and next(rockspec.supported_platforms) then |
192 | local supported = false | 205 | local supported = false |
193 | for _, plat in pairs(rockspec.supported_platforms) do | 206 | for _, plat in pairs(rockspec.supported_platforms) do |
@@ -214,7 +227,7 @@ function deps.fulfill_dependencies(rockspec, depskey, deps_mode) | |||
214 | 227 | ||
215 | util.printout() | 228 | util.printout() |
216 | for _, dep in ipairs(rockspec[depskey]) do | 229 | for _, dep in ipairs(rockspec[depskey]) do |
217 | local ok, err = deps.fulfill_dependency(dep, deps_mode, rockspec.name, rockspec.version, rockspec.rocks_provided) | 230 | local ok, err = deps.fulfill_dependency(dep, deps_mode, rockspec.name, rockspec.version, rockspec.rocks_provided, verify) |
218 | if not ok then | 231 | if not ok then |
219 | return nil, err | 232 | return nil, err |
220 | end | 233 | end |
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua index cd78c327..8fa7d6a6 100644 --- a/src/luarocks/fetch.lua +++ b/src/luarocks/fetch.lua | |||
@@ -5,6 +5,7 @@ local fetch = {} | |||
5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
6 | local dir = require("luarocks.dir") | 6 | local dir = require("luarocks.dir") |
7 | local rockspecs = require("luarocks.rockspecs") | 7 | local rockspecs = require("luarocks.rockspecs") |
8 | local signing = require("luarocks.signing") | ||
8 | local persist = require("luarocks.persist") | 9 | local persist = require("luarocks.persist") |
9 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
10 | local cfg = require("luarocks.core.cfg") | 11 | local cfg = require("luarocks.core.cfg") |
@@ -120,27 +121,52 @@ function fetch.find_base_dir(file, temp_dir, src_url, src_dir) | |||
120 | return inferred_dir, found_dir | 121 | return inferred_dir, found_dir |
121 | end | 122 | end |
122 | 123 | ||
124 | local function fetch_and_verify_signature_for(url, filename, tmpdir) | ||
125 | local sig_url = signing.signature_url(url) | ||
126 | local sig_file, err, errcode = fetch.fetch_url_at_temp_dir(sig_url, tmpdir) | ||
127 | if not sig_file then | ||
128 | return nil, "Could not fetch signature file for verification: " .. err, errcode | ||
129 | end | ||
130 | |||
131 | local ok, err = signing.verify_signature(filename, sig_file) | ||
132 | if not ok then | ||
133 | return nil, "Failed signature verification: " .. err | ||
134 | end | ||
135 | |||
136 | return fs.absolute_name(sig_file) | ||
137 | end | ||
138 | |||
123 | --- Obtain a rock and unpack it. | 139 | --- Obtain a rock and unpack it. |
124 | -- If a directory is not given, a temporary directory will be created, | 140 | -- If a directory is not given, a temporary directory will be created, |
125 | -- which will be deleted on program termination. | 141 | -- which will be deleted on program termination. |
126 | -- @param rock_file string: URL or filename of the rock. | 142 | -- @param rock_file string: URL or filename of the rock. |
127 | -- @param dest string or nil: if given, directory will be used as | 143 | -- @param dest string or nil: if given, directory will be used as |
128 | -- a permanent destination. | 144 | -- a permanent destination. |
145 | -- @param verify boolean: if true, download and verify signature for rockspec | ||
129 | -- @return string or (nil, string, [string]): the directory containing the contents | 146 | -- @return string or (nil, string, [string]): the directory containing the contents |
130 | -- of the unpacked rock. | 147 | -- of the unpacked rock. |
131 | function fetch.fetch_and_unpack_rock(rock_file, dest) | 148 | function fetch.fetch_and_unpack_rock(url, dest, verify) |
132 | assert(type(rock_file) == "string") | 149 | assert(type(url) == "string") |
133 | assert(type(dest) == "string" or not dest) | 150 | assert(type(dest) == "string" or not dest) |
134 | 151 | ||
135 | local name = dir.base_name(rock_file):match("(.*)%.[^.]*%.rock") | 152 | local name = dir.base_name(url):match("(.*)%.[^.]*%.rock") |
136 | 153 | local tmpname = "luarocks-rock-" .. name | |
137 | local err, errcode | 154 | |
138 | rock_file, err, errcode = fetch.fetch_url_at_temp_dir(rock_file,"luarocks-rock-"..name) | 155 | local rock_file, err, errcode = fetch.fetch_url_at_temp_dir(url, tmpname) |
139 | if not rock_file then | 156 | if not rock_file then |
140 | return nil, "Could not fetch rock file: " .. err, errcode | 157 | return nil, "Could not fetch rock file: " .. err, errcode |
141 | end | 158 | end |
142 | 159 | ||
160 | local sig_file | ||
161 | if verify then | ||
162 | sig_file, err = fetch_and_verify_signature_for(url, rock_file, tmpname) | ||
163 | if err then | ||
164 | return nil, err | ||
165 | end | ||
166 | end | ||
167 | |||
143 | rock_file = fs.absolute_name(rock_file) | 168 | rock_file = fs.absolute_name(rock_file) |
169 | |||
144 | local unpack_dir | 170 | local unpack_dir |
145 | if dest then | 171 | if dest then |
146 | unpack_dir = dest | 172 | unpack_dir = dest |
@@ -163,6 +189,12 @@ function fetch.fetch_and_unpack_rock(rock_file, dest) | |||
163 | if not ok then | 189 | if not ok then |
164 | return nil, "Failed unpacking rock file: " .. rock_file .. ": " .. err | 190 | return nil, "Failed unpacking rock file: " .. rock_file .. ": " .. err |
165 | end | 191 | end |
192 | if sig_file then | ||
193 | ok, err = fs.copy(sig_file, ".") | ||
194 | if not ok then | ||
195 | return nil, "Failed copying signature file" | ||
196 | end | ||
197 | end | ||
166 | fs.pop_dir() | 198 | fs.pop_dir() |
167 | return unpack_dir | 199 | return unpack_dir |
168 | end | 200 | end |
@@ -210,35 +242,44 @@ end | |||
210 | -- @param filename string: Local or remote filename of a rockspec. | 242 | -- @param filename string: Local or remote filename of a rockspec. |
211 | -- @param location string or nil: Where to download. If not given, | 243 | -- @param location string or nil: Where to download. If not given, |
212 | -- a temporary dir is created. | 244 | -- a temporary dir is created. |
245 | -- @param verify boolean: if true, download and verify signature for rockspec | ||
213 | -- @return table or (nil, string, [string]): A table representing the rockspec | 246 | -- @return table or (nil, string, [string]): A table representing the rockspec |
214 | -- or nil followed by an error message and optional error code. | 247 | -- or nil followed by an error message and optional error code. |
215 | function fetch.load_rockspec(filename, location) | 248 | function fetch.load_rockspec(url, location, verify) |
216 | assert(type(filename) == "string") | 249 | assert(type(url) == "string") |
217 | 250 | ||
218 | local name | 251 | local name |
219 | local basename = dir.base_name(filename) | 252 | local basename = dir.base_name(url) |
220 | if basename == "rockspec" then | 253 | if basename == "rockspec" then |
221 | name = "rockspec" | 254 | name = "rockspec" |
222 | else | 255 | else |
223 | name = basename:match("(.*)%.rockspec") | 256 | name = basename:match("(.*)%.rockspec") |
224 | if not name then | 257 | if not name then |
225 | return nil, "Filename '"..filename.."' does not look like a rockspec." | 258 | return nil, "Filename '"..url.."' does not look like a rockspec." |
226 | end | 259 | end |
227 | end | 260 | end |
228 | 261 | ||
229 | local err, errcode | 262 | local tmpname = "luarocks-rockspec-"..name |
263 | local filename, err, errcode | ||
230 | if location then | 264 | if location then |
231 | local ok, err = fs.change_dir(location) | 265 | local ok, err = fs.change_dir(location) |
232 | if not ok then return nil, err end | 266 | if not ok then return nil, err end |
233 | filename, err = fetch.fetch_url(filename) | 267 | filename, err = fetch.fetch_url(url) |
234 | fs.pop_dir() | 268 | fs.pop_dir() |
235 | else | 269 | else |
236 | filename, err, errcode = fetch.fetch_url_at_temp_dir(filename,"luarocks-rockspec-"..name) | 270 | filename, err, errcode = fetch.fetch_url_at_temp_dir(url, tmpname) |
237 | end | 271 | end |
238 | if not filename then | 272 | if not filename then |
239 | return nil, err, errcode | 273 | return nil, err, errcode |
240 | end | 274 | end |
241 | 275 | ||
276 | if verify then | ||
277 | local _, err = fetch_and_verify_signature_for(url, filename, tmpname) | ||
278 | if err then | ||
279 | return nil, err | ||
280 | end | ||
281 | end | ||
282 | |||
242 | return fetch.load_local_rockspec(filename) | 283 | return fetch.load_local_rockspec(filename) |
243 | end | 284 | end |
244 | 285 | ||
diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua index 3955af3d..336b9167 100644 --- a/src/luarocks/pack.lua +++ b/src/luarocks/pack.lua | |||
@@ -14,6 +14,7 @@ local util = require("luarocks.util") | |||
14 | local dir = require("luarocks.dir") | 14 | local dir = require("luarocks.dir") |
15 | local manif = require("luarocks.manif") | 15 | local manif = require("luarocks.manif") |
16 | local search = require("luarocks.search") | 16 | local search = require("luarocks.search") |
17 | local signing = require("luarocks.signing") | ||
17 | 18 | ||
18 | --- Create a source rock. | 19 | --- Create a source rock. |
19 | -- Packages a rockspec and its required source files in a rock | 20 | -- Packages a rockspec and its required source files in a rock |
@@ -125,7 +126,26 @@ function pack.pack_installed_rock(query, tree) | |||
125 | return rock_file | 126 | return rock_file |
126 | end | 127 | end |
127 | 128 | ||
128 | function pack.pack_binary_rock(name, version, cmd) | 129 | function pack.report_and_sign_local_file(file, err, sign) |
130 | if err then | ||
131 | return nil, err | ||
132 | end | ||
133 | local sigfile | ||
134 | if sign then | ||
135 | sigfile, err = signing.sign_file(file) | ||
136 | util.printout() | ||
137 | end | ||
138 | util.printout("Packed: "..file) | ||
139 | if sigfile then | ||
140 | util.printout("Sigature stored in: "..sigfile) | ||
141 | end | ||
142 | if err then | ||
143 | return nil, err | ||
144 | end | ||
145 | return true | ||
146 | end | ||
147 | |||
148 | function pack.pack_binary_rock(name, version, sign, cmd) | ||
129 | 149 | ||
130 | -- The --pack-binary-rock option for "luarocks build" basically performs | 150 | -- The --pack-binary-rock option for "luarocks build" basically performs |
131 | -- "luarocks build" on a temporary tree and then "luarocks pack". The | 151 | -- "luarocks build" on a temporary tree and then "luarocks pack". The |
@@ -150,7 +170,8 @@ function pack.pack_binary_rock(name, version, cmd) | |||
150 | rname, rversion = name, version | 170 | rname, rversion = name, version |
151 | end | 171 | end |
152 | local query = queries.new(rname, rversion) | 172 | local query = queries.new(rname, rversion) |
153 | return pack.pack_installed_rock(query, temp_dir) | 173 | local file, err = pack.pack_installed_rock(query, temp_dir) |
174 | return pack.report_and_sign_local_file(file, err, sign) | ||
154 | end | 175 | end |
155 | 176 | ||
156 | return pack | 177 | return pack |
diff --git a/src/luarocks/signing.lua b/src/luarocks/signing.lua index 7503768e..2e61041e 100644 --- a/src/luarocks/signing.lua +++ b/src/luarocks/signing.lua | |||
@@ -3,13 +3,25 @@ local signing = {} | |||
3 | local cfg = require("luarocks.core.cfg") | 3 | local cfg = require("luarocks.core.cfg") |
4 | local fs = require("luarocks.fs") | 4 | local fs = require("luarocks.fs") |
5 | 5 | ||
6 | function signing.sign_file(file) | 6 | local function get_gpg() |
7 | local vars = cfg.variables | 7 | local vars = cfg.variables |
8 | local gpg_ok, err = fs.is_tool_available(vars.GPG, "gpg") | 8 | local gpg = vars.GPG |
9 | local gpg_ok, err = fs.is_tool_available(gpg, "gpg") | ||
9 | if not gpg_ok then | 10 | if not gpg_ok then |
10 | return nil, err | 11 | return nil, err |
11 | end | 12 | end |
12 | local gpg = vars.GPG | 13 | return gpg |
14 | end | ||
15 | |||
16 | function signing.signature_url(url) | ||
17 | return url .. ".asc" | ||
18 | end | ||
19 | |||
20 | function signing.sign_file(file) | ||
21 | local gpg, err = get_gpg() | ||
22 | if not gpg then | ||
23 | return nil, err | ||
24 | end | ||
13 | 25 | ||
14 | local sigfile = file .. ".asc" | 26 | local sigfile = file .. ".asc" |
15 | if fs.execute(gpg, "--armor", "--output", sigfile, "--detach-sign", file) then | 27 | if fs.execute(gpg, "--armor", "--output", sigfile, "--detach-sign", file) then |
@@ -19,4 +31,18 @@ function signing.sign_file(file) | |||
19 | end | 31 | end |
20 | end | 32 | end |
21 | 33 | ||
34 | function signing.verify_signature(file, sigfile) | ||
35 | local gpg, err = get_gpg() | ||
36 | if not gpg then | ||
37 | return nil, err | ||
38 | end | ||
39 | |||
40 | if fs.execute(gpg, "--verify", sigfile, file) then | ||
41 | return true | ||
42 | else | ||
43 | return nil, "GPG returned a verification error" | ||
44 | end | ||
45 | |||
46 | end | ||
47 | |||
22 | return signing | 48 | return signing |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index e370e688..2ad59d46 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
@@ -162,6 +162,7 @@ local supported_flags = { | |||
162 | ["tree"] = "<path>", | 162 | ["tree"] = "<path>", |
163 | ["user-config"] = true, | 163 | ["user-config"] = true, |
164 | ["verbose"] = true, | 164 | ["verbose"] = true, |
165 | ["verify"] = true, | ||
165 | ["version"] = true, | 166 | ["version"] = true, |
166 | } | 167 | } |
167 | 168 | ||