New build system + hysh functionality #4

Merged
Astronand merged 3 commits from spsf/HyperionOS:main into main 2026-02-21 14:54:02 -05:00
24 changed files with 273 additions and 944 deletions

BIN
Build.tar

Binary file not shown.

BIN
Build.zip

Binary file not shown.

20
Makefile Normal file
View 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

View File

@@ -4,6 +4,12 @@ HyperionOS is a modular, hybrid kernel operating system written entirely in Lua.
--- ---
## Building
See `building.md`.
---
## Features ## Features
- Functionality is split into kernel modules (`.kmod`) - Functionality is split into kernel modules (`.kmod`)

View File

@@ -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

View File

@@ -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

View File

@@ -1,7 +1,7 @@
--:Minify:-- --:Minify:--
syscall.open("/dev/tty/TTY1","r") --stdin (fd 0) syscall.open("/dev/tty/TTY1", "r") --stdin (fd 0)
syscall.open("/dev/tty/TTY1","w") --stdout (fd 1) syscall.open("/dev/tty/TTY1", "w") --stdout (fd 1)
syscall.open("/dev/null","w") --stderr (fd 2) syscall.open("/dev/null", "w") --stderr (fd 2)
local fs = require("sys.fs") local fs = require("sys.fs")
@@ -78,21 +78,18 @@ local function spawnShell(username, uid, shell, homedir)
return false return false
end 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 errFifo = {}
local proc = syscall.spawn(function() local proc = syscall.spawn(function()
syscall.setuid(uid) syscall.setuid(uid)
syscall.chdir(homedir) syscall.chdir(homedir)
syscall.setEnviron("HOME", homedir) syscall.setEnviron("HOME", homedir)
syscall.setEnviron("USER", username) syscall.setEnviron("USER", username)
syscall.setEnviron("SHELL", shell) syscall.setEnviron("SHELL", shell)
syscall.setEnviron("PATH", "/bin/") syscall.setEnviron("PATH", "/bin/")
local shellFn, loadErr = load(shellText, "@" .. shell) local shellFn, loadErr = load(shellText, "@" .. shell)
if not shellFn then if not shellFn then
-- Report load error via log and a recognizable exit code
syscall.log("login: shell load error: " .. tostring(loadErr), "ERROR") syscall.log("login: shell load error: " .. tostring(loadErr), "ERROR")
syscall.exit(-1) syscall.exit(-1)
return return
@@ -103,21 +100,7 @@ local function spawnShell(username, uid, shell, homedir)
syscall.log("login: shell runtime error: " .. tostring(runErr), "ERROR") syscall.log("login: shell runtime error: " .. tostring(runErr), "ERROR")
end end
end, username .. ":shell") end, username .. ":shell")
syscall.exit(0)
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
end end
local function doLogin() local function doLogin()
@@ -145,7 +128,7 @@ local function doLogin()
if ok then if ok then
local uid = syscall.auth_getuid(username) local uid = syscall.auth_getuid(username)
local pwent = uid and syscall.auth_getpasswd(uid) 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 "/" local homedir = (pwent and pwent.homedir) or "/"
syscall.devctl(1, "sfgc", 3) syscall.devctl(1, "sfgc", 3)

View File

@@ -1,4 +0,0 @@
local fs = require("sys.fs")
local bashStr = fs.readAllText("/bin/bash")
local bashFun = load(bashStr)
syscall.spawn(bashFun, "bash")

View File

@@ -1,7 +1,6 @@
--:Minify:-- --:Minify:--
local fs = require("sys.fs") local fs = require("sys.fs")
local targetUser = ({ ... })[1] or "root"
local targetUser = ({...})[1] or "root"
local currentUid = syscall.getuid() local currentUid = syscall.getuid()
local currentUser = syscall.getUsername(currentUid) or tostring(currentUid) local currentUser = syscall.getUsername(currentUid) or tostring(currentUid)
@@ -26,7 +25,9 @@ else
syscall.write(1, "\n") syscall.write(1, "\n")
break break
elseif ch == "\b" then 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 else
pw = pw .. ch pw = pw .. ch
syscall.write(1, "*") syscall.write(1, "*")
@@ -46,13 +47,13 @@ if currentUid == 0 then
syscall.setuid(targetUid) syscall.setuid(targetUid)
end end
local pwent = syscall.auth_getpasswd(targetUid) local pwent = syscall.auth_getpasswd(targetUid)
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 "/" local homedir = (pwent and pwent.homedir) or "/"
syscall.chdir(homedir) syscall.chdir(homedir)
syscall.setEnviron("HOME", homedir) syscall.setEnviron("HOME", homedir)
syscall.setEnviron("USER", targetUser) syscall.setEnviron("USER", targetUser)
syscall.setEnviron("SHELL", shell) syscall.setEnviron("SHELL", shell)
local shellText = fs.readAllText(shell) local shellText = fs.readAllText(shell)
@@ -63,10 +64,17 @@ if not shellText then
end end
local shellFn, loadErr = load(shellText, "@" .. shell) local shellFn, loadErr = load(shellText, "@" .. shell)
if not shellFn then if not shellFn then
print("su: cannot load shell: " .. tostring(loadErr)) print("su: cannot load shell: " .. tostring(loadErr))
syscall.exit(1) syscall.exit(1)
return return
end 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

View File

@@ -1 +1 @@
0:0:root:/root:/bin/bash 0:0:root:/root:/bin/hysh

View File

@@ -129,9 +129,6 @@ function sys.kill(pid)
if not tasks[tostring(pid)] then if not tasks[tostring(pid)] then
return false, "Task does not exist" 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 elseif tasks[tostring(pid)].status == "Z" then
return false, "Task is already dead" return false, "Task is already dead"
@@ -148,9 +145,6 @@ function sys.stop(pid)
if not tasks[tostring(pid)] then if not tasks[tostring(pid)] then
return false, "Task does not exist" 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 elseif tasks[tostring(pid)].status ~= "R" then
return false, "Cannot stop non running task" return false, "Cannot stop non running task"
@@ -166,9 +160,6 @@ function sys.continue(pid)
if not tasks[tostring(pid)] then if not tasks[tostring(pid)] then
return false, "Task does not exist" 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 elseif tasks[tostring(pid)].status ~= "T" then
return false, "Task is not stopped" return false, "Task is not stopped"

154
build.py Normal file
View 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
View 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
```

View File

@@ -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."

View File

@@ -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."

View File

@@ -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."

View File

@@ -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."

View File

@@ -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."

View File

@@ -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"

View File

@@ -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."

View File

@@ -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."