1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
--- Module implementing the LuaRocks "new_version" command.
-- Utility function that writes a new rockspec, updating data from a previous one.
local new_version = {}
local util = require("luarocks.util")
local download = require("luarocks.download")
local fetch = require("luarocks.fetch")
local persist = require("luarocks.persist")
local fs = require("luarocks.fs")
local dir = require("luarocks.dir")
local type_rockspec = require("luarocks.type.rockspec")
function new_version.add_to_parser(parser)
local cmd = parser:command("new_version", [[
This is a utility function that writes a new rockspec, updating data from a
previous one.
If a package name is given, it downloads the latest rockspec from the default
server. If a rockspec is given, it uses it instead. If no argument is given, it
looks for a rockspec same way 'luarocks make' does.
If the version number is not given and tag is passed using --tag, it is used as
the version, with 'v' removed from beginning. Otherwise, it only increments the
revision number of the given (or downloaded) rockspec.
If a URL is given, it replaces the one from the old rockspec with the given URL.
If a URL is not given and a new version is given, it tries to guess the new URL
by replacing occurrences of the version number in the URL or tag; if the guessed
URL is invalid, the old URL is restored. It also tries to download the new URL
to determine the new MD5 checksum.
If a tag is given, it replaces the one from the old rockspec. If there is an old
tag but no new one passed, it is guessed in the same way URL is.
If a directory is not given, it defaults to the current directory.
WARNING: it writes the new rockspec to the given directory, overwriting the file
if it already exists.]], util.see_also())
:summary("Auto-write a rockspec for a new version of a rock.")
cmd:argument("rock", "Package name or rockspec.")
:args("?")
cmd:argument("new_version", "New version of the rock.")
:args("?")
cmd:argument("new_url", "New URL of the rock.")
:args("?")
cmd:option("--dir", "Output directory for the new rockspec.")
cmd:option("--tag", "New SCM tag.")
end
local function try_replace(tbl, field, old, new)
if not tbl[field] then
return false
end
local old_field = tbl[field]
local new_field = tbl[field]:gsub(old, new)
if new_field ~= old_field then
util.printout("Guessing new '"..field.."' field as "..new_field)
tbl[field] = new_field
return true
end
return false
end
-- Try to download source file using URL from a rockspec.
-- If it specified MD5, update it.
-- @return (true, false) if MD5 was not specified or it stayed same,
-- (true, true) if MD5 changed, (nil, string) on error.
local function check_url_and_update_md5(out_rs, invalid_is_error)
local file, temp_dir = fetch.fetch_url_at_temp_dir(out_rs.source.url, "luarocks-new-version-"..out_rs.package)
if not file then
if invalid_is_error then
return nil, "invalid URL - "..temp_dir
end
util.warning("invalid URL - "..temp_dir)
return true, false
end
do
local inferred_dir, found_dir = fetch.find_base_dir(file, temp_dir, out_rs.source.url, out_rs.source.dir)
if not inferred_dir then
return nil, found_dir
end
if found_dir and found_dir ~= inferred_dir then
out_rs.source.dir = found_dir
end
end
if file then
if out_rs.source.md5 then
util.printout("File successfully downloaded. Updating MD5 checksum...")
local new_md5, err = fs.get_md5(file)
if not new_md5 then
return nil, err
end
local old_md5 = out_rs.source.md5
out_rs.source.md5 = new_md5
return true, new_md5 ~= old_md5
else
util.printout("File successfully downloaded.")
return true, false
end
end
end
local function update_source_section(out_rs, url, tag, old_ver, new_ver)
if tag then
out_rs.source.tag = tag
end
if url then
out_rs.source.url = url
return check_url_and_update_md5(out_rs)
end
if new_ver == old_ver then
return true
end
if out_rs.source.dir then
try_replace(out_rs.source, "dir", old_ver, new_ver)
end
if out_rs.source.file then
try_replace(out_rs.source, "file", old_ver, new_ver)
end
local old_url = out_rs.source.url
if try_replace(out_rs.source, "url", old_ver, new_ver) then
local ok, md5_changed = check_url_and_update_md5(out_rs, true)
if ok then
return ok, md5_changed
end
out_rs.source.url = old_url
end
if tag or try_replace(out_rs.source, "tag", old_ver, new_ver) then
return true
end
-- Couldn't replace anything significant, use the old URL.
local ok, md5_changed = check_url_and_update_md5(out_rs)
if not ok then
return nil, md5_changed
end
if md5_changed then
util.warning("URL is the same, but MD5 has changed. Old rockspec is broken.")
end
return true
end
function new_version.command(args)
if not args.rock then
local err
args.rock, err = util.get_default_rockspec()
if not args.rock then
return nil, err
end
end
local filename, err
if args.rock:match("rockspec$") then
filename, err = fetch.fetch_url(args.rock)
if not filename then
return nil, err
end
else
filename, err = download.download("rockspec", args.rock:lower())
if not filename then
return nil, err
end
end
local valid_rs, err = fetch.load_rockspec(filename)
if not valid_rs then
return nil, err
end
local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$")
local new_ver, new_rev
if args.tag and not args.new_version then
args.new_version = args.tag:gsub("^v", "")
end
local out_dir
if args.dir then
out_dir = dir.normalize(args.dir)
end
if args.new_version then
new_ver, new_rev = args.new_version:match("(.*)%-(%d+)$")
new_rev = tonumber(new_rev)
if not new_rev then
new_ver = args.new_version
new_rev = 1
end
else
new_ver = old_ver
new_rev = tonumber(old_rev) + 1
end
local new_rockver = new_ver:gsub("-", "")
local out_rs, err = persist.load_into_table(filename)
local out_name = out_rs.package:lower()
out_rs.version = new_rockver.."-"..new_rev
local ok, err = update_source_section(out_rs, args.new_url, args.tag, old_ver, new_ver)
if not ok then return nil, err end
if out_rs.build and out_rs.build.type == "module" then
out_rs.build.type = "builtin"
end
local out_filename = out_name.."-"..new_rockver.."-"..new_rev..".rockspec"
if out_dir then
out_filename = dir.path(out_dir, out_filename)
fs.make_dir(out_dir)
end
persist.save_from_table(out_filename, out_rs, type_rockspec.order)
util.printout("Wrote "..out_filename)
local valid_out_rs, err = fetch.load_local_rockspec(out_filename)
if not valid_out_rs then
return nil, "Failed loading generated rockspec: "..err
end
return true
end
return new_version
|