#!/usr/bin/env python3 import argparse from script_common import find_node_app_root, resolve_repo_root, run, sha256_files def main() -> int: parser = argparse.ArgumentParser(description="Cross-platform web/tauri publish helper") parser.add_argument("--target", choices=["web", "tauri"], default="web") parser.add_argument("--configuration", choices=["Release", "Debug"], default="Release") parser.add_argument("--tauri-bundles", choices=["none", "nsis", "msi"], default="none") parser.add_argument("--install-deps", action="store_true") parser.add_argument("--skip-install", action="store_true") parser.add_argument("--dry-run", action="store_true") parser.add_argument("--repo-root", default=None) parser.add_argument("--app-root", default=None, help="Relative or absolute app root with package.json") args = parser.parse_args() repo_root = resolve_repo_root(args.repo_root) app_root = find_node_app_root(repo_root, args.app_root) if app_root is None: print("Unable to locate app root (no unique package.json found).") return 2 package_json = app_root / "package.json" lock_file = app_root / "package-lock.json" node_modules = app_root / "node_modules" deps_hash_file = node_modules / ".sdt-deps.sha256" expected_hash = sha256_files([package_json, lock_file]) should_install = args.install_deps or not node_modules.exists() if not should_install and not args.skip_install: if not deps_hash_file.exists(): should_install = True else: current = deps_hash_file.read_text(encoding="utf-8").strip() should_install = current != expected_hash if args.skip_install: should_install = False print(f"App root: {app_root}") print(f"Target: {args.target} ({args.configuration})") if should_install: install_args = ["ci", "--no-audit", "--fund=false"] if lock_file.exists() else ["install", "--no-audit", "--fund=false"] print("$ npm " + " ".join(install_args)) if not args.dry_run: code = run("npm", install_args, app_root) if code != 0: if lock_file.exists() and install_args[0] == "ci": print("npm ci failed (likely lockfile out of sync). Falling back to npm install...") fallback_args = ["install", "--no-audit", "--fund=false"] print("$ npm " + " ".join(fallback_args)) code = run("npm", fallback_args, app_root) if code != 0: return code else: return code node_modules.mkdir(parents=True, exist_ok=True) deps_hash_file.write_text(expected_hash, encoding="utf-8") else: print("Skipping dependency install.") if args.target == "web": cmd = ["run", "build"] print("$ npm " + " ".join(cmd)) if not args.dry_run: return run("npm", cmd, app_root) return 0 tauri_cmd = ["run", "tauri", "build"] tauri_tail: list[str] = [] if args.tauri_bundles == "none": tauri_tail.extend(["--no-bundle"]) else: tauri_tail.extend(["--bundles", args.tauri_bundles]) if args.configuration == "Debug": tauri_tail.append("--debug") if tauri_tail: tauri_cmd.extend(["--", *tauri_tail]) print("$ npm " + " ".join(tauri_cmd)) if not args.dry_run: return run("npm", tauri_cmd, app_root) return 0 if __name__ == "__main__": raise SystemExit(main())