diff --git a/DevTools/Build_Project.py b/DevTools/Build_Project.py index 4da806b..31cf8e5 100644 --- a/DevTools/Build_Project.py +++ b/DevTools/Build_Project.py @@ -1,9 +1,16 @@ +import sys import sll from pathlib import Path import os import shutil +import TreeLib +import tarfile + +SOURCE_DIR = "" +OUTPUT_DIR = "" + def get_parent_dir(): script_dir = Path(__file__).resolve().parent return script_dir.parent @@ -18,6 +25,81 @@ def delete_dir(path): return True sll.warn(f"Directory non existend or invalid : {target}") return False +def file_exists(filepath: str | Path) -> bool: + path = Path(filepath) + return path.is_file() + +def dir_exists(dirpath: str | Path) -> bool: + path = Path(dirpath) + return path.is_dir() +def get_dir_size(folder_path: Path) -> int: + """Calculates the total size of all files inside a directory (in bytes).""" + total_size = 0 + for file in folder_path.rglob("*"): + if file.is_file(): + total_size += file.stat().st_size + return total_size + +def compress_directory( + source_dir: str | Path, + output_tar: str | Path, + progress_callback=None, +): + """ + Compresses source_dir into a .tar.gz archive at output_tar. + + :param source_dir: The directory to compress. + :param output_tar: Output filename ending in .tar.gz. + :param progress_callback: A function taking a float (0.0 to 100.0). + """ + source_path = Path(source_dir).resolve() + output_path = Path(output_tar).resolve() + + if not source_path.is_dir(): + raise ValueError(f"Source directory '{source_path}' does not exist.") + + # Calculate total bytes for progress tracking + total_bytes = get_dir_size(source_path) + processed_bytes = 0 + + # Ensure parent output dir exists + output_path.parent.mkdir(parents=True, exist_ok=True) + + with tarfile.open(output_path, "w:gz") as tar: + for file_path in source_path.rglob("*"): + # Compute relative path inside the archive + arcname = file_path.relative_to(source_path) + + if file_path.is_file(): + tar.add(file_path, arcname=arcname, recursive=False) + processed_bytes += file_path.stat().st_size + + # Trigger callback with percentage progress + if progress_callback and total_bytes > 0: + percent = (processed_bytes / total_bytes) * 100 + progress_callback(min(percent, 100.0)) + elif file_path.is_dir(): + tar.add(file_path, arcname=arcname, recursive=False) + + # Final explicit 100% notification + if progress_callback: + progress_callback(100.0) + + return output_path + +def bundle_dualroot(): + def showBar(percent: float): + bar = TreeLib.draw_progress_bar(int(percent),20) + sys.stdout.write(f"\r|-> Part 1 - Bundling filesystem {bar}") + sys.stdout.flush() + + if file_exists(str(SOURCE_DIR)+"/include/dualrootfs.tar.gz"): + bar = TreeLib.draw_progress_bar(100,20) + sys.stdout.write(f"\r|-> Part 1 - Bundling filesystem {bar} -> Using pre bundled tarball") + sys.stdout.flush() + + else: + dualroot = compress_directory(str(SOURCE_DIR)+"/include/dual_rootfs",str(OUTPUT_DIR)+"dualrootfs.tar.gz",progress_callback=showBar) @@ -34,6 +116,8 @@ OUTPUT_DIR = create_dir_os(f"{SOURCE_DIR}/output") sll.log(f"Creating output dump -> {OUTPUT_DIR}") sll.log("Checking required source tree") +bundle_dualroot() + diff --git a/Troposphere Docs/.obsidian/workspace.json b/Troposphere Docs/.obsidian/workspace.json index 06ae3c8..58b97cf 100644 --- a/Troposphere Docs/.obsidian/workspace.json +++ b/Troposphere Docs/.obsidian/workspace.json @@ -43,9 +43,9 @@ "state": { "file": "Installer Compiler.canvas", "viewState": { - "x": 119.08203125, - "y": 98.44140625, - "zoom": 0 + "x": -308.8184712754345, + "y": -345.6115967557915, + "zoom": -0.8 } }, "icon": "lucide-layout-dashboard", diff --git a/Troposphere Docs/Installer Compiler.canvas b/Troposphere Docs/Installer Compiler.canvas index 6a35549..c3686f5 100644 --- a/Troposphere Docs/Installer Compiler.canvas +++ b/Troposphere Docs/Installer Compiler.canvas @@ -3,12 +3,22 @@ {"id":"d3356cf33d2adf4b","x":-270,"y":-160,"width":170,"height":60,"type":"text","text":"Start compiling"}, {"id":"9499e7bd3972e410","x":-435,"y":40,"width":250,"height":60,"type":"text","text":"Fetch from config"}, {"id":"5d9eddcdd9aa0902","x":-185,"y":40,"width":250,"height":60,"type":"text","text":"Start questionnaire on what to include"}, - {"id":"0f78f6240cc57aec","x":-310,"y":220,"width":250,"height":60,"type":"text","text":"Stage packages"} + {"id":"0f78f6240cc57aec","x":-310,"y":220,"width":250,"height":60,"type":"text","text":"Stage packages"}, + {"id":"d16eb58cab4b3310","x":-310,"y":-680,"width":250,"height":60,"type":"text","text":"Script"}, + {"id":"92491452a538c1d8","x":-310,"y":-560,"width":250,"height":60,"type":"text","text":"Clear output folder"}, + {"id":"81a2dcc51e105371","x":-310,"y":-460,"width":250,"height":60,"type":"text","text":"New Output"}, + {"id":"a56e2dff6e955514","x":-311,"y":-332,"width":250,"height":60,"type":"text","text":"Copy dualroot into `/output/dualroot.tar.gz`"}, + {"id":"e7fba7bf29006b47","x":-740,"y":-332,"width":250,"height":60,"type":"text","text":"Bundle dualroot if not bundled"} ], "edges":[ {"id":"07f79b7584421b54","fromNode":"d3356cf33d2adf4b","fromSide":"bottom","toNode":"9499e7bd3972e410","toSide":"top"}, {"id":"28fd19de7f80697d","fromNode":"d3356cf33d2adf4b","fromSide":"bottom","toNode":"5d9eddcdd9aa0902","toSide":"top"}, {"id":"ba2c3a14858a0f49","fromNode":"9499e7bd3972e410","fromSide":"bottom","toNode":"0f78f6240cc57aec","toSide":"top"}, - {"id":"e384c4e77327c84d","fromNode":"5d9eddcdd9aa0902","fromSide":"bottom","toNode":"0f78f6240cc57aec","toSide":"top"} + {"id":"e384c4e77327c84d","fromNode":"5d9eddcdd9aa0902","fromSide":"bottom","toNode":"0f78f6240cc57aec","toSide":"top"}, + {"id":"8365728c3dac50ee","fromNode":"d16eb58cab4b3310","fromSide":"bottom","toNode":"92491452a538c1d8","toSide":"top"}, + {"id":"fa2d7adb1c7c3822","fromNode":"92491452a538c1d8","fromSide":"bottom","toNode":"81a2dcc51e105371","toSide":"top"}, + {"id":"d38f255124c915a6","fromNode":"81a2dcc51e105371","fromSide":"bottom","toNode":"a56e2dff6e955514","toSide":"top"}, + {"id":"0d418fc8ed75c772","fromNode":"a56e2dff6e955514","fromSide":"bottom","toNode":"d3356cf33d2adf4b","toSide":"top"}, + {"id":"0e2e2577cb582045","fromNode":"a56e2dff6e955514","fromSide":"left","toNode":"e7fba7bf29006b47","toSide":"right"} ] } \ No newline at end of file