New build system + hysh functionality #4
20
Makefile
Normal file
20
Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
PYTHON := python3
|
||||
ARCH_FLAG := $(if $(ARCH),--arch $(ARCH),)
|
||||
MODE_FLAG := $(if $(DEV),--dev,--release)
|
||||
|
||||
.PHONY: build build-mini build-test build-mini-test clean
|
||||
|
||||
build:
|
||||
$(PYTHON) build.py build $(ARCH_FLAG) $(MODE_FLAG)
|
||||
|
||||
build-mini:
|
||||
$(PYTHON) build.py build-mini $(ARCH_FLAG) $(MODE_FLAG)
|
||||
|
||||
build-test:
|
||||
$(PYTHON) build.py build-test $(ARCH_FLAG) $(MODE_FLAG)
|
||||
|
||||
build-mini-test:
|
||||
$(PYTHON) build.py build-mini-test $(ARCH_FLAG) $(MODE_FLAG)
|
||||
|
||||
clean:
|
||||
$(PYTHON) build.py clean
|
||||
@@ -4,6 +4,12 @@ HyperionOS is a modular, hybrid kernel operating system written entirely in Lua.
|
||||
|
||||
---
|
||||
|
||||
## Building
|
||||
|
||||
See `building.md`.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- Functionality is split into kernel modules (`.kmod`)
|
||||
|
||||
@@ -1,295 +0,0 @@
|
||||
--:Minify:--
|
||||
syscall.open("/dev/tty/TTY1","r") --stdin (Device 0)
|
||||
syscall.open("/dev/tty/TTY1","w") --stdout (Device 1)
|
||||
syscall.open("/dev/null","w") --stderr (device 2)
|
||||
|
||||
local success, errorMsg = xpcall(function()
|
||||
|
||||
|
||||
|
||||
local fs = require("sys.fs")
|
||||
|
||||
syscall.devctl(1,"clear")
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
syscall.devctl(1,"spos",1,1)
|
||||
print("HyperionOS Bash Shell")
|
||||
|
||||
local userhost = (syscall.getUsername() or "Unknown").."@"..(syscall.getHostname() or "Unknown")
|
||||
local commandHistory = {}
|
||||
local terminate = false
|
||||
syscall.setEnviron("SHELL","rtbash")
|
||||
syscall.setEnviron("PATH","/bin/")
|
||||
syscall.chdir("/")
|
||||
local oldWD = ""
|
||||
|
||||
for i = 1, 16 do
|
||||
syscall.devctl(1,"sbgc",i)
|
||||
printInline(" ");
|
||||
end
|
||||
print("\n")
|
||||
|
||||
syscall.sigcatch(function(sig)
|
||||
if sig == 1 then
|
||||
terminate = true
|
||||
end
|
||||
end)
|
||||
|
||||
local builtinCmds = {}
|
||||
|
||||
builtinCmds.cd = function(path)
|
||||
local cwd = syscall.getcwd()
|
||||
local dirIn = (path or "")
|
||||
if dirIn == "-" then
|
||||
if oldWD == "" then
|
||||
print("bash-cd: No previous working directory set.")
|
||||
else
|
||||
print(oldWD)
|
||||
syscall.chdir(oldWD)
|
||||
oldWD = cwd
|
||||
end
|
||||
return
|
||||
end
|
||||
local dirInMod = dirIn
|
||||
if dirIn:sub(1, 1) ~= "/" then dirInMod = cwd .. "/" .. dirIn end
|
||||
local parts = {}
|
||||
for part in dirInMod:gmatch("[^/]+") do
|
||||
if part == ".." then
|
||||
if #parts > 0 then table.remove(parts) end
|
||||
elseif part ~= "." and part ~= "" then
|
||||
table.insert(parts, part)
|
||||
end
|
||||
end
|
||||
local normDir = "/" .. table.concat(parts, "/")
|
||||
if normDir:sub(#normDir, #normDir) ~= "/" then normDir = normDir .. "/" end
|
||||
|
||||
if not fs.isDir(normDir) then
|
||||
print("bash-cd: "..dirIn..": No such directory.")
|
||||
return
|
||||
end
|
||||
oldWD = cwd
|
||||
syscall.chdir(normDir)
|
||||
end
|
||||
|
||||
|
||||
local function getUserInput()
|
||||
syscall.devctl(1,"sfgc",3)
|
||||
printInline(userhost)
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
printInline(":")
|
||||
syscall.devctl(1,"sfgc",10)
|
||||
printInline(syscall.getcwd())
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
printInline("$ ")
|
||||
local curOffsetStr = syscall.devctl(1, "gpos")
|
||||
local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1))
|
||||
local curOffsetY = tonumber(curOffsetStr:sub(curOffsetStr:find(";")+1))
|
||||
|
||||
local input = ""
|
||||
local blinkState = false
|
||||
local cursorPos = 1
|
||||
local history = 0
|
||||
|
||||
while true do
|
||||
local key=syscall.read(0)
|
||||
if key then
|
||||
if key == "\19" then --TODO: REPLACE WITH LEFT ARROW
|
||||
if cursorPos > 1 then
|
||||
cursorPos = cursorPos - 1
|
||||
end
|
||||
elseif key == "\20" then --TODO: REPLACE WITH RIGHT ARROW
|
||||
if cursorPos <= #input then
|
||||
cursorPos = cursorPos + 1
|
||||
end
|
||||
elseif key == "\17" then --TODO: REPLACE WITH UP ARROW
|
||||
if history < #commandHistory then
|
||||
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
|
||||
printInline((" "):rep(#input + 1))
|
||||
history = history + 1
|
||||
input = commandHistory[#commandHistory - history + 1]
|
||||
cursorPos = #input + 1
|
||||
end
|
||||
elseif key == "\18" then --TODO: REPLACE WITH DOWN ARROW
|
||||
if history > 1 then
|
||||
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
|
||||
printInline((" "):rep(#input + 1))
|
||||
history = history - 1
|
||||
input = commandHistory[#commandHistory - history + 1]
|
||||
cursorPos = #input + 1
|
||||
elseif history == 1 then
|
||||
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
|
||||
printInline((" "):rep(#input + 1))
|
||||
history = 0
|
||||
input = ""
|
||||
cursorPos = 1
|
||||
end
|
||||
elseif key == "\b" then
|
||||
if cursorPos > 1 then
|
||||
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
|
||||
printInline((" "):rep(#input + 1))
|
||||
input = string.sub(input, 1, cursorPos-2)..string.sub(input, cursorPos)
|
||||
cursorPos = cursorPos - 1
|
||||
end
|
||||
elseif key == "\n" then
|
||||
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
|
||||
print(input.." ")
|
||||
return input
|
||||
else
|
||||
input = string.sub(input, 1, cursorPos-1)..key..string.sub(input, cursorPos)
|
||||
cursorPos = cursorPos + 1
|
||||
end
|
||||
local screenSizeStr = syscall.devctl(1, "size")
|
||||
local sizeX = tonumber(screenSizeStr:sub(1, screenSizeStr:find(";")-1))
|
||||
local sizeY = tonumber(screenSizeStr:sub(screenSizeStr:find(";")+1))
|
||||
local totalChars = sizeX * sizeY
|
||||
local eocCharNum = ((curOffsetY - 1) * sizeX) + curOffsetX + #input
|
||||
if eocCharNum >= totalChars then
|
||||
syscall.devctl(1,"spos",sizeX,sizeY)
|
||||
printInline(" ")
|
||||
curOffsetY = curOffsetY - 1
|
||||
end
|
||||
end
|
||||
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
|
||||
printInline(string.sub(input, 1, cursorPos-1))
|
||||
if blinkState then
|
||||
syscall.devctl(1,"sfgc",16)
|
||||
syscall.devctl(1,"sbgc",1)
|
||||
end
|
||||
if cursorPos > #input then
|
||||
printInline(" ")
|
||||
else
|
||||
printInline(string.sub(input, cursorPos, cursorPos))
|
||||
end
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
syscall.devctl(1,"sbgc",16)
|
||||
printInline(string.sub(input, cursorPos+1))
|
||||
if cursorPos <= #input then
|
||||
printInline(" ")
|
||||
end
|
||||
local curBlink = ((math.floor(syscall.getUptime() / 500) % 2) == 0)
|
||||
if curBlink ~= blinkState then
|
||||
blinkState = curBlink
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function runCommand(command)
|
||||
do
|
||||
local func = load("return " .. command, "@equation", "t", {})
|
||||
if func then
|
||||
local success, result = pcall(func)
|
||||
if success and type(result) == "number" then
|
||||
print(result)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
terminate = false
|
||||
local args = string.split(command, " ")
|
||||
if builtinCmds[args[1]] then
|
||||
local success, msg = pcall(builtinCmds[args[1]], table.unpack(args, 2))
|
||||
if not success then
|
||||
local errSL = string.sub(msg, string.find(msg, "]") + 2)
|
||||
syscall.devctl(1,"sfgc",2)
|
||||
printInline(args[1]..": Program runtime error on line ")
|
||||
print(string.sub(errSL, 1, string.find(errSL, ":") - 1))
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
print(string.sub(errSL, string.find(errSL, ":") + 1))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local cmdPath = ""
|
||||
if string.find(args[1], "/") then
|
||||
if fs.exists(args[1]) then
|
||||
cmdPath = args[1]
|
||||
end
|
||||
else
|
||||
local paths = string.split(syscall.getEnviron("PATH"), ":")
|
||||
for _, path in pairs(paths) do
|
||||
if fs.exists(path..args[1]) then
|
||||
cmdPath = path..args[1]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if cmdPath == "" then
|
||||
print(args[1]..": Command not found")
|
||||
return
|
||||
end
|
||||
|
||||
local progName = string.sub(cmdPath, #cmdPath - string.find(string.reverse(cmdPath), "/") + 2)
|
||||
|
||||
local text = fs.readAllText(cmdPath)
|
||||
local program, err = load(text, progName)
|
||||
if not program then
|
||||
local errSL = string.sub(err, string.find(err, ":") + 1)
|
||||
syscall.devctl(1,"sfgc",2)
|
||||
printInline(progName..": Program load error on line ")
|
||||
print(string.sub(errSL, 1, string.find(errSL, ":") - 1))
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
print(string.sub(errSL, string.find(errSL, ":") + 1))
|
||||
return
|
||||
end
|
||||
|
||||
local proc = syscall.spawn(function(...)
|
||||
syscall.open("/dev/tty/TTY1","r")
|
||||
syscall.open("/dev/tty/TTY1","w")
|
||||
syscall.open("/dev/null","w")
|
||||
local success, msg = pcall(program, ...)
|
||||
if not success then
|
||||
local errSL = string.sub(msg, string.find(msg, ":") + 1)
|
||||
syscall.devctl(1,"sfgc",2)
|
||||
printInline(progName..": Program runtime error on line ")
|
||||
print(string.sub(errSL, 1, string.find(errSL, ":") - 1))
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
print(string.sub(errSL, string.find(errSL, ":") + 1))
|
||||
end
|
||||
end, progName, nil, {table.unpack(args, 2)})
|
||||
|
||||
while true do
|
||||
local exited, code = syscall.collect(proc)
|
||||
if exited then
|
||||
if code then
|
||||
print("\nTask exited with code:\n"..tostring(code))
|
||||
end
|
||||
return
|
||||
end
|
||||
if terminate then
|
||||
local success, err = syscall.kill(proc)
|
||||
if success then
|
||||
syscall.devctl(1,"sbgc",16)
|
||||
syscall.devctl(1,"sfgc",2)
|
||||
print("\nProgram Terminated.")
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
end
|
||||
terminate = false
|
||||
break
|
||||
end
|
||||
sleep(0.05)
|
||||
end
|
||||
end
|
||||
|
||||
while true do
|
||||
local command = getUserInput()
|
||||
if command ~= "" then
|
||||
if command ~= commandHistory[#commandHistory] then
|
||||
table.insert(commandHistory, command)
|
||||
end
|
||||
runCommand(command)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--ERROR HANDLING
|
||||
end, debug.traceback)
|
||||
|
||||
if not success then
|
||||
syscall.log("Error running shell: "..errorMsg, "ERROR")
|
||||
syscall.devctl(1,"sfgc",2)
|
||||
syscall.devctl(1,"sbgc",16)
|
||||
print()
|
||||
print("Error running shell: ")
|
||||
print(errorMsg)
|
||||
end
|
||||
@@ -1,94 +0,0 @@
|
||||
--:Minify:--
|
||||
syscall.open("/dev/tty/TTY1","r")
|
||||
syscall.open("/dev/tty/TTY1","w")
|
||||
syscall.open("/dev/null","r")
|
||||
syscall.devctl(1,"clear")
|
||||
syscall.devctl(1,"sfgc",1)
|
||||
syscall.devctl(1,"spos",1,1)
|
||||
print("HyperionOS Bash Shell")
|
||||
local str=""
|
||||
local stopInput=false
|
||||
local proc=0
|
||||
local fs=require("sys.fs")
|
||||
local timeout=false
|
||||
syscall.setEnviron("SHELL","simpleshell")
|
||||
printInline("> ")
|
||||
syscall.sigcatch(function(sig)
|
||||
if sig==1 then
|
||||
syscall.kill(proc)
|
||||
print("Terminated")
|
||||
printInline("> ")
|
||||
stopInput=false
|
||||
end
|
||||
end)
|
||||
|
||||
while true do
|
||||
if not stopInput then
|
||||
local input=syscall.read(0)
|
||||
if input then
|
||||
if input=="\b" then
|
||||
if #str>0 then
|
||||
str=str:sub(1,#str-1)
|
||||
printInline("\b")
|
||||
end
|
||||
elseif input=="\n" then
|
||||
print("")
|
||||
stopInput=true
|
||||
if str == "" then
|
||||
printInline("> ")
|
||||
stopInput=false
|
||||
else
|
||||
local path=nil
|
||||
local split=string.split(str, " ")
|
||||
if fs.exists("/bin/"..split[1]) then
|
||||
path="/bin/"..split[1]
|
||||
elseif fs.exists("/bin/"..split[1]..".lua") then
|
||||
path="/bin/"..split[1]..".lua"
|
||||
end
|
||||
if not path then
|
||||
print("Program not found")
|
||||
printInline("> ")
|
||||
stopInput=false
|
||||
else
|
||||
local text = fs.readAllText(path)
|
||||
local program, err = load(text, path)
|
||||
if not program then
|
||||
print(err)
|
||||
printInline("> ")
|
||||
end
|
||||
proc = syscall.spawn(function(...)
|
||||
syscall.open("/dev/tty/TTY1","r")
|
||||
syscall.open("/dev/tty/TTY1","w")
|
||||
syscall.open("/dev/null","w")
|
||||
program(...)
|
||||
end, path, nil, {table.unpack(split, 2)})
|
||||
end
|
||||
str=""
|
||||
end
|
||||
else
|
||||
str=str..input
|
||||
printInline(input)
|
||||
end
|
||||
timeout=false
|
||||
else
|
||||
timeout=true
|
||||
end
|
||||
else
|
||||
local exited, code = syscall.collect(proc)
|
||||
if exited then
|
||||
if code then
|
||||
print("\nTask exited with code:\n"..tostring(code))
|
||||
end
|
||||
printInline("> ")
|
||||
stopInput=false
|
||||
end
|
||||
timeout=true
|
||||
end
|
||||
if timeout then
|
||||
if stopInput then
|
||||
sleep(.5)
|
||||
else
|
||||
sleep(.05)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
--:Minify:--
|
||||
syscall.open("/dev/tty/TTY1","r") --stdin (fd 0)
|
||||
syscall.open("/dev/tty/TTY1","w") --stdout (fd 1)
|
||||
syscall.open("/dev/null","w") --stderr (fd 2)
|
||||
syscall.open("/dev/tty/TTY1", "r") --stdin (fd 0)
|
||||
syscall.open("/dev/tty/TTY1", "w") --stdout (fd 1)
|
||||
syscall.open("/dev/null", "w") --stderr (fd 2)
|
||||
|
||||
local fs = require("sys.fs")
|
||||
|
||||
@@ -78,21 +78,18 @@ local function spawnShell(username, uid, shell, homedir)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Spawn a wrapper that loads and runs the shell, reporting any error back
|
||||
-- via exit code channel so we can display it
|
||||
local errFifo = {}
|
||||
|
||||
local proc = syscall.spawn(function()
|
||||
syscall.setuid(uid)
|
||||
syscall.chdir(homedir)
|
||||
syscall.setEnviron("HOME", homedir)
|
||||
syscall.setEnviron("USER", username)
|
||||
syscall.setEnviron("HOME", homedir)
|
||||
syscall.setEnviron("USER", username)
|
||||
syscall.setEnviron("SHELL", shell)
|
||||
syscall.setEnviron("PATH", "/bin/")
|
||||
syscall.setEnviron("PATH", "/bin/")
|
||||
|
||||
local shellFn, loadErr = load(shellText, "@" .. shell)
|
||||
if not shellFn then
|
||||
-- Report load error via log and a recognizable exit code
|
||||
syscall.log("login: shell load error: " .. tostring(loadErr), "ERROR")
|
||||
syscall.exit(-1)
|
||||
return
|
||||
@@ -103,21 +100,7 @@ local function spawnShell(username, uid, shell, homedir)
|
||||
syscall.log("login: shell runtime error: " .. tostring(runErr), "ERROR")
|
||||
end
|
||||
end, username .. ":shell")
|
||||
|
||||
while true do
|
||||
local exited, code = syscall.collect(proc)
|
||||
if exited then
|
||||
if code then
|
||||
syscall.devctl(1, "sfgc", 2)
|
||||
syscall.write(1, "\nShell exited with code: " .. tostring(code) .. "\n")
|
||||
syscall.write(1, "(Check /var/log/syslog.log for details)\n")
|
||||
syscall.devctl(1, "sfgc", 1)
|
||||
sleep(2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
sleep(0.1)
|
||||
end
|
||||
syscall.exit(0)
|
||||
end
|
||||
|
||||
local function doLogin()
|
||||
@@ -145,7 +128,7 @@ local function doLogin()
|
||||
if ok then
|
||||
local uid = syscall.auth_getuid(username)
|
||||
local pwent = uid and syscall.auth_getpasswd(uid)
|
||||
local shell = (pwent and pwent.shell) or "/bin/hysh"
|
||||
local shell = (pwent and pwent.shell) or "/bin/hysh"
|
||||
local homedir = (pwent and pwent.homedir) or "/"
|
||||
|
||||
syscall.devctl(1, "sfgc", 3)
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
local fs = require("sys.fs")
|
||||
local bashStr = fs.readAllText("/bin/bash")
|
||||
local bashFun = load(bashStr)
|
||||
syscall.spawn(bashFun, "bash")
|
||||
@@ -1,7 +1,6 @@
|
||||
--:Minify:--
|
||||
local fs = require("sys.fs")
|
||||
|
||||
local targetUser = ({...})[1] or "root"
|
||||
local targetUser = ({ ... })[1] or "root"
|
||||
|
||||
local currentUid = syscall.getuid()
|
||||
local currentUser = syscall.getUsername(currentUid) or tostring(currentUid)
|
||||
@@ -26,7 +25,9 @@ else
|
||||
syscall.write(1, "\n")
|
||||
break
|
||||
elseif ch == "\b" then
|
||||
if #pw > 0 then pw = pw:sub(1, -2); syscall.write(1, "\b \b") end
|
||||
if #pw > 0 then
|
||||
pw = pw:sub(1, -2); syscall.write(1, "\b \b")
|
||||
end
|
||||
else
|
||||
pw = pw .. ch
|
||||
syscall.write(1, "*")
|
||||
@@ -46,13 +47,13 @@ if currentUid == 0 then
|
||||
syscall.setuid(targetUid)
|
||||
end
|
||||
|
||||
local pwent = syscall.auth_getpasswd(targetUid)
|
||||
local shell = (pwent and pwent.shell) or "/bin/hysh"
|
||||
local pwent = syscall.auth_getpasswd(targetUid)
|
||||
local shell = (pwent and pwent.shell) or "/bin/hysh"
|
||||
local homedir = (pwent and pwent.homedir) or "/"
|
||||
|
||||
syscall.chdir(homedir)
|
||||
syscall.setEnviron("HOME", homedir)
|
||||
syscall.setEnviron("USER", targetUser)
|
||||
syscall.setEnviron("HOME", homedir)
|
||||
syscall.setEnviron("USER", targetUser)
|
||||
syscall.setEnviron("SHELL", shell)
|
||||
|
||||
local shellText = fs.readAllText(shell)
|
||||
@@ -63,10 +64,17 @@ if not shellText then
|
||||
end
|
||||
|
||||
local shellFn, loadErr = load(shellText, "@" .. shell)
|
||||
|
||||
if not shellFn then
|
||||
print("su: cannot load shell: " .. tostring(loadErr))
|
||||
syscall.exit(1)
|
||||
return
|
||||
end
|
||||
|
||||
shellFn()
|
||||
local success, err = syscall.kill(syscall.getppid())
|
||||
if success then
|
||||
syscall.spawn(shellFn, targetUser .. ":" .. shell, syscall.getEnviron())
|
||||
syscall.exit(0)
|
||||
else
|
||||
print("su: "..err)
|
||||
end
|
||||
@@ -1 +1 @@
|
||||
0:0:root:/root:/bin/bash
|
||||
0:0:root:/root:/bin/hysh
|
||||
@@ -129,9 +129,6 @@ function sys.kill(pid)
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid, table.unpack(children)) and kernel.uid ~= 0 then
|
||||
return false, "You do not own this task"
|
||||
|
||||
elseif tasks[tostring(pid)].status == "Z" then
|
||||
return false, "Task is already dead"
|
||||
|
||||
@@ -148,9 +145,6 @@ function sys.stop(pid)
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid, table.unpack(children)) and kernel.uid ~= 0 then
|
||||
return false, "You do not own this task"
|
||||
|
||||
elseif tasks[tostring(pid)].status ~= "R" then
|
||||
return false, "Cannot stop non running task"
|
||||
|
||||
@@ -166,9 +160,6 @@ function sys.continue(pid)
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid, table.unpack(children)) and kernel.uid ~= 0 then
|
||||
return false, "You do not own this task"
|
||||
|
||||
elseif tasks[tostring(pid)].status ~= "T" then
|
||||
return false, "Task is not stopped"
|
||||
|
||||
|
||||
154
build.py
Normal file
154
build.py
Normal file
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Usage:
|
||||
python build.py <target> [--arch cct|oc] [--release|--dev]
|
||||
|
||||
Targets:
|
||||
build
|
||||
build-mini
|
||||
build-test
|
||||
build-mini-test
|
||||
clean
|
||||
|
||||
Arch flags:
|
||||
--arch cct
|
||||
--arch oc
|
||||
|
||||
Release flags:
|
||||
--release
|
||||
--dev
|
||||
"""
|
||||
|
||||
import sys
|
||||
import shutil
|
||||
import argparse
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent
|
||||
SRC_ROOT = PROJECT_ROOT / "Src"
|
||||
TEST_ROOT = PROJECT_ROOT / "Test"
|
||||
BUILD_ROOT = PROJECT_ROOT / "Build"
|
||||
|
||||
ARCH_BOOT_DIR = {
|
||||
"cct": Path("boot") / "cct",
|
||||
"oc": Path("boot") / "oc",
|
||||
}
|
||||
|
||||
|
||||
def clean():
|
||||
if BUILD_ROOT.exists():
|
||||
print(f"Removing {BUILD_ROOT} ...")
|
||||
shutil.rmtree(BUILD_ROOT)
|
||||
else:
|
||||
print("Nothing to clean.")
|
||||
|
||||
|
||||
def process_root(src_root: Path, out_root: Path, minify: bool):
|
||||
print(f"Building from {src_root}")
|
||||
print(f"Output to {out_root}")
|
||||
print()
|
||||
|
||||
for pkg_dir in sorted(src_root.iterdir()):
|
||||
if not pkg_dir.is_dir():
|
||||
continue
|
||||
|
||||
print(f"== Package: {pkg_dir.name} ==")
|
||||
|
||||
for src in sorted(pkg_dir.rglob("*")):
|
||||
if not src.is_file():
|
||||
continue
|
||||
|
||||
rel = src.relative_to(pkg_dir)
|
||||
dst = out_root / rel
|
||||
dst.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f" Processing: {src.relative_to(src_root)}")
|
||||
|
||||
if minify and has_minify_header(src):
|
||||
print(" > Minifying")
|
||||
result = subprocess.run(
|
||||
["luamin", "-f", str(src)],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print(f" ! luamin failed: {result.stderr.strip()}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
dst.write_text(result.stdout, encoding="utf-8")
|
||||
else:
|
||||
print(" > Copying")
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def install_bootloader(arch: str, release: bool):
|
||||
boot_dir = BUILD_ROOT / "$" / ARCH_BOOT_DIR[arch]
|
||||
boot_lua = boot_dir / "boot.lua"
|
||||
eeprom = boot_dir / "eeprom"
|
||||
|
||||
for src in (boot_lua, eeprom):
|
||||
if not src.exists():
|
||||
print(f" ! Bootloader file not found: {src}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(f" Installing: boot.lua -> Build/boot.lua")
|
||||
shutil.copy2(boot_lua, BUILD_ROOT / "boot.lua")
|
||||
|
||||
eeprom_dst_name = "startup.lua" if release else "eeprom"
|
||||
print(f" Installing: eeprom -> Build/{eeprom_dst_name}")
|
||||
shutil.copy2(eeprom, BUILD_ROOT / eeprom_dst_name)
|
||||
|
||||
|
||||
def has_minify_header(path: Path) -> bool:
|
||||
try:
|
||||
with path.open("r", encoding="utf-8", errors="ignore") as f:
|
||||
for _ in range(3):
|
||||
if "--:Minify:--" in f.readline():
|
||||
return True
|
||||
except OSError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def run_build(minify: bool, include_test: bool, arch: str | None, release: bool):
|
||||
clean()
|
||||
BUILD_ROOT.mkdir()
|
||||
|
||||
out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT
|
||||
|
||||
process_root(SRC_ROOT, out_root, minify)
|
||||
if include_test:
|
||||
process_root(TEST_ROOT, out_root, minify)
|
||||
|
||||
if arch:
|
||||
print("Installing bootloader files ...")
|
||||
install_bootloader(arch, release)
|
||||
print()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="HyperionOS build script")
|
||||
parser.add_argument("target", choices=["build", "build-mini", "build-test", "build-mini-test", "clean"])
|
||||
parser.add_argument("--arch", choices=["cct", "oc"], default=None,
|
||||
help="Target architecture (cct or oc)")
|
||||
parser.add_argument("--release", dest="release", action="store_true", default=True,
|
||||
help="Release build: eeprom placed as startup.lua (default)")
|
||||
parser.add_argument("--dev", dest="release", action="store_false",
|
||||
help="Dev build: boot.lua and eeprom copied unchanged")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.target == "clean":
|
||||
clean()
|
||||
return
|
||||
|
||||
minify = "mini" in args.target
|
||||
include_test = "test" in args.target
|
||||
|
||||
run_build(minify=minify, include_test=include_test, arch=args.arch, release=args.release)
|
||||
print("Build complete.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
68
building.md
Normal file
68
building.md
Normal file
@@ -0,0 +1,68 @@
|
||||
## Building
|
||||
|
||||
### Linux / `make`-compatible systems
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
|
||||
Optional variables:
|
||||
|
||||
* **`ARCH=`**
|
||||
|
||||
* `cct` Build using the cct bootloader
|
||||
* `oc` Build using the oc bootloader
|
||||
|
||||
* **`DEV=1`**
|
||||
|
||||
* Builds in development mode
|
||||
* Bootloader does not start automatically on system startup
|
||||
|
||||
If `DEV` is not specified:
|
||||
|
||||
* Default is release mode
|
||||
* Bootloader starts automatically on system startup
|
||||
|
||||
**Examples**
|
||||
|
||||
```bash
|
||||
make build ARCH=cct
|
||||
make build ARCH=oc DEV=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Windows / Any system with Python 3.7+
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python build.py build
|
||||
```
|
||||
|
||||
Optional arguments:
|
||||
|
||||
* **`--arch {cct|oc}`**
|
||||
Select bootloader
|
||||
|
||||
* `cct` Use the cct bootloader
|
||||
* `oc` Use the oc bootloader
|
||||
|
||||
* **`--dev`**
|
||||
|
||||
* Development mode
|
||||
* Bootloader does not start automatically
|
||||
|
||||
* **`--release`** (default)
|
||||
|
||||
* Release mode
|
||||
* Bootloader starts automatically
|
||||
|
||||
**Examples**
|
||||
|
||||
```bash
|
||||
python build.py build --arch cct
|
||||
python build.py build --arch oc --dev
|
||||
```
|
||||
@@ -1,44 +0,0 @@
|
||||
$testRoot = Join-Path $PSScriptRoot "..\src"
|
||||
$buildRoot = Join-Path $PSScriptRoot "..\Build"
|
||||
|
||||
$testRoot = Resolve-Path $testRoot
|
||||
|
||||
# Clean Build folder
|
||||
if (Test-Path $buildRoot) {
|
||||
Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $buildRoot | Out-Null
|
||||
|
||||
Write-Host "Building from $testRoot"
|
||||
Write-Host "Output to $buildRoot"
|
||||
Write-Host ""
|
||||
|
||||
# Each top-level folder in test/
|
||||
Get-ChildItem -Path $testRoot -Directory | ForEach-Object {
|
||||
|
||||
$folderRoot = $_.FullName
|
||||
Write-Host "== Package: $($_.Name) =="
|
||||
|
||||
# Walk files inside this folder
|
||||
Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object {
|
||||
|
||||
$src = $_.FullName
|
||||
$rel = $src.Substring($folderRoot.Length).TrimStart("\")
|
||||
$dst = Join-Path $buildRoot $rel
|
||||
$dstDir = Split-Path $dst
|
||||
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Processing: $rel"
|
||||
Write-Host " > Copying"
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "Build complete."
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
TEST_ROOT="$(realpath "$SCRIPT_ROOT/../src")"
|
||||
BUILD_ROOT="$SCRIPT_ROOT/../Build"
|
||||
|
||||
if [[ -d "$BUILD_ROOT" ]]; then
|
||||
rm -rf "$BUILD_ROOT"
|
||||
fi
|
||||
mkdir -p "$BUILD_ROOT"
|
||||
|
||||
echo "Building from $TEST_ROOT"
|
||||
echo "Output to $BUILD_ROOT"
|
||||
echo ""
|
||||
|
||||
for folder in "$TEST_ROOT"/*/; do
|
||||
[[ -d "$folder" ]] || continue
|
||||
|
||||
folder_root="$folder"
|
||||
package_name="$(basename "$folder_root")"
|
||||
echo "== Package: $package_name =="
|
||||
|
||||
find "$folder_root" -type f | while IFS= read -r src; do
|
||||
rel="${src#$folder_root}"
|
||||
dst="$BUILD_ROOT/$rel"
|
||||
dst_dir="$(dirname "$dst")"
|
||||
|
||||
if [[ ! -d "$dst_dir" ]]; then
|
||||
mkdir -p "$dst_dir"
|
||||
fi
|
||||
|
||||
echo "Processing: $rel"
|
||||
echo " > Copying"
|
||||
cp -f "$src" "$dst"
|
||||
done
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Build complete."
|
||||
@@ -1,57 +0,0 @@
|
||||
$testRoot = Join-Path $PSScriptRoot "..\src"
|
||||
$buildRoot = Join-Path $PSScriptRoot "..\Build"
|
||||
|
||||
$testRoot = Resolve-Path $testRoot
|
||||
|
||||
# Clean Build folder
|
||||
if (Test-Path $buildRoot) {
|
||||
Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $buildRoot | Out-Null
|
||||
|
||||
Write-Host "Building from $testRoot"
|
||||
Write-Host "Output to $buildRoot"
|
||||
Write-Host ""
|
||||
|
||||
# Each top-level folder in test/
|
||||
Get-ChildItem -Path $testRoot -Directory | ForEach-Object {
|
||||
|
||||
$folderRoot = $_.FullName
|
||||
Write-Host "== Package: $($_.Name) =="
|
||||
|
||||
# Walk files inside this folder
|
||||
Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object {
|
||||
|
||||
$src = $_.FullName
|
||||
$rel = $src.Substring($folderRoot.Length).TrimStart("\")
|
||||
$dst = Join-Path $buildRoot $rel
|
||||
$dstDir = Split-Path $dst
|
||||
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Processing: $rel"
|
||||
|
||||
# Read first 3 lines
|
||||
$header = Get-Content $src -TotalCount 3 -ErrorAction SilentlyContinue
|
||||
|
||||
if ($header -match "--:Minify:--") {
|
||||
Write-Host " > Minifying"
|
||||
$content = luamin -f "$src"
|
||||
|
||||
# UTF8 encoding without BOM because it breaks lua
|
||||
$utf8NoBOM = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText($dst, $content, $utf8NoBOM)
|
||||
}
|
||||
else {
|
||||
Write-Host " > Copying"
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "Build complete."
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
TEST_ROOT="$(realpath "$SCRIPT_ROOT/../src")"
|
||||
BUILD_ROOT="$SCRIPT_ROOT/../Build"
|
||||
|
||||
if [[ -d "$BUILD_ROOT" ]]; then
|
||||
rm -rf "$BUILD_ROOT"
|
||||
fi
|
||||
mkdir -p "$BUILD_ROOT"
|
||||
|
||||
echo "Building from $TEST_ROOT"
|
||||
echo "Output to $BUILD_ROOT"
|
||||
echo ""
|
||||
|
||||
for folder in "$TEST_ROOT"/*/; do
|
||||
[[ -d "$folder" ]] || continue
|
||||
|
||||
folder_root="$folder"
|
||||
package_name="$(basename "$folder_root")"
|
||||
echo "== Package: $package_name =="
|
||||
|
||||
find "$folder_root" -type f | while IFS= read -r src; do
|
||||
rel="${src#$folder_root}"
|
||||
dst="$BUILD_ROOT/$rel"
|
||||
dst_dir="$(dirname "$dst")"
|
||||
|
||||
if [[ ! -d "$dst_dir" ]]; then
|
||||
mkdir -p "$dst_dir"
|
||||
fi
|
||||
|
||||
echo "Processing: $rel"
|
||||
|
||||
header="$(head -n 3 "$src" 2>/dev/null || true)"
|
||||
|
||||
if echo "$header" | grep -q -- "--:Minify:--"; then
|
||||
echo " > Minifying"
|
||||
luamin -f "$src" > "$dst"
|
||||
else
|
||||
echo " > Copying"
|
||||
cp -f "$src" "$dst"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Build complete."
|
||||
@@ -1,108 +0,0 @@
|
||||
$testRoot = Join-Path $PSScriptRoot "..\src"
|
||||
$buildRoot = Join-Path $PSScriptRoot "..\Build"
|
||||
|
||||
$testRoot = Resolve-Path $testRoot
|
||||
|
||||
# Clean Build folder
|
||||
if (Test-Path $buildRoot) {
|
||||
Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $buildRoot | Out-Null
|
||||
|
||||
Write-Host "Building from $testRoot"
|
||||
Write-Host "Output to $buildRoot"
|
||||
Write-Host ""
|
||||
|
||||
# Each top-level folder in test/
|
||||
Get-ChildItem -Path $testRoot -Directory | ForEach-Object {
|
||||
|
||||
$folderRoot = $_.FullName
|
||||
Write-Host "== Package: $($_.Name) =="
|
||||
|
||||
# Walk files inside this folder
|
||||
Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object {
|
||||
|
||||
$src = $_.FullName
|
||||
$rel = $src.Substring($folderRoot.Length).TrimStart("\")
|
||||
$dst = Join-Path $buildRoot $rel
|
||||
$dstDir = Split-Path $dst
|
||||
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Processing: $rel"
|
||||
|
||||
# Read first 3 lines
|
||||
$header = Get-Content $src -TotalCount 3 -ErrorAction SilentlyContinue
|
||||
|
||||
if ($header -match "--:Minify:--") {
|
||||
Write-Host " > Minifying"
|
||||
$content = luamin -f "$src"
|
||||
|
||||
# UTF8 encoding without BOM because it breaks lua
|
||||
$utf8NoBOM = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText($dst, $content, $utf8NoBOM)
|
||||
}
|
||||
else {
|
||||
Write-Host " > Copying"
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "Build complete."
|
||||
|
||||
$testRoot = Join-Path $PSScriptRoot "..\test"
|
||||
$buildRoot = Join-Path $PSScriptRoot "..\Build"
|
||||
|
||||
$testRoot = Resolve-Path $testRoot
|
||||
|
||||
Write-Host "Building from $testRoot"
|
||||
Write-Host "Output to $buildRoot"
|
||||
Write-Host ""
|
||||
|
||||
# Each top-level folder in test/
|
||||
Get-ChildItem -Path $testRoot -Directory | ForEach-Object {
|
||||
|
||||
$folderRoot = $_.FullName
|
||||
Write-Host "== Package: $($_.Name) =="
|
||||
|
||||
# Walk files inside this folder
|
||||
Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object {
|
||||
|
||||
$src = $_.FullName
|
||||
$rel = $src.Substring($folderRoot.Length).TrimStart("\")
|
||||
$dst = Join-Path $buildRoot $rel
|
||||
$dstDir = Split-Path $dst
|
||||
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Processing: $rel"
|
||||
|
||||
# Read first 3 lines
|
||||
$header = Get-Content $src -TotalCount 3 -ErrorAction SilentlyContinue
|
||||
|
||||
if ($header -match "--:Minify:--") {
|
||||
Write-Host " > Minifying"
|
||||
$content = luamin -f "$src"
|
||||
|
||||
# UTF8 encoding without BOM because it breaks lua
|
||||
$utf8NoBOM = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText($dst, $content, $utf8NoBOM)
|
||||
}
|
||||
else {
|
||||
Write-Host " > Copying"
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "Build complete."
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
build_from_root() {
|
||||
local TEST_ROOT
|
||||
TEST_ROOT="$(realpath "$1")"
|
||||
local BUILD_ROOT="$SCRIPT_ROOT/../Build"
|
||||
|
||||
if [[ -d "$BUILD_ROOT" ]]; then
|
||||
rm -rf "$BUILD_ROOT"
|
||||
fi
|
||||
mkdir -p "$BUILD_ROOT"
|
||||
|
||||
echo "Building from $TEST_ROOT"
|
||||
echo "Output to $BUILD_ROOT"
|
||||
echo ""
|
||||
|
||||
for folder in "$TEST_ROOT"/*/; do
|
||||
[[ -d "$folder" ]] || continue
|
||||
|
||||
local package_name
|
||||
package_name="$(basename "$folder")"
|
||||
echo "== Package: $package_name =="
|
||||
|
||||
find "$folder" -type f | while IFS= read -r src; do
|
||||
rel="${src#$folder}"
|
||||
dst="$BUILD_ROOT/$rel"
|
||||
dst_dir="$(dirname "$dst")"
|
||||
|
||||
mkdir -p "$dst_dir"
|
||||
|
||||
echo "Processing: $rel"
|
||||
|
||||
header="$(head -n 3 "$src" 2>/dev/null || true)"
|
||||
|
||||
if echo "$header" | grep -q -- "--:Minify:--"; then
|
||||
echo " > Minifying"
|
||||
luamin -f "$src" > "$dst"
|
||||
else
|
||||
echo " > Copying"
|
||||
cp -f "$src" "$dst"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Build complete."
|
||||
}
|
||||
|
||||
build_from_root "$SCRIPT_ROOT/../src"
|
||||
|
||||
build_from_root "$SCRIPT_ROOT/../test"
|
||||
@@ -1,83 +0,0 @@
|
||||
$testRoot = Join-Path $PSScriptRoot "..\src"
|
||||
$buildRoot = Join-Path $PSScriptRoot "..\Build"
|
||||
|
||||
$testRoot = Resolve-Path $testRoot
|
||||
|
||||
# Clean Build folder
|
||||
if (Test-Path $buildRoot) {
|
||||
Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $buildRoot | Out-Null
|
||||
|
||||
Write-Host "Building from $testRoot"
|
||||
Write-Host "Output to $buildRoot"
|
||||
Write-Host ""
|
||||
|
||||
# Each top-level folder in test/
|
||||
Get-ChildItem -Path $testRoot -Directory | ForEach-Object {
|
||||
|
||||
$folderRoot = $_.FullName
|
||||
Write-Host "== Package: $($_.Name) =="
|
||||
|
||||
# Walk files inside this folder
|
||||
Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object {
|
||||
|
||||
$src = $_.FullName
|
||||
$rel = $src.Substring($folderRoot.Length).TrimStart("\")
|
||||
$dst = Join-Path $buildRoot $rel
|
||||
$dstDir = Split-Path $dst
|
||||
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Processing: $rel"
|
||||
Write-Host " > Copying"
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "Build complete."
|
||||
|
||||
|
||||
$testRoot = Join-Path $PSScriptRoot "..\test"
|
||||
$buildRoot = Join-Path $PSScriptRoot "..\Build"
|
||||
|
||||
$testRoot = Resolve-Path $testRoot
|
||||
|
||||
Write-Host "Building from $testRoot"
|
||||
Write-Host "Output to $buildRoot"
|
||||
Write-Host ""
|
||||
|
||||
# Each top-level folder in test/
|
||||
Get-ChildItem -Path $testRoot -Directory | ForEach-Object {
|
||||
|
||||
$folderRoot = $_.FullName
|
||||
Write-Host "== Package: $($_.Name) =="
|
||||
|
||||
# Walk files inside this folder
|
||||
Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object {
|
||||
|
||||
$src = $_.FullName
|
||||
$rel = $src.Substring($folderRoot.Length).TrimStart("\")
|
||||
$dst = Join-Path $buildRoot $rel
|
||||
$dstDir = Split-Path $dst
|
||||
|
||||
if (-not (Test-Path $dstDir)) {
|
||||
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "Processing: $rel"
|
||||
|
||||
Write-Host " > Copying"
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "Build complete."
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
TEST_ROOT="$(realpath "$SCRIPT_ROOT/../src")"
|
||||
BUILD_ROOT="$(realpath "$SCRIPT_ROOT/../Build" 2>/dev/null || echo "$SCRIPT_ROOT/../Build")"
|
||||
|
||||
if [[ -d "$BUILD_ROOT" ]]; then
|
||||
rm -rf "$BUILD_ROOT"
|
||||
fi
|
||||
mkdir -p "$BUILD_ROOT"
|
||||
|
||||
echo "Building from $TEST_ROOT"
|
||||
echo "Output to $BUILD_ROOT"
|
||||
echo ""
|
||||
|
||||
for folder in "$TEST_ROOT"/*/; do
|
||||
[[ -d "$folder" ]] || continue
|
||||
|
||||
package_name="$(basename "$folder")"
|
||||
echo "== Package: $package_name =="
|
||||
|
||||
find "$folder" -type f | while read -r src; do
|
||||
rel="${src#$folder}"
|
||||
dst="$BUILD_ROOT/$rel"
|
||||
dst_dir="$(dirname "$dst")"
|
||||
|
||||
mkdir -p "$dst_dir"
|
||||
|
||||
echo "Processing: $rel"
|
||||
echo " > Copying"
|
||||
cp -f "$src" "$dst"
|
||||
done
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Build complete."
|
||||
|
||||
TEST_ROOT="$(realpath "$SCRIPT_ROOT/../test")"
|
||||
BUILD_ROOT="$(realpath "$SCRIPT_ROOT/../Build" 2>/dev/null || echo "$SCRIPT_ROOT/../Build")"
|
||||
|
||||
echo "Building from $TEST_ROOT"
|
||||
echo "Output to $BUILD_ROOT"
|
||||
echo ""
|
||||
|
||||
for folder in "$TEST_ROOT"/*/; do
|
||||
[[ -d "$folder" ]] || continue
|
||||
|
||||
package_name="$(basename "$folder")"
|
||||
echo "== Package: $package_name =="
|
||||
|
||||
find "$folder" -type f | while read -r src; do
|
||||
rel="${src#$folder}"
|
||||
dst="$BUILD_ROOT/$rel"
|
||||
dst_dir="$(dirname "$dst")"
|
||||
|
||||
mkdir -p "$dst_dir"
|
||||
|
||||
echo "Processing: $rel"
|
||||
echo " > Copying"
|
||||
cp -f "$src" "$dst"
|
||||
done
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Build complete."
|
||||
Reference in New Issue
Block a user