mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-09 07:15:11 -04:00
openos improvements
1. if /home is readonly, a helpful message is displayed tell the user to run install 2. remove -i from `cp` alias because a bunch of people complain about it 3. `install` now does not clobber /etc/rc.cfg nor /home/.shrc
This commit is contained in:
parent
4857395e6a
commit
09505e6cff
@ -1 +1 @@
|
||||
{label = "OpenOS", reboot=true, setlabel=true, setboot=true}
|
||||
{label = "OpenOS", reboot=true, setlabel=true, setboot=true, noclobber={"etc/rc.cfg","home/.shrc"}}
|
||||
|
@ -30,7 +30,7 @@ options =
|
||||
P = options.P,
|
||||
v = options.v,
|
||||
x = options.x,
|
||||
skip = options.skip,
|
||||
skip = {options.skip},
|
||||
}
|
||||
|
||||
return transfer.batch(args, options)
|
||||
|
@ -1,6 +1,4 @@
|
||||
local computer = require("computer")
|
||||
local shell = require("shell")
|
||||
|
||||
local options
|
||||
|
||||
do
|
||||
@ -12,21 +10,23 @@ do
|
||||
options = basic(...)
|
||||
end
|
||||
|
||||
if not options then return end
|
||||
if not options then
|
||||
return
|
||||
end
|
||||
|
||||
if computer.freeMemory() < 50000 then
|
||||
print("Low memory, collecting garbage")
|
||||
for i=1,20 do os.sleep(0) end
|
||||
for i = 1, 20 do
|
||||
os.sleep(0)
|
||||
end
|
||||
end
|
||||
|
||||
local cp, reason = loadfile(shell.resolve("cp", "lua"), "bt", _G)
|
||||
assert(cp, reason)
|
||||
|
||||
local ok, ec = pcall(cp, table.unpack(options.cp_args))
|
||||
assert(ok, ec)
|
||||
|
||||
if ec ~= nil and ec ~= 0 then
|
||||
return ec
|
||||
local transfer = require("tools/transfer")
|
||||
for _, inst in ipairs(options.cp_args) do
|
||||
local ec = transfer.batch(table.unpack(inst))
|
||||
if ec ~= nil and ec ~= 0 then
|
||||
return ec
|
||||
end
|
||||
end
|
||||
|
||||
print("Installation complete!")
|
||||
@ -44,7 +44,7 @@ end
|
||||
|
||||
if options.reboot then
|
||||
io.write("Reboot now? [Y/n] ")
|
||||
if ((io.read() or "n").."y"):match("^%s*[Yy]") then
|
||||
if ((io.read() or "n") .. "y"):match("^%s*[Yy]") then
|
||||
print("\nRebooting now!\n")
|
||||
computer.shutdown(true)
|
||||
end
|
||||
|
@ -24,7 +24,7 @@ options =
|
||||
i = options.i,
|
||||
v = options.v,
|
||||
n = options.n, -- no clobber
|
||||
skip = options.skip,
|
||||
skip = {options.skip},
|
||||
P = true, -- move operations always preserve
|
||||
r = true, -- move is allowed to move entire dirs
|
||||
x = true, -- cannot move mount points
|
||||
|
@ -32,3 +32,7 @@ for _,line in ipairs(lines) do
|
||||
io.write(borders[2][1], " ", line, (" "):rep(maxLine - #line + 1), borders[2][3], " \n")
|
||||
end
|
||||
io.write(borders[3][1] .. string.rep(borders[3][2], maxLine + 2) .. borders[3][3] .. "\n")
|
||||
|
||||
if require("filesystem").get("home").isReadOnly() then
|
||||
io.write("\27[33mNote: Your home directory is readonly. Run `install` and reboot.\27[m\n")
|
||||
end
|
||||
|
@ -20,7 +20,6 @@ shell.setAlias("cls", "clear")
|
||||
shell.setAlias("rs", "redstone")
|
||||
shell.setAlias("view", "edit -r")
|
||||
shell.setAlias("help", "man")
|
||||
shell.setAlias("cp", "cp -i")
|
||||
shell.setAlias("l", "ls -lhp")
|
||||
shell.setAlias("..", "cd ..")
|
||||
shell.setAlias("df", "df -h")
|
||||
|
@ -27,7 +27,7 @@ local utils
|
||||
|
||||
local rootfs = fs.get("/")
|
||||
if not rootfs then
|
||||
io.stderr:write("no root filesystem, aborting\n");
|
||||
io.stderr:write("no root filesystem, aborting\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
@ -86,11 +86,13 @@ for dev, path in pairs(devices) do
|
||||
io.stderr:write("Cannot install to " .. options.to .. ", it is read only\n")
|
||||
os.exit(1)
|
||||
end
|
||||
elseif specified or
|
||||
not (source_filter and address:find(source_filter, 1, true) == 1) and -- specified for source
|
||||
not target_filter and
|
||||
address ~= tmpAddress then
|
||||
table.insert(targets, {dev=dev, path=install_path, specified=specified})
|
||||
elseif
|
||||
specified or
|
||||
not (source_filter and address:find(source_filter, 1, true) == 1) and -- specified for source
|
||||
not target_filter and
|
||||
address ~= tmpAddress
|
||||
then
|
||||
table.insert(targets, {dev = dev, path = install_path, specified = specified})
|
||||
end
|
||||
end
|
||||
|
||||
@ -105,11 +107,11 @@ for dev, path in pairs(devices) do
|
||||
local install_path = dev == source_filter_dev and options.from or path
|
||||
local specified = source_filter and address:find(source_filter, 1, true) == 1
|
||||
|
||||
if fs.list(install_path)()
|
||||
and (specified or
|
||||
not source_filter and
|
||||
address ~= tmpAddress and
|
||||
not (address == rootfs.address and not rootfs.isReadOnly())) then
|
||||
if
|
||||
fs.list(install_path)() and
|
||||
(specified or
|
||||
not source_filter and address ~= tmpAddress and not (address == rootfs.address and not rootfs.isReadOnly()))
|
||||
then
|
||||
local prop = {}
|
||||
local prop_path = path .. "/.prop"
|
||||
local prop_file = fs.open(prop_path)
|
||||
@ -125,7 +127,7 @@ for dev, path in pairs(devices) do
|
||||
end
|
||||
if not prop.ignore then
|
||||
if not label or label:lower() == (prop.label or dev.getLabel() or ""):lower() then
|
||||
table.insert(sources, {dev=dev, path=install_path, prop=prop, specified=specified})
|
||||
table.insert(sources, {dev = dev, path = install_path, prop = prop, specified = specified})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -137,23 +139,24 @@ if #sources ~= 1 then
|
||||
utils = loadfile(utils_path, "bt", _G)
|
||||
source = utils("select", "sources", options, sources)
|
||||
end
|
||||
if not source then return end
|
||||
if not source then
|
||||
return
|
||||
end
|
||||
|
||||
options =
|
||||
{
|
||||
from = source.path .. '/',
|
||||
fromDir = fs.canonical(options.fromDir or source.prop.fromDir or ""),
|
||||
root = fs.canonical(options.root or options.toDir or source.prop.root or ""),
|
||||
update = options.update or options.u,
|
||||
label = source.prop.label or label,
|
||||
options = {
|
||||
from = source.path .. "/",
|
||||
fromDir = fs.canonical(options.fromDir or source.prop.fromDir or ""),
|
||||
root = fs.canonical(options.root or options.toDir or source.prop.root or ""),
|
||||
update = options.update or options.u,
|
||||
label = source.prop.label or label,
|
||||
setlabel = not (options.nosetlabel or options.nolabelset) and source.prop.setlabel,
|
||||
setboot = not (options.nosetboot or options.noboot) and source.prop.setboot,
|
||||
reboot = not options.noreboot and source.prop.reboot,
|
||||
setboot = not (options.nosetboot or options.noboot) and source.prop.setboot,
|
||||
reboot = not options.noreboot and source.prop.reboot
|
||||
}
|
||||
local source_display = options.label or source.dev.getLabel() or source.path
|
||||
|
||||
-- Remove the source from the target options
|
||||
for index,entry in ipairs(targets) do
|
||||
for index, entry in ipairs(targets) do
|
||||
if entry.dev == source.dev then
|
||||
table.remove(targets, index)
|
||||
target = targets[1]
|
||||
@ -162,47 +165,67 @@ end
|
||||
|
||||
-- Ask the user to select a target
|
||||
if #targets ~= 1 then
|
||||
if #sources == 1 then
|
||||
io.write(source_display, " selected for install\n")
|
||||
end
|
||||
if #sources == 1 then
|
||||
io.write(source_display, " selected for install\n")
|
||||
end
|
||||
|
||||
utils = utils or loadfile(utils_path, "bt", _G)
|
||||
utils = utils or loadfile(utils_path, "bt", _G)
|
||||
target = utils("select", "targets", options, targets)
|
||||
end
|
||||
if not target then return end
|
||||
if not target then
|
||||
return
|
||||
end
|
||||
|
||||
options.to = target.path .. '/'
|
||||
options.to = target.path .. "/"
|
||||
|
||||
local cp_args =
|
||||
{
|
||||
"-vrx" .. (options.update and "ui" or ""),
|
||||
"--skip=.prop",
|
||||
fs.concat(options.from, options.fromDir) .. "/.",
|
||||
fs.concat(options.to , options.root)
|
||||
local function resolveFrom(path)
|
||||
return fs.concat(options.from, options.fromDir) .. "/" .. path
|
||||
end
|
||||
|
||||
local fullTargetPath = fs.concat(options.to, options.root)
|
||||
local transfer_args = {
|
||||
{
|
||||
{resolveFrom("."), fullTargetPath},
|
||||
{
|
||||
cmd = "cp",
|
||||
r = true, v = true, x = true, u = options.update, i = options.update,
|
||||
skip = {resolveFrom(".prop")},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if source.prop.noclobber and #source.prop.noclobber > 0 then
|
||||
local noclobber_opts = {cmd = "cp", v = true, n = true}
|
||||
for _, noclobber in ipairs(source.prop.noclobber or {}) do
|
||||
local noclobberFrom = resolveFrom(noclobber)
|
||||
local noclobberTo = fs.concat(fullTargetPath, noclobber)
|
||||
table.insert(transfer_args[1][2].skip, noclobberFrom)
|
||||
table.insert(transfer_args, {{noclobberFrom, noclobberTo}, noclobber_opts})
|
||||
end
|
||||
end
|
||||
|
||||
local special_target = ""
|
||||
if #targets > 1 or target_filter or source_filter then
|
||||
special_target = " to " .. cp_args[4]
|
||||
special_target = " to " .. transfer_args[1].args[2]
|
||||
end
|
||||
|
||||
io.write("Install " .. source_display .. special_target .. "? [Y/n] ")
|
||||
if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
|
||||
if not ((io.read() or "n") .. "y"):match("^%s*[Yy]") then
|
||||
io.write("Installation cancelled\n")
|
||||
os.exit()
|
||||
end
|
||||
|
||||
local installer_path = options.from .. "/.install"
|
||||
if fs.exists(installer_path) then
|
||||
local installer, reason = loadfile(installer_path, "bt", setmetatable({install=options}, {__index = _G}))
|
||||
local installer, reason = loadfile(installer_path, "bt", setmetatable({install = options}, {__index = _G}))
|
||||
if not installer then
|
||||
io.stderr:write("installer failed to load: " .. tostring(reason) .. '\n')
|
||||
io.stderr:write("installer failed to load: " .. tostring(reason) .. "\n")
|
||||
os.exit(1)
|
||||
end
|
||||
os.exit(installer())
|
||||
end
|
||||
|
||||
options.cp_args = cp_args
|
||||
options.cp_args = transfer_args
|
||||
options.target = target
|
||||
|
||||
return options
|
||||
|
@ -93,7 +93,7 @@ function lib.recurse(fromPath, toPath, options, origin, top)
|
||||
local toPathFull = shell.resolve(toPath)
|
||||
local mv = options.cmd == "mv"
|
||||
local verbose = options.v and (not mv or top)
|
||||
if select(2, fromPathFull:find(options.skip)) == #fromPathFull then
|
||||
if options.skip[fromPathFull] then
|
||||
status(verbose, string.format("skipping %s", fromPath))
|
||||
return true
|
||||
end
|
||||
@ -221,8 +221,13 @@ function lib.batch(args, options)
|
||||
-- standardized options
|
||||
options.i = options.i and not options.f
|
||||
options.P = options.P or options.r
|
||||
options.skip = text.escapeMagic(options.skip or "")
|
||||
|
||||
|
||||
local skips = options.skip or {}
|
||||
options.skip = {}
|
||||
for _, skip_item in ipairs(skips) do
|
||||
options.skip[shell.resolve(skip_item)] = true
|
||||
end
|
||||
|
||||
local origin = {}
|
||||
for dev,path in fs.mounts() do
|
||||
origin[path] = dev
|
||||
|
Loading…
x
Reference in New Issue
Block a user