From 09505e6cff410fb1bfd822eebb2b0f61f52024b3 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 21 May 2020 00:36:09 -0700 Subject: [PATCH] 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 --- .../assets/opencomputers/loot/openos/.prop | 2 +- .../opencomputers/loot/openos/bin/cp.lua | 2 +- .../opencomputers/loot/openos/bin/install.lua | 26 ++--- .../opencomputers/loot/openos/bin/mv.lua | 2 +- .../assets/opencomputers/loot/openos/etc/motd | 4 + .../opencomputers/loot/openos/etc/profile.lua | 1 - .../loot/openos/lib/core/install_basics.lua | 103 +++++++++++------- .../loot/openos/lib/tools/transfer.lua | 11 +- 8 files changed, 91 insertions(+), 60 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/openos/.prop b/src/main/resources/assets/opencomputers/loot/openos/.prop index 5cf0ed07b..3425482c1 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/.prop +++ b/src/main/resources/assets/opencomputers/loot/openos/.prop @@ -1 +1 @@ -{label = "OpenOS", reboot=true, setlabel=true, setboot=true} +{label = "OpenOS", reboot=true, setlabel=true, setboot=true, noclobber={"etc/rc.cfg","home/.shrc"}} diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua index d173e219a..3341709a6 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua @@ -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) diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua index f8410e98b..d3a39b476 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua @@ -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 diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/mv.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/mv.lua index 9567d6f64..d5f0b4796 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/mv.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/mv.lua @@ -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 diff --git a/src/main/resources/assets/opencomputers/loot/openos/etc/motd b/src/main/resources/assets/opencomputers/loot/openos/etc/motd index 0c73a8250..2d07a9b1b 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/etc/motd +++ b/src/main/resources/assets/opencomputers/loot/openos/etc/motd @@ -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 diff --git a/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua b/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua index 52e054734..6c54cb4d1 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua @@ -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") diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/install_basics.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/install_basics.lua index f139eeb3b..41b72d1cf 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/install_basics.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/install_basics.lua @@ -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 diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/tools/transfer.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/tools/transfer.lua index 3e3f4b725..ec847252f 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/tools/transfer.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/tools/transfer.lua @@ -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