You've already forked greyhack
first commit
This commit is contained in:
119
provision.py
Normal file
119
provision.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
SOURCE_DIR = ROOT / "source"
|
||||
OUTPUT = ROOT / "provision.src"
|
||||
|
||||
|
||||
def variable_name(path: Path) -> str:
|
||||
stem = re.sub(r"\W+", "_", path.stem.lower()).strip("_")
|
||||
if not stem:
|
||||
raise ValueError(f"cannot derive variable name from {path.name!r}")
|
||||
if stem[0].isdigit():
|
||||
stem = f"_{stem}"
|
||||
return stem
|
||||
|
||||
|
||||
def greyscript_string(value: str) -> str:
|
||||
return '"' + value.replace('"', '""') + '"'
|
||||
|
||||
|
||||
def content_lines(var: str, content: str) -> list[str]:
|
||||
lines = [f'{var}_content = ""']
|
||||
for line in content.splitlines():
|
||||
lines.append(
|
||||
f"{var}_content = {var}_content + {greyscript_string(line)} + NL"
|
||||
)
|
||||
return lines
|
||||
|
||||
|
||||
def source_files() -> list[Path]:
|
||||
files = sorted(SOURCE_DIR.glob("*.src"), key=lambda p: p.name)
|
||||
bbuild = SOURCE_DIR / "bbuild.src"
|
||||
if bbuild not in files:
|
||||
raise RuntimeError(f"required bootstrap source missing: {bbuild}")
|
||||
if bbuild in files:
|
||||
files.remove(bbuild)
|
||||
files.insert(0, bbuild)
|
||||
return files
|
||||
|
||||
|
||||
def install_binary_lines(var: str, bin_name: str) -> list[str]:
|
||||
return [
|
||||
f'{var}_bin = cp.File("/bin/{bin_name}")',
|
||||
f'if not {var}_bin then exit("Failed to install {bin_name}")',
|
||||
f'{var}_bin.set_group("root")',
|
||||
f'{var}_bin.set_owner("root")',
|
||||
f'{var}_bin.chmod("u+rwx,g+rx,o+rx")',
|
||||
"",
|
||||
]
|
||||
|
||||
|
||||
def build_provision() -> str:
|
||||
sources = source_files()
|
||||
if not sources:
|
||||
raise RuntimeError(f"no .src files found in {SOURCE_DIR}")
|
||||
|
||||
output: list[str] = [
|
||||
"cp = get_shell.host_computer",
|
||||
'home = "/home/" + active_user',
|
||||
"NL = char(10)",
|
||||
'cp.create_folder(home, "source")',
|
||||
"",
|
||||
]
|
||||
|
||||
for src in sources:
|
||||
var = variable_name(src)
|
||||
output.extend(
|
||||
[
|
||||
f'cp.touch(home + "/source/", "{src.name}")',
|
||||
f'{var}_source = cp.File(home + "/source/{src.name}")',
|
||||
*content_lines(var, src.read_text()),
|
||||
f"{var}_source.set_content({var}_content)",
|
||||
"",
|
||||
]
|
||||
)
|
||||
|
||||
bbuild = sources[0]
|
||||
bbuild_var = variable_name(bbuild)
|
||||
output.extend(
|
||||
[
|
||||
f"build_result = get_shell.build({bbuild_var}_source.path, current_path)",
|
||||
'if build_result != "" then exit(build_result)',
|
||||
f'{bbuild_var}_bin = cp.File(current_path + "/bbuild")',
|
||||
f'if not {bbuild_var}_bin then exit("Failed to build bbuild")',
|
||||
f'{bbuild_var}_bin.move("/bin", "bbuild")',
|
||||
*install_binary_lines(bbuild_var, "bbuild"),
|
||||
]
|
||||
)
|
||||
|
||||
for src in sources[1:]:
|
||||
var = variable_name(src)
|
||||
bin_name = src.stem
|
||||
output.extend(
|
||||
[
|
||||
f'get_shell.launch("/bin/bbuild", {var}_source.path)',
|
||||
*install_binary_lines(var, bin_name),
|
||||
]
|
||||
)
|
||||
|
||||
output.extend(
|
||||
[
|
||||
'provision_source = cp.File(home + "/provision.src")',
|
||||
"if provision_source then provision_source.delete",
|
||||
'provision_bin = cp.File(home + "/provision")',
|
||||
"if provision_bin then provision_bin.delete",
|
||||
]
|
||||
)
|
||||
return "\n".join(output) + "\n"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
OUTPUT.write_text(build_provision())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user