v2.5.0 - Added apps for drive actions (lsdrv/lsblk, label, maindrv)
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
local agcfg = {
|
||||
["halyde"] = {
|
||||
["maindir"] = "",
|
||||
["version"] = "2.4.1",
|
||||
["version"] = "2.5.0",
|
||||
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
|
||||
["directories"] = {
|
||||
"halyde/apps",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
Usage: label [ADDRESS] [LABEL]
|
||||
Get or set a label of a component that supports labelling.
|
||||
|
||||
ADDRESS The component to use for getting or setting the label.
|
||||
eeprom The computer's EEPROM.
|
||||
halyde The drive where the Halyde installation resides in.
|
||||
slotN The slot number of the drive, in top-to-bottom order (range 7-9)
|
||||
#N The slot number of the drive, in drive space (range 1-3)
|
||||
The ID of the component, abbreviated. Must have three or more characters.
|
||||
LABEL* The label to set the component to. If not found, the current label will be printed out.
|
||||
|
||||
Examples:
|
||||
label #3 Get the label of the third drive in the computer.
|
||||
label eeprom Get the label of the EEPROM inserted in the computer.
|
||||
label slot8 Storage Set the drive at slot 8 to have the label "Storage"
|
||||
label halyde Halyde Set the label of the Halyde installation to "Halyde"
|
||||
@@ -0,0 +1,27 @@
|
||||
Usage: lsdrv [FLAGS]
|
||||
Shows all drives that are inserted into the computer.
|
||||
|
||||
FLAGS Specifies extra options when executing the command.
|
||||
-a, --all Shows every column and every component. Acts the same as '-o all -s all'.
|
||||
-o, --output [COLS] Specifies the columns to output in the output table.
|
||||
Possible columns are: "slot", "capacity", "managed", "readOnly", "id", "mount", "bootable", and "label".
|
||||
If the list of columns start with a "+", the default columns will appear first.
|
||||
Default columns are slots, capacity, the entire ID, the mount point, and the drive label.
|
||||
-s, --show [EXPR] Only list drives when the expression returns 'true'.
|
||||
-S, --sort [EXPR] Sort the output by an expression that returns a number.
|
||||
The higher the number, the lower the drive is displayed, and vice-versa.
|
||||
EXPR An expression in Lua, for filtering or sorting output.
|
||||
If this expression contains spaces, make sure to put quotation marks on them!
|
||||
Built-in variables are: "component", "computer", "type", "id", "readonly", "capacity", "managed", "eeprom", "halyde", "tmp", "proxy", "slot", and "all" (true).
|
||||
|
||||
Examples:
|
||||
lsblk Show regular drives, with the default columns.
|
||||
lsblk -a Show all storage components, with every column.
|
||||
lsblk -o +bootable Show drives, with an added "bootable" category.
|
||||
lsblk -o slot,label -s halyde Show the slot and the label of the drive where Halyde is installed.
|
||||
lsblk -o mount,capacity,label -s "not halyde" Show the mount points, capacities and labels of all drives other than Halyde.
|
||||
lsblk -s type=='filesystem' Only show managed drives.
|
||||
lsblk -s slot==1 Show all drives that aren't physical (Virtual components, tmpfs)
|
||||
lsblk -S capacity Sort the drives by capacity, in ascending order.
|
||||
lsblk -S -capacity Sort the drives by capacity, in descending order.
|
||||
lsblk -o +managed -S managed Show managed drives first, then unmanaged drives second, with an extra "managed" column.
|
||||
@@ -0,0 +1,2 @@
|
||||
Usage: maindrv
|
||||
Shows the entire ID of the drive where Halyde is installed to.
|
||||
@@ -0,0 +1,92 @@
|
||||
local component = import("component")
|
||||
local computer = import("computer")
|
||||
local args = {...}
|
||||
if not args then return print("\x1b[91mCannot get arguments.") end
|
||||
if not args[1] then
|
||||
return shell.run("help label")
|
||||
end
|
||||
local inputID = args[1]
|
||||
local comp
|
||||
|
||||
local function componentFromSlot(slotNum)
|
||||
if slotNum>=5 and slotNum<=8 then slotNum=slotNum-1 end
|
||||
for i,v in component.list() do
|
||||
if component.slot(i)==slotNum then
|
||||
comp=component.proxy(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if inputID=="eeprom" then
|
||||
comp = component.eeprom
|
||||
elseif inputID=="halyde" then
|
||||
comp = component.proxy(computer.getBootAddress())
|
||||
elseif inputID:sub(1,4)=="slot" and tonumber(inputID:sub(5)) then
|
||||
local slotNum = tonumber(inputID:sub(5))-1
|
||||
componentFromSlot(slotNum)
|
||||
elseif inputID:sub(1,1)=="#" and tonumber(inputID:sub(2)) then
|
||||
local slotNum = tonumber(inputID:sub(2))+5
|
||||
componentFromSlot(slotNum)
|
||||
elseif #inputID>=3 then
|
||||
local fullID = component.get(inputID)
|
||||
if not fullID then return print("\x1b[91mCould not find entire component ID from \""..inputID.."\".") end
|
||||
comp = component.proxy(fullID)
|
||||
else
|
||||
print("\x1b[91mAddress must have atleast 3 characters")
|
||||
return shell.run("help label")
|
||||
end
|
||||
if not comp then
|
||||
return print("\x1b[91mCould not find component from \""..inputID.."\".")
|
||||
end
|
||||
local compID = comp.address
|
||||
|
||||
local function formatID(id)
|
||||
return id:sub(1,8).."\x1b[37m"..id:sub(9).."\x1b[39m"
|
||||
end
|
||||
|
||||
local function unsupported(act)
|
||||
print("This \x1b[92m"..(comp.type or "unknown").."\x1b[39m component doesn't support "..act.." labels.\nID: "..formatID(compID))
|
||||
end
|
||||
|
||||
local function compError(act,reason)
|
||||
print("\x1b[91mAn error occured while "..act.." the label of this component.\nComponent: "..(compID or "unknown id").." ("..((comp or {}).type or "unknown type")..")\n\n"..reason)
|
||||
end
|
||||
|
||||
local function formatLabel(label)
|
||||
local res = "No label defined"
|
||||
if label then res="\""..label.."\"" end
|
||||
return res
|
||||
end
|
||||
|
||||
if type(args[2])~="string" then
|
||||
if not comp.getLabel then
|
||||
return unsupported("getting")
|
||||
end
|
||||
local label
|
||||
local success,reason = pcall(function()
|
||||
label = comp.getLabel()
|
||||
end)
|
||||
if success then
|
||||
print("Label of "..formatID(compID)..((comp.type and comp.type~="filesystem") and " ("..comp.type..")" or "")..":\n \x1b[92m"..formatLabel(label).."\x1b[39m")
|
||||
else
|
||||
compError("getting",reason)
|
||||
end
|
||||
else
|
||||
if not comp.setLabel then
|
||||
return unsupported("setting")
|
||||
end
|
||||
local newLabel = ""
|
||||
for i=2,#args do
|
||||
newLabel=newLabel..tostring(args[i])
|
||||
if i<#args then newLabel=newLabel.." " end
|
||||
end
|
||||
local label
|
||||
local success,reason = pcall(function()
|
||||
label = comp.setLabel(newLabel)
|
||||
end)
|
||||
if success then
|
||||
print("Successfully set label of "..formatID(compID)..(comp.type and " ("..comp.type..")" or "").." to:\n \x1b[92m"..formatLabel(label).."\x1b[39m")
|
||||
else
|
||||
compError("setting",reason)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,308 @@
|
||||
local component = import("component")
|
||||
local computer = import("computer")
|
||||
local unicode = import("unicode")
|
||||
|
||||
local width,height = component.gpu.getResolution()
|
||||
|
||||
local args = {...}
|
||||
local showAll = not not (table.find(args,"-a") or table.find(args,"--all"))
|
||||
|
||||
local tablePos = {}
|
||||
local tableOut = {}
|
||||
local headers = {
|
||||
["slot"]="SLOT",
|
||||
["capacity"]="CAPACITY",
|
||||
["managed"]="MANAGED",
|
||||
["readOnly"]="READ-ONLY",
|
||||
["id"]="FULL COMPONENT ID",
|
||||
["mount"]="MOUNT",
|
||||
["bootable"]="BOOTABLE",
|
||||
["label"]="LABEL"
|
||||
}
|
||||
local headerAlign = {
|
||||
["slot"]=false,
|
||||
["capacity"]=true,
|
||||
["managed"]=false,
|
||||
["readOnly"]=false,
|
||||
["id"]=false,
|
||||
["mount"]=false,
|
||||
["bootable"]=false,
|
||||
["label"]=false
|
||||
}
|
||||
local function addHeader(id)
|
||||
table.insert(tableOut,{headerAlign[id],headers[id]})
|
||||
tablePos[id]=#tableOut
|
||||
end
|
||||
for i,v in pairs(tablePos) do print(i,v) end
|
||||
|
||||
local function everyHeader()
|
||||
addHeader("slot")
|
||||
addHeader("capacity")
|
||||
addHeader("managed")
|
||||
addHeader("readOnly")
|
||||
addHeader("id")
|
||||
addHeader("mount")
|
||||
addHeader("bootable")
|
||||
addHeader("label")
|
||||
end
|
||||
|
||||
local function defaultHeaders()
|
||||
if width>100 then addHeader("slot") end
|
||||
addHeader("capacity")
|
||||
if width>80 then addHeader("id") end
|
||||
addHeader("mount")
|
||||
addHeader("label")
|
||||
end
|
||||
|
||||
local outArgIdx = table.find(args,"-o") or table.find(args,"--output")
|
||||
if showAll then
|
||||
everyHeader()
|
||||
elseif outArgIdx then
|
||||
table.remove(args,outArgIdx)
|
||||
local arg = table.remove(args,outArgIdx)
|
||||
if not arg then return invalidArgSyntax("Argument -o must have a value") end
|
||||
if arg=="all" then
|
||||
everyHeader()
|
||||
else
|
||||
if arg:sub(1,1)=="+" then
|
||||
defaultHeaders()
|
||||
end
|
||||
for word in string.gmatch(arg:sub(2),"([^,]+)") do
|
||||
if headers[word] then
|
||||
addHeader(word)
|
||||
else
|
||||
print("\x1b[93mCategory \""..word.."\" doesn't exist\x1b[39m")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
defaultHeaders()
|
||||
end
|
||||
|
||||
local function headerUsed(id)
|
||||
return not not tablePos[id]
|
||||
end
|
||||
|
||||
local bibytes = not (table.find(args,"-H") or table.find(args,"--si"))
|
||||
local function formatSize(mem)
|
||||
local units = bibytes and {"B","KiB","MiB","GiB"} or {"B","KB","MB","GB"}
|
||||
local unit = 1
|
||||
local unitStep = bibytes and 1024 or 1000
|
||||
while mem > unitStep and units[unit] do
|
||||
unit = unit + 1
|
||||
mem = mem/unitStep
|
||||
end
|
||||
local memStr = tostring(mem):sub(1,5)
|
||||
if unicode.sub(memStr,-2)==".0" then
|
||||
memStr=unicode.sub(memStr,1,-3)
|
||||
end
|
||||
return memStr.." "..units[unit]
|
||||
end
|
||||
|
||||
local function fileExists(proxy,path)
|
||||
return proxy.exists(path) and not proxy.isDirectory(path)
|
||||
end
|
||||
|
||||
local function getBootCode(proxy)
|
||||
local sector1 = proxy.readSector(1)
|
||||
for i = 1,#sector1 do
|
||||
if sector1:sub(i,i)=="\0" then
|
||||
sector1 = sector1:sub(1,i-1)
|
||||
break
|
||||
end
|
||||
end
|
||||
return sector1
|
||||
end
|
||||
|
||||
local function isBootable(proxy,type)
|
||||
if type=="drive" then
|
||||
return not not load(getBootCode(proxy))
|
||||
elseif type=="filesystem" then
|
||||
return not not (fileExists(proxy,"/init.lua") or fileExists(proxy,"/OS.lua"))
|
||||
end
|
||||
end
|
||||
|
||||
local function formatBoolean(bool)
|
||||
return ({[true]="Yes",[false]="No"})[bool]
|
||||
end
|
||||
|
||||
local function handleComponent(id,type)
|
||||
if not id then return end
|
||||
local proxy = component.proxy(id)
|
||||
if not proxy then return end
|
||||
-- local out = {}
|
||||
-- for i=1,#tableOut do table.insert(out,"unknown") end
|
||||
local slot,capacity,managed,readOnly,mount,bootable,label
|
||||
|
||||
local cslot = component.slot(id)
|
||||
if cslot==-1 then
|
||||
slot="Virtual"
|
||||
elseif cslot==9 then
|
||||
slot="EEPROM"
|
||||
else
|
||||
slot="#"..(cslot+2)
|
||||
end
|
||||
|
||||
managed="Yes"
|
||||
readOnly="No"
|
||||
if type=="drive" then
|
||||
managed="No"
|
||||
capacity=formatSize(proxy.getCapacity())
|
||||
mount="/special/drive/"..id:sub(1,3)
|
||||
elseif type=="filesystem" then
|
||||
capacity=formatSize(proxy.spaceTotal())
|
||||
if proxy.isReadOnly() then
|
||||
readOnly="Yes"
|
||||
end
|
||||
mount="/mnt/"..id:sub(1,3)
|
||||
if computer.getBootAddress()==id then mount="/" end
|
||||
if computer.tmpAddress()==id then
|
||||
mount="/tmp"
|
||||
slot="Temporary"
|
||||
end
|
||||
elseif type=="eeprom" then
|
||||
capacity=formatSize(proxy.getSize()+proxy.getDataSize())
|
||||
mount="/special/eeprom/"
|
||||
end
|
||||
|
||||
if headerUsed("bootable") then
|
||||
bootable = formatBoolean(isBootable(proxy,type))
|
||||
end
|
||||
|
||||
local clabel = proxy.getLabel()
|
||||
label=clabel and "\""..clabel.."\"" or "None"
|
||||
|
||||
local function insertElement(i,v)
|
||||
if not tablePos[i] then return end
|
||||
table.insert(tableOut[tablePos[i]],v or "unknown")
|
||||
end
|
||||
insertElement("slot",slot)
|
||||
insertElement("capacity",capacity)
|
||||
insertElement("managed",managed)
|
||||
insertElement("readOnly",readOnly)
|
||||
insertElement("id",id)
|
||||
insertElement("mount",mount)
|
||||
insertElement("bootable",bootable)
|
||||
insertElement("label",label)
|
||||
end
|
||||
|
||||
local function filter(tbl,test)
|
||||
local i=1
|
||||
while i<=#tbl do
|
||||
if not test(tbl[i]) then
|
||||
table.remove(tbl,i)
|
||||
i=i-1
|
||||
end
|
||||
i=i+1
|
||||
end
|
||||
end
|
||||
|
||||
local function luaExpr(arg)
|
||||
local func,err = load("local component,computer,type,id,readonly,capacity=... local managed,eeprom,halyde,tmp,proxy,slot,all=type==\"drive\",type==\"eeprom\",id==\""..computer.getBootAddress().."\",id==\""..computer.tmpAddress().."\",component.proxy(id),component.slot(id)+2,true return "..arg)
|
||||
if func then
|
||||
return function(comp)
|
||||
local readOnly,capacity=false,nil
|
||||
if comp[2]=="filesystem" then
|
||||
readOnly=component.invoke(comp[1],"isReadOnly")
|
||||
capacity=component.invoke(comp[1],"spaceTotal")
|
||||
elseif comp[2]=="drive" then
|
||||
capacity=component.invoke(comp[1],"getCapacity")
|
||||
elseif comp[2]=="eeprom" then
|
||||
capacity=component.invoke(comp[1],"getSize")+component.invoke(comp[1],"getDataSize")
|
||||
end
|
||||
return func(component,computer,comp[2],comp[1],readOnly,capacity)
|
||||
end
|
||||
else
|
||||
return nil,err
|
||||
end
|
||||
end
|
||||
|
||||
local function boolToNum(val)
|
||||
if type(val)=="boolean" then
|
||||
if val then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
local comps = {}
|
||||
for i,v in component.list("filesystem") do table.insert(comps,{i,v}) end
|
||||
for i,v in component.list("drive") do table.insert(comps,{i,v}) end
|
||||
for i,v in component.list("eeprom") do table.insert(comps,{i,v}) end
|
||||
|
||||
if not showAll then
|
||||
local showArgIdx = table.find(args,"-s") or table.find(args,"--show")
|
||||
if showArgIdx then
|
||||
table.remove(args,showArgIdx)
|
||||
local arg = table.remove(args,showArgIdx)
|
||||
local func,err = luaExpr(arg)
|
||||
if func then
|
||||
filter(comps,func)
|
||||
else
|
||||
return print("\x1b[91mInvalid component filter:\n\n"..tostring(err).."\x1b[39m")
|
||||
end
|
||||
else
|
||||
filter(comps,function(comp)
|
||||
return comp[2]~="eeprom" and comp[1]~=computer.tmpAddress()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local sortArgIdx = table.find(args,"-S") or table.find(args,"--sort")
|
||||
if sortArgIdx then
|
||||
table.remove(args,sortArgIdx)
|
||||
local arg = table.remove(args,sortArgIdx)
|
||||
local func,err = luaExpr(arg)
|
||||
if func then
|
||||
table.sort(comps,function(a,b)
|
||||
return (boolToNum(func(a)) or 0)<(boolToNum(func(b)) or 0)
|
||||
end)
|
||||
else
|
||||
return print("\x1b[91mInvalid sort expression:\n\n"..tostring(err).."\x1b[39m")
|
||||
end
|
||||
else
|
||||
table.sort(comps,function(a,b)
|
||||
return a[1]<b[1]
|
||||
end)
|
||||
end
|
||||
|
||||
if #comps>0 then
|
||||
for i,v in ipairs(comps) do handleComponent(v[1],v[2]) end
|
||||
else
|
||||
return print("Could not find storage components for this filter.")
|
||||
end
|
||||
|
||||
local function renderTableOutput()
|
||||
local lines = {}
|
||||
for i=1,#tableOut[1]-1 do
|
||||
table.insert(lines,"")
|
||||
end
|
||||
|
||||
for i=1,#tableOut do
|
||||
local length = 1
|
||||
for j=1,#lines do
|
||||
tableOut[i][j+1]=tableOut[i][j+1] or "[nil]"
|
||||
length = math.max(length,unicode.wlen(tableOut[i][j+1]))
|
||||
end
|
||||
for j=1,#lines do
|
||||
if tableOut[i][1] then
|
||||
lines[j]=lines[j]..string.rep(" ",length-unicode.wlen(tableOut[i][j+1]))..tableOut[i][j+1]
|
||||
elseif i<#tableOut then
|
||||
lines[j]=lines[j]..tableOut[i][j+1]..string.rep(" ",length-unicode.wlen(tableOut[i][j+1]))
|
||||
else
|
||||
lines[j]=lines[j]..tableOut[i][j+1]
|
||||
end
|
||||
if i<#tableOut then lines[j]=lines[j].." " end
|
||||
end
|
||||
end
|
||||
|
||||
print(lines[1].."\n")
|
||||
for i=2,#lines do
|
||||
print(lines[i])
|
||||
end
|
||||
end
|
||||
|
||||
renderTableOutput()
|
||||
@@ -0,0 +1,8 @@
|
||||
local computer = import("computer")
|
||||
|
||||
if type(computer)~="table" then
|
||||
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[39m")
|
||||
end
|
||||
|
||||
local address = computer.getBootAddress()
|
||||
print(address)
|
||||
@@ -1 +1 @@
|
||||
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
|
||||
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local loadfile = ...
|
||||
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
|
||||
|
||||
_G._OSVERSION = "Halyde 2.4.1"
|
||||
_G._OSVERSION = "Halyde 2.5.0"
|
||||
_G._OSLOGO = ""
|
||||
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
|
||||
repeat
|
||||
|
||||
@@ -18,6 +18,7 @@ function compLib.virtual.add(address, componentType, proxy)
|
||||
checkArg(1, address, "string")
|
||||
checkArg(2, componentType, "string")
|
||||
checkArg(3, proxy, "table")
|
||||
proxy["address"] = address
|
||||
componentlib.additions[address] = {["componentType"] = componentType, ["proxy"] = proxy}
|
||||
if componentlib.removals[address] then
|
||||
componentlib.removals[address] = nil
|
||||
|
||||
Reference in New Issue
Block a user