Skip to content

Commit 2efce44

Browse files
committed
Implement install patching
1 parent 0662a5f commit 2efce44

File tree

10 files changed

+119
-80
lines changed

10 files changed

+119
-80
lines changed

bsrocks/bin/bsrocks.lua

+1-9
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,4 @@ addCommand({
8989
-- Default to printing help messages
9090
local foundCommand = getCommand(... or "help")
9191
local args = {...}
92-
xpcall(
93-
function()
94-
return foundCommand.execute(select(2, unpack(args)))
95-
end,
96-
function(message)
97-
printError(message)
98-
print(utils.traceback())
99-
end
100-
)
92+
return foundCommand.execute(select(2, unpack(args)))

bsrocks/commands/admin/add.lua

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
local download = require "bsrocks.downloaders"
22
local fileWrapper = require "bsrocks.lib.files"
3+
local patchDirectory = require "bsrocks.lib.settings".patchDirectory
34
local rockspec = require "bsrocks.rocks.rockspec"
45
local serialize = require "bsrocks.lib.serialize"
5-
local settings = require "bsrocks.lib.settings"
6-
7-
local patchDirectory = settings.patchDirectory
8-
local servers = settings.servers
96

107
local function execute(name, version)
118
if not name then error("Expected name", 0) end
129

13-
local server, manifest = rockspec.findRock(servers, name)
10+
local server, manifest = rockspec.findRock(name)
1411
if not server then
1512
error("Cannot find '" .. name .. "'", 0)
1613
end

bsrocks/commands/admin/fetch.lua

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ local log = require "bsrocks.lib.utils".log
44
local patchspec = require "bsrocks.rocks.patchspec"
55
local rockspec = require "bsrocks.rocks.rockspec"
66
local serialize = require "bsrocks.lib.serialize"
7-
local settings = require "bsrocks.lib.settings"
8-
9-
local patchDirectory = settings.patchDirectory
10-
local servers = settings.servers
7+
local patchDirectory = require "bsrocks.lib.settings".patchDirectory
118

129
local function execute(...)
1310
local patched, force
@@ -38,7 +35,7 @@ local function execute(...)
3835
error("Patchspec" .. name .. " has no version", 0)
3936
end
4037

41-
local server, manifest = rockspec.findRock(servers, name)
38+
local server, manifest = rockspec.findRock(name)
4239
if not server then
4340
error("Cannot find '" .. name .. "'", 0)
4441
end

bsrocks/downloaders/github.lua

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
--- A downloader for GitHub repositories
22

3-
local download = require "bsrocks.downloaders.download"
3+
local tree = require "bsrocks.downloaders.tree"
44

5-
return function(source, files, settings)
5+
return function(source, files)
66
local url = source.url
77
if not url then return end
88

@@ -15,5 +15,5 @@ return function(source, files, settings)
1515
end
1616

1717
print("Downloading " .. repo .. "@" .. branch)
18-
return download('https://raw.github.com/'..repo..'/'..branch..'/', files, settings.tries, settings.callback)
18+
return tree('https://raw.github.com/'..repo..'/'..branch..'/', files)
1919
end

bsrocks/downloaders/init.lua

+1-19
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,9 @@ local downloaders = {
22
require "bsrocks.downloaders.github",
33
}
44

5-
local tries = require "bsrocks.lib.settings".tries
6-
7-
local settings = {
8-
tries = tries,
9-
callback = function(success, path, count, total)
10-
if not success then
11-
local x, y = term.getCursorPos()
12-
term.setCursorPos(1, y)
13-
term.clearLine()
14-
printError("Cannot download " .. path)
15-
end
16-
17-
local x, y = term.getCursorPos()
18-
term.setCursorPos(1, y)
19-
term.clearLine()
20-
write(("Downloading: %s/%s (%s%%)"):format(count, total, count / total * 100))
21-
end
22-
}
235
return function(source, files)
246
for _, downloader in ipairs(downloaders) do
25-
local files = downloader(source, files, settings)
7+
local files = downloader(source, files)
268
if files then
279
print()
2810
return files

bsrocks/downloaders/download.lua bsrocks/downloaders/tree.lua

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1+
local function callback(success, path, count, total)
2+
if not success then
3+
local x, y = term.getCursorPos()
4+
term.setCursorPos(1, y)
5+
term.clearLine()
6+
printError("Cannot download " .. path)
7+
end
8+
9+
local x, y = term.getCursorPos()
10+
term.setCursorPos(1, y)
11+
term.clearLine()
12+
write(("Downloading: %s/%s (%s%%)"):format(count, total, count / total * 100))
13+
end
14+
15+
local tries = require "bsrocks.lib.settings".tries
16+
117
--- Download individual files
218
-- @tparam string prefix The url prefix to use
319
-- @tparam table files The list of files to download
420
-- @tparam int tries Number of times to attempt to download
5-
-- @tparam (success:boolean, path:string, count:int, total:int)->nil callback Function to call on download progress
6-
return function(prefix, files, tries, callback)
21+
local function tree(prefix, files)
722
local result = {}
823

924
local count = 0
@@ -47,3 +62,5 @@ return function(prefix, files, tries, callback)
4762

4863
return result
4964
end
65+
66+
return tree

bsrocks/rocks/dependencies.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ local function parseVersion(vstring)
109109
-- extract a word
110110
token, rest = vstring:match("^(%a+)[%.%-%_]*(.*)")
111111
if not token then
112-
util.printerr("Warning: version number '"..vstring.."' could not be parsed.")
112+
error("Warning: version number '"..vstring.."' could not be parsed.", 0)
113113

114114
if not version[i] then version[i] = 0 end
115115
break

bsrocks/rocks/install.lua

+38-18
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,36 @@
11
local dependencies = require "bsrocks.rocks.dependencies"
22
local download = require "bsrocks.downloaders"
33
local fileWrapper = require "bsrocks.lib.files"
4+
local log = require "bsrocks.lib.utils".log
5+
local patchspec = require "bsrocks.rocks.patchspec"
46
local rockspec = require "bsrocks.rocks.rockspec"
57
local serialize = require "bsrocks.lib.serialize"
68
local settings = require "bsrocks.lib.settings"
7-
local utils = require "bsrocks.lib.utils"
9+
local tree = require "bsrocks.downloaders.tree"
810

911
local installDirectory = settings.installDirectory
10-
local servers = settings.servers
11-
local patchServers = settings.patchServers
1212

1313
local fetched = false
1414
local installed = {}
1515

16-
local function save(rockS)
17-
local files = rockspec.extractFiles(rockS)
16+
local function save(rockS, patchS)
17+
local blacklist = {}
18+
if patchspec and patchspec.remove then
19+
for _, v in ipairs(patchspec.remove) do blacklist[v] = true end
20+
end
1821

22+
local files = rockspec.extractFiles(rockS, blacklist)
1923
local downloaded = download(rockS.source, files)
2024

2125
if not downloaded then
22-
error("Cannot find downloader for " .. rockS.source.url)
26+
error("Cannot find downloader for " .. rockS.source.url, 0)
27+
end
28+
29+
if patchS then
30+
local patchFiles = rockspec.extractFiles(patchS)
31+
local downloadPatch = tree(patchFiles.server .. '/' .. rockS.name, patchFiles)
32+
33+
files = applyPatches(downloaded, downloadPatch, patchS.patches or {}, patchS.added or {}, patchS.removed or {})
2334
end
2435

2536
rockspec.saveFiles(rockS, downloaded, installDirectory)
@@ -49,21 +60,30 @@ local function getInstalled()
4960
end
5061

5162
local function install(name, version, constraints)
52-
local server, manifest = rockspec.findRock(servers, name)
63+
-- Do the cheapest action ASAP
64+
local versions = getInstalled()
65+
local current = versions[name]
66+
if current and (version == nil or current.version == version) then
67+
error("Already installed", 0)
68+
end
69+
70+
local server, manifest = rockspec.findRock(name)
71+
5372
if not server then
54-
error("Cannot find '" .. name .. "'")
73+
error("Cannot find '" .. name .. "'", 0)
5574
end
5675

76+
local patchspec = patchspec.findPatchspec(name)
5777
if not version then
58-
version = rockspec.latestVersion(manifest, name, constraints)
78+
if patchspec then
79+
version = patchspec.version
80+
else
81+
version = rockspec.latestVersion(manifest, name, constraints)
82+
end
5983
end
6084

61-
local versions = getInstalled()
62-
local current = versions[name]
63-
if current then
64-
if current.version == version then
65-
error("Already installed")
66-
end
85+
if current and current.version == version then
86+
error("Already installed", 0)
6787
end
6888

6989
local rockspec = rockspec.fetchRockspec(server, name, version)
@@ -77,15 +97,15 @@ local function install(name, version, constraints)
7797
if current then
7898
local version = dependencies.parseVersion(current.version)
7999
if not dependencies.matchConstraints(version, dependency.constraints) then
80-
print("Should update " .. dependency.name .. " ( got " .. current.version .. ", need " .. deps .. ")")
100+
log("Should update " .. dependency.name .. " ( got " .. current.version .. ", need " .. deps .. ")")
81101
end
82102
else
83-
print("Installing dependency " .. name)
103+
log("Installing dependency " .. name)
84104
install(name, nil, dependency.constraints)
85105
end
86106
end
87107

88-
save(rockspec)
108+
save(rockspec, patchspec)
89109
end
90110

91111
return {

bsrocks/rocks/patchspec.lua

+35-7
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
local diff = require "bsrocks.lib.diffmatchpatch"
2-
local unserialize = require "bsrocks.lib.serialize".unserialize
32
local fileWrapper = require "bsrocks.lib.files"
4-
local patchDirectory = require "bsrocks.lib.settings".patchDirectory
3+
local log = require "bsrocks.lib.utils".log
4+
local settings = require "bsrocks.lib.settings"
5+
local unserialize = require "bsrocks.lib.serialize".unserialize
6+
7+
local patchDirectory, servers = settings.patchDirectory, settings.patchServers
58

69
local cache = {}
7-
local function fetchPatchspec(servers, name)
10+
local function findPatchspec(name)
811
local result = cache[name] or false
912
if result then return result end
1013

14+
log("Fetching patchspec for " .. name)
15+
local patchS = name .. ".patchspec"
16+
1117
for _, server in ipairs(servers) do
12-
local handle = http.get(servers .. name)
18+
local handle = http.get(server .. patchS)
1319
if handle then
1420
local contents = handle.readAll()
1521
handle.close()
1622

17-
result = unserialize(contenets)
23+
result = unserialize(contents)
24+
result.server = server
1825
break
1926
end
2027
end
2128

22-
cache[name] = result
29+
cache[name] = result or false
2330
return result
2431
end
2532

@@ -40,6 +47,26 @@ local function getAll()
4047
return installed
4148
end
4249

50+
local function extractFiles(patch)
51+
local files, n = {}, 0
52+
53+
if patch.added then
54+
for _, file in ipairs(patch.added) do
55+
n = n + 1
56+
files[n] = file
57+
end
58+
end
59+
60+
if patch.patches then
61+
for _, file in ipairs(patch.patches) do
62+
n = n + 1
63+
files[n] = file .. ".patch"
64+
end
65+
end
66+
67+
return files
68+
end
69+
4370
local function makePatches(original, changed)
4471
local patches, remove = {}, {}
4572
local files = {}
@@ -125,8 +152,9 @@ local function applyPatches(original, files, patches, added, removed)
125152
end
126153

127154
return {
128-
fetchPatchspec = fetchPatchspec,
155+
findPatchspec = findPatchspec,
129156
makePatches = makePatches,
130157
applyPatches = applyPatches,
158+
extractFiles = extractFiles,
131159
getAll = getAll,
132160
}

0 commit comments

Comments
 (0)