#!/usr/bin/env nu # Installer creation tool - creates installation scripts for different platforms # # Creates: # - Platform-specific installation scripts # - Package manager integration (deb, rpm, msi) # - Automated configuration setup # - Service installation and management # - Uninstall scripts and rollback procedures use std log def main [ --distribution-path: string # Path to distribution to create installer for (required) --output-dir: string = "installers" # Output directory for installers --installer-types: string = "shell,package" # Installer types: shell, package, gui, all --platforms: string = "linux,macos,windows" # Target platforms --include-services: bool = true # Include service installation --create-uninstaller: bool = true # Create uninstall scripts --sign-packages: bool = false # Sign installation packages --validate-installer: bool = true # Validate generated installers --compression: string = "gzip" # Compression method for packages --verbose: bool = false # Enable verbose logging ] -> record { if $distribution_path == "" { log error "Distribution path is required" exit 1 } let dist_root = ($distribution_path | path expand) if not ($dist_root | path exists) { log error $"Distribution path does not exist: ($dist_root)" exit 1 } let installer_types_list = if $installer_types == "all" { ["shell", "package", "gui"] } else { ($installer_types | split row "," | each { str trim }) } let platforms_list = ($platforms | split row "," | each { str trim }) let installer_config = { distribution_path: $dist_root output_dir: ($output_dir | path expand) installer_types: $installer_types_list platforms: $platforms_list include_services: $include_services create_uninstaller: $create_uninstaller sign_packages: $sign_packages validate_installer: $validate_installer compression: $compression verbose: $verbose } log info $"Starting installer creation with config: ($installer_config)" # Ensure output directory exists mkdir ($installer_config.output_dir) let creation_results = [] try { # Phase 1: Analyze distribution let analysis_result = analyze_distribution $installer_config let creation_results = ($creation_results | append { phase: "analysis", result: $analysis_result }) if $analysis_result.status != "success" { log error $"Distribution analysis failed: ($analysis_result.reason)" exit 1 } # Phase 2: Create shell installers let shell_result = if "shell" in $installer_config.installer_types { create_shell_installers $installer_config $analysis_result } else { { status: "skipped", reason: "shell installers not requested" } } let creation_results = ($creation_results | append { phase: "shell", result: $shell_result }) # Phase 3: Create package installers let package_result = if "package" in $installer_config.installer_types { create_package_installers $installer_config $analysis_result } else { { status: "skipped", reason: "package installers not requested" } } let creation_results = ($creation_results | append { phase: "package", result: $package_result }) # Phase 4: Create GUI installers let gui_result = if "gui" in $installer_config.installer_types { create_gui_installers $installer_config $analysis_result } else { { status: "skipped", reason: "GUI installers not requested" } } let creation_results = ($creation_results | append { phase: "gui", result: $gui_result }) # Phase 5: Create uninstallers let uninstall_result = if $installer_config.create_uninstaller { create_uninstall_scripts $installer_config $analysis_result } else { { status: "skipped", reason: "uninstaller creation disabled" } } let creation_results = ($creation_results | append { phase: "uninstall", result: $uninstall_result }) # Phase 6: Validate installers let validation_result = if $installer_config.validate_installer { validate_installers $installer_config $creation_results } else { { status: "skipped", reason: "installer validation disabled" } } let creation_results = ($creation_results | append { phase: "validation", result: $validation_result }) let summary = { distribution_path: $installer_config.distribution_path output_directory: $installer_config.output_dir installer_types: ($installer_config.installer_types | length) platforms: ($installer_config.platforms | length) successful_phases: ($creation_results | where {|r| $r.result.status == "success"} | length) total_phases: ($creation_results | length) installers_created: (count_created_installers $creation_results) installer_config: $installer_config phases: $creation_results } log info $"Installer creation completed - ($summary.installers_created) installers created" return $summary } catch {|err| log error $"Installer creation failed: ($err.msg)" exit 1 } } # Analyze the distribution to understand its structure def analyze_distribution [installer_config: record] -> record { log info "Analyzing distribution structure..." let start_time = (date now) try { let dist_path = $installer_config.distribution_path # Detect distribution type and structure let dist_info = { is_archive: (($dist_path | path type) == "file") is_directory: (($dist_path | path type) == "dir") name: ($dist_path | path basename) } # If it's an archive, we need to extract it temporarily for analysis let analysis_path = if $dist_info.is_archive { extract_distribution_for_analysis $dist_path $installer_config } else { $dist_path } # Analyze distribution contents let components = analyze_distribution_components $analysis_path # Detect version information let version_info = detect_distribution_version $analysis_path # Analyze installation requirements let requirements = analyze_installation_requirements $analysis_path $components { status: "success" distribution_info: $dist_info analysis_path: $analysis_path components: $components version_info: $version_info requirements: $requirements duration: ((date now) - $start_time) } } catch {|err| { status: "failed" reason: $err.msg duration: ((date now) - $start_time) } } } # Extract distribution archive for analysis def extract_distribution_for_analysis [dist_path: string, installer_config: record] -> string { let temp_dir = ($installer_config.output_dir | path join "tmp" "analysis") mkdir $temp_dir let dist_name = ($dist_path | path basename) if ($dist_name | str ends-with ".tar.gz") or ($dist_name | str ends-with ".tgz") { cd $temp_dir tar -xzf $dist_path } else if ($dist_name | str ends-with ".zip") { cd $temp_dir unzip $dist_path } else { error $"Unsupported archive format: ($dist_name)" } # Find the extracted directory (usually a single top-level directory) let extracted_contents = (ls $temp_dir) if ($extracted_contents | length) == 1 and (($extracted_contents | get 0.type) == "dir") { return ($extracted_contents | get 0.name) } else { return $temp_dir } } # Analyze distribution components def analyze_distribution_components [analysis_path: string] -> record { let components = { has_platform: (($analysis_path | path join "platform") | path exists) has_core: (($analysis_path | path join "core") | path exists) has_config: (($analysis_path | path join "config") | path exists) has_docs: (($analysis_path | path join "docs") | path exists) has_services: (($analysis_path | path join "services") | path exists) } # Find executables let executables = if $components.has_platform { ls ($analysis_path | path join "platform") | where type == file | get name } else if $components.has_core and (($analysis_path | path join "core" "bin") | path exists) { ls ($analysis_path | path join "core" "bin") | where type == file | get name } else { [] } # Find configuration files let config_files = if $components.has_config { find ($analysis_path | path join "config") -name "*.toml" -o -name "*.yaml" -o -name "*.json" | lines } else { [] } # Find service definitions let service_files = if $components.has_services { find ($analysis_path | path join "services") -name "*.service" -o -name "*.yml" -o -name "*.yaml" | lines } else { [] } let components = ($components | insert executables $executables | insert config_files $config_files | insert service_files $service_files | insert total_size (get_directory_size $analysis_path)) return $components } # Detect distribution version def detect_distribution_version [analysis_path: string] -> record { # Try to find version from metadata let metadata_files = [ ($analysis_path | path join "core-metadata.json") ($analysis_path | path join "platform-metadata.json") ($analysis_path | path join "metadata.json") ($analysis_path | path join "VERSION") ] for metadata_file in $metadata_files { if ($metadata_file | path exists) { let version = try { if ($metadata_file | str ends-with ".json") { let data = (open $metadata_file) return $data.version } else { open $metadata_file --raw | str trim } } catch { "unknown" } if $version != "unknown" { return { version: $version, source: ($metadata_file | path basename) } } } } # Fallback: try to extract from directory name let dir_name = ($analysis_path | path basename) let version_match = ($dir_name | parse --regex ".*-([0-9]+\\.[0-9]+\\.[0-9]+)") if ($version_match | length) > 0 { return { version: ($version_match | get 0.capture0), source: "directory_name" } } return { version: "unknown", source: "none" } } # Analyze installation requirements def analyze_installation_requirements [analysis_path: string, components: record] -> record { let mut requirements = { system_user: "provisioning" system_group: "provisioning" install_dirs: [] config_dirs: [] data_dirs: [] log_dirs: [] service_dependencies: [] port_requirements: [] } # Standard installation directories if $components.has_platform or ($components.executables | length) > 0 { $requirements.install_dirs = ($requirements.install_dirs | append "/usr/local/bin") } if $components.has_core { $requirements.install_dirs = ($requirements.install_dirs | append "/usr/local/lib/provisioning") } if $components.has_config { $requirements.config_dirs = ($requirements.config_dirs | append "/etc/provisioning") } # Data and log directories $requirements.data_dirs = ($requirements.data_dirs | append "/var/lib/provisioning") $requirements.log_dirs = ($requirements.log_dirs | append "/var/log/provisioning") # Service dependencies (would analyze service files to determine) if $components.has_services { $requirements.service_dependencies = ($requirements.service_dependencies | append "network.target") } # Port requirements (would analyze configuration to determine) $requirements.port_requirements = ($requirements.port_requirements | append { port: 8080, description: "Main API" }) return $requirements } # Create shell installers for different platforms def create_shell_installers [ installer_config: record analysis_result: record ] -> record { log info "Creating shell installers..." let start_time = (date now) try { let mut created_installers = [] for platform in $installer_config.platforms { match $platform { "linux" | "macos" => { let installer_result = create_unix_shell_installer $platform $installer_config $analysis_result if $installer_result.status == "success" { $created_installers = ($created_installers | append $installer_result) } } "windows" => { let installer_result = create_windows_batch_installer $installer_config $analysis_result if $installer_result.status == "success" { $created_installers = ($created_installers | append $installer_result) } } _ => { log warning $"Unsupported platform for shell installer: ($platform)" } } } { status: "success" installers_created: ($created_installers | length) created_installers: $created_installers duration: ((date now) - $start_time) } } catch {|err| { status: "failed" reason: $err.msg duration: ((date now) - $start_time) } } } # Create Unix shell installer def create_unix_shell_installer [ platform: string installer_config: record analysis_result: record ] -> record { let version = $analysis_result.version_info.version let components = $analysis_result.components let requirements = $analysis_result.requirements let installer_content = $"#!/bin/bash # Provisioning System Installer # Platform: ($platform) # Version: ($version) set -e # Colors for output RED='\\033[0;31m' GREEN='\\033[0;32m' YELLOW='\\033[1;33m' NC='\\033[0m' # No Color # Configuration INSTALL_USER=\"($requirements.system_user)\" INSTALL_GROUP=\"($requirements.system_group)\" SERVICE_NAME=\"provisioning\" # Installation directories BIN_DIR=\"/usr/local/bin\" LIB_DIR=\"/usr/local/lib/provisioning\" CONFIG_DIR=\"/etc/provisioning\" DATA_DIR=\"/var/lib/provisioning\" LOG_DIR=\"/var/log/provisioning\" # Functions log_info() { echo -e \"${GREEN}[INFO]${NC} $1\" } log_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\" } log_error() { echo -e \"${RED}[ERROR]${NC} $1\" } check_root() { if [[ $EUID -ne 0 ]]; then log_error \"This script must be run as root (use sudo)\" exit 1 fi } create_user() { if ! id \"$INSTALL_USER\" >/dev/null 2>&1; then log_info \"Creating user: $INSTALL_USER\" useradd -r -s /bin/false -m -d \"$DATA_DIR\" \"$INSTALL_USER\" usermod -a -G \"$INSTALL_GROUP\" \"$INSTALL_USER\" 2>/dev/null || true else log_info \"User $INSTALL_USER already exists\" fi } create_directories() { log_info \"Creating directories...\" mkdir -p \"$BIN_DIR\" \"$LIB_DIR\" \"$CONFIG_DIR\" \"$DATA_DIR\" \"$LOG_DIR\" # Set ownership chown -R \"$INSTALL_USER:$INSTALL_GROUP\" \"$DATA_DIR\" \"$LOG_DIR\" chmod 755 \"$DATA_DIR\" \"$LOG_DIR\" } install_binaries() { log_info \"Installing binaries...\" if [[ -d \"platform\" ]]; then cp platform/* \"$BIN_DIR/\" chmod +x \"$BIN_DIR\"/provisioning-* elif [[ -d \"core/bin\" ]]; then cp core/bin/* \"$BIN_DIR/\" chmod +x \"$BIN_DIR\"/provisioning* else log_error \"No binaries found to install\" return 1 fi } install_libraries() { if [[ -d \"core\" ]]; then log_info \"Installing core libraries...\" cp -r core/* \"$LIB_DIR/\" chown -R root:root \"$LIB_DIR\" find \"$LIB_DIR\" -type f -name \"*.nu\" -exec chmod 644 {} \\; fi } install_configuration() { if [[ -d \"config\" ]]; then log_info \"Installing configuration...\" cp config/*.toml \"$CONFIG_DIR/\" 2>/dev/null || true cp config/*.template \"$CONFIG_DIR/\" 2>/dev/null || true # Set secure permissions on config files chown -R root:\"$INSTALL_GROUP\" \"$CONFIG_DIR\" chmod 755 \"$CONFIG_DIR\" find \"$CONFIG_DIR\" -name \"*.toml\" -exec chmod 640 {} \\; fi } install_services() { if [[ -d \"services\" ]] && command -v systemctl >/dev/null 2>&1; then log_info \"Installing systemd services...\" cp services/*.service /etc/systemd/system/ 2>/dev/null || true systemctl daemon-reload # Enable but don't start services for service in services/*.service; do if [[ -f \"$service\" ]]; then service_name=$(basename \"$service\") log_info \"Enabling service: $service_name\" systemctl enable \"$service_name\" fi done fi } configure_environment() { log_info \"Configuring environment...\" # Create environment file cat > /etc/environment.d/provisioning.conf << EOF PROVISIONING_HOME=\"$LIB_DIR\" PROVISIONING_CONFIG=\"$CONFIG_DIR\" PROVISIONING_DATA=\"$DATA_DIR\" PROVISIONING_LOG=\"$LOG_DIR\" EOF # Create shell profile cat > /etc/profile.d/provisioning.sh << 'EOF' # Provisioning System Environment if [ -d \"/usr/local/bin\" ]; then case \":$PATH:\" in *:/usr/local/bin:*) ;; *) PATH=\"/usr/local/bin:$PATH\" ;; esac fi export PROVISIONING_HOME=\"/usr/local/lib/provisioning\" export PROVISIONING_CONFIG=\"/etc/provisioning\" EOF } setup_logrotate() { log_info \"Setting up log rotation...\" cat > /etc/logrotate.d/provisioning << 'EOF' /var/log/provisioning/*.log { daily missingok rotate 52 compress delaycompress notifempty create 644 provisioning provisioning } EOF } main() { log_info \"Starting Provisioning System installation...\" check_root create_user create_directories install_binaries install_libraries install_configuration if [[ \"$1\" != \"--no-services\" ]]; then install_services fi configure_environment setup_logrotate log_info \"Installation completed successfully!\" log_info \"\" log_info \"Next steps:\" log_info \" 1. Review configuration in $CONFIG_DIR\" log_info \" 2. Start services: sudo systemctl start provisioning\" log_info \" 3. Run 'provisioning help' to get started\" log_info \"\" log_info \"For more information, see the documentation in $LIB_DIR/docs\" } # Handle command line arguments case \"$1\" in --help|-h) echo \"Provisioning System Installer ($version)\" echo \"\" echo \"Usage: $0 [OPTIONS]\" echo \"\" echo \"Options:\" echo \" --no-services Skip service installation\" echo \" --help, -h Show this help message\" exit 0 ;; *) main \"$@\" ;; esac " let installer_file = ($installer_config.output_dir | path join $"install-($platform).sh") $installer_content | save $installer_file chmod +x $installer_file { platform: $platform status: "success" installer_type: "shell" installer_file: $installer_file size: ($installer_content | str length) } } # Create Windows batch installer def create_windows_batch_installer [ installer_config: record analysis_result: record ] -> record { let version = $analysis_result.version_info.version let components = $analysis_result.components let installer_content = $"@echo off REM Provisioning System Installer REM Platform: Windows REM Version: ($version) setlocal EnableDelayedExpansion REM Configuration set \"INSTALL_DIR=C:\\Program Files\\Provisioning\" set \"CONFIG_DIR=C:\\ProgramData\\Provisioning\" set \"SERVICE_NAME=ProvisioningService\" echo. echo ======================================== echo Provisioning System Installer ($version) echo ======================================== echo. REM Check for administrator privileges net session >nul 2>&1 if %errorLevel% neq 0 ( echo ERROR: This script must be run as Administrator echo Right-click and select \"Run as administrator\" pause exit /b 1 ) echo Creating directories... mkdir \"%INSTALL_DIR%\\bin\" 2>nul mkdir \"%INSTALL_DIR%\\lib\" 2>nul mkdir \"%CONFIG_DIR%\" 2>nul echo Installing binaries... if exist \"platform\\\" ( xcopy platform\\* \"%INSTALL_DIR%\\bin\\\" /Y /Q ) else if exist \"core\\bin\\\" ( xcopy core\\bin\\* \"%INSTALL_DIR%\\bin\\\" /Y /Q ) else ( echo ERROR: No binaries found to install pause exit /b 1 ) echo Installing libraries... if exist \"core\\\" ( xcopy core\\* \"%INSTALL_DIR%\\lib\\\" /Y /Q /S ) echo Installing configuration... if exist \"config\\\" ( xcopy config\\* \"%CONFIG_DIR%\\\" /Y /Q /S ) echo Configuring environment... REM Add installation directory to system PATH for /f \"usebackq tokens=2,*\" %%A in (`reg query HKCU\\Environment /v PATH`) do set \"current_path=%%B\" echo !current_path! | findstr /C:\"%INSTALL_DIR%\\bin\" >nul if !errorLevel! neq 0 ( setx PATH \"!current_path!;%INSTALL_DIR%\\bin\" echo Added %INSTALL_DIR%\\bin to PATH ) REM Set environment variables setx PROVISIONING_HOME \"%INSTALL_DIR%\" setx PROVISIONING_CONFIG \"%CONFIG_DIR%\" echo. echo Installation completed successfully! echo. echo Next steps: echo 1. Review configuration in %CONFIG_DIR% echo 2. Run 'provisioning-orchestrator --help' to get started echo 3. Check the documentation in %INSTALL_DIR%\\lib\\docs echo. echo NOTE: You may need to restart your command prompt for PATH changes to take effect. echo. pause " let installer_file = ($installer_config.output_dir | path join "install-windows.bat") $installer_content | save $installer_file { platform: "windows" status: "success" installer_type: "batch" installer_file: $installer_file size: ($installer_content | str length) } } # Create package installers (deb, rpm, msi) def create_package_installers [ installer_config: record analysis_result: record ] -> record { log info "Creating package installers..." let start_time = (date now) # Package creation would involve: # 1. Creating package control files # 2. Building packages with appropriate tools # 3. Signing packages if requested log warning "Package installer creation not fully implemented" { status: "skipped" reason: "package installers not fully implemented" installers_created: 0 duration: ((date now) - $start_time) } } # Create GUI installers def create_gui_installers [ installer_config: record analysis_result: record ] -> record { log info "Creating GUI installers..." let start_time = (date now) # GUI installer creation would involve: # 1. Creating installer definition files # 2. Using platform-specific tools (NSIS, InstallShield, etc.) # 3. Including custom installation wizards log warning "GUI installer creation not fully implemented" { status: "skipped" reason: "GUI installers not fully implemented" installers_created: 0 duration: ((date now) - $start_time) } } # Create uninstall scripts def create_uninstall_scripts [ installer_config: record analysis_result: record ] -> record { log info "Creating uninstall scripts..." let start_time = (date now) try { let mut created_uninstallers = [] for platform in $installer_config.platforms { match $platform { "linux" | "macos" => { let uninstaller_result = create_unix_uninstaller $platform $installer_config $analysis_result if $uninstaller_result.status == "success" { $created_uninstallers = ($created_uninstallers | append $uninstaller_result) } } "windows" => { let uninstaller_result = create_windows_uninstaller $installer_config $analysis_result if $uninstaller_result.status == "success" { $created_uninstallers = ($created_uninstallers | append $uninstaller_result) } } _ => { log warning $"Unsupported platform for uninstaller: ($platform)" } } } { status: "success" uninstallers_created: ($created_uninstallers | length) created_uninstallers: $created_uninstallers duration: ((date now) - $start_time) } } catch {|err| { status: "failed" reason: $err.msg duration: ((date now) - $start_time) } } } # Create Unix uninstaller def create_unix_uninstaller [ platform: string installer_config: record analysis_result: record ] -> record { let version = $analysis_result.version_info.version let requirements = $analysis_result.requirements let uninstaller_content = $"#!/bin/bash # Provisioning System Uninstaller # Platform: ($platform) # Version: ($version) set -e # Colors for output RED='\\033[0;31m' GREEN='\\033[0;32m' YELLOW='\\033[1;33m' NC='\\033[0m' log_info() { echo -e \"${GREEN}[INFO]${NC} $1\" } log_warn() { echo -e \"${YELLOW}[WARN]${NC} $1\" } log_error() { echo -e \"${RED}[ERROR]${NC} $1\" } check_root() { if [[ $EUID -ne 0 ]]; then log_error \"This script must be run as root (use sudo)\" exit 1 fi } confirm_uninstall() { echo \"This will completely remove the Provisioning System from your system.\" echo \"This includes:\" echo \" - All binaries and libraries\" echo \" - Configuration files\" echo \" - Service definitions\" echo \" - Log files and data\" echo \"\" read -p \"Are you sure you want to continue? (y/N): \" -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_info \"Uninstallation cancelled\" exit 0 fi } stop_services() { log_info \"Stopping services...\" if command -v systemctl >/dev/null 2>&1; then systemctl stop provisioning* 2>/dev/null || true systemctl disable provisioning* 2>/dev/null || true fi } remove_binaries() { log_info \"Removing binaries...\" rm -f /usr/local/bin/provisioning* } remove_libraries() { log_info \"Removing libraries...\" rm -rf /usr/local/lib/provisioning } remove_configuration() { log_info \"Removing configuration...\" rm -rf /etc/provisioning } remove_data() { if [[ \"$1\" == \"--keep-data\" ]]; then log_info \"Keeping data directory (--keep-data specified)\" else log_info \"Removing data and logs...\" rm -rf /var/lib/provisioning rm -rf /var/log/provisioning fi } remove_services() { log_info \"Removing service definitions...\" rm -f /etc/systemd/system/provisioning*.service if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload fi } remove_environment() { log_info \"Removing environment configuration...\" rm -f /etc/environment.d/provisioning.conf rm -f /etc/profile.d/provisioning.sh rm -f /etc/logrotate.d/provisioning } remove_user() { if [[ \"$1\" == \"--keep-user\" ]]; then log_info \"Keeping system user (--keep-user specified)\" else log_info \"Removing system user...\" userdel provisioning 2>/dev/null || true fi } main() { log_info \"Starting Provisioning System uninstallation...\" check_root confirm_uninstall stop_services remove_services remove_binaries remove_libraries remove_configuration remove_data \"$1\" remove_environment remove_user \"$1\" log_info \"Uninstallation completed successfully!\" log_info \"\" log_info \"Thank you for using the Provisioning System.\" } case \"$1\" in --help|-h) echo \"Provisioning System Uninstaller ($version)\" echo \"\" echo \"Usage: $0 [OPTIONS]\" echo \"\" echo \"Options:\" echo \" --keep-data Keep data directory and logs\" echo \" --keep-user Keep system user account\" echo \" --help, -h Show this help message\" exit 0 ;; *) main \"$@\" ;; esac " let uninstaller_file = ($installer_config.output_dir | path join $"uninstall-($platform).sh") $uninstaller_content | save $uninstaller_file chmod +x $uninstaller_file { platform: $platform status: "success" uninstaller_type: "shell" uninstaller_file: $uninstaller_file size: ($uninstaller_content | str length) } } # Create Windows uninstaller def create_windows_uninstaller [ installer_config: record analysis_result: record ] -> record { let version = $analysis_result.version_info.version let uninstaller_content = $"@echo off REM Provisioning System Uninstaller REM Platform: Windows REM Version: ($version) setlocal EnableDelayedExpansion echo. echo ========================================== echo Provisioning System Uninstaller ($version) echo ========================================== echo. REM Check for administrator privileges net session >nul 2>&1 if %errorLevel% neq 0 ( echo ERROR: This script must be run as Administrator pause exit /b 1 ) echo This will completely remove the Provisioning System from your system. echo. set /p \"confirm=Are you sure you want to continue? (y/N): \" if /I not \"!confirm!\"==\"y\" ( echo Uninstallation cancelled exit /b 0 ) echo. echo Stopping services... REM Stop any running services here echo Removing installation directory... if exist \"C:\\Program Files\\Provisioning\" ( rmdir /S /Q \"C:\\Program Files\\Provisioning\" ) echo Removing configuration... if exist \"C:\\ProgramData\\Provisioning\" ( rmdir /S /Q \"C:\\ProgramData\\Provisioning\" ) echo Removing environment variables... reg delete HKCU\\Environment /v PROVISIONING_HOME /f 2>nul reg delete HKCU\\Environment /v PROVISIONING_CONFIG /f 2>nul echo Removing from PATH... for /f \"usebackq tokens=2,*\" %%A in (`reg query HKCU\\Environment /v PATH 2^>nul`) do ( set \"current_path=%%B\" set \"new_path=!current_path:C:\\Program Files\\Provisioning\\bin;=!\" set \"new_path=!new_path:;C:\\Program Files\\Provisioning\\bin=!\" if not \"!new_path!\"==\"!current_path!\" ( setx PATH \"!new_path!\" echo Removed from PATH ) ) echo. echo Uninstallation completed successfully! echo Thank you for using the Provisioning System. echo. pause " let uninstaller_file = ($installer_config.output_dir | path join "uninstall-windows.bat") $uninstaller_content | save $uninstaller_file { platform: "windows" status: "success" uninstaller_type: "batch" uninstaller_file: $uninstaller_file size: ($uninstaller_content | str length) } } # Validate generated installers def validate_installers [ installer_config: record creation_results: list ] -> record { log info "Validating installers..." let start_time = (date now) # Installer validation would involve: # 1. Syntax checking of shell scripts # 2. Testing installation in clean environments # 3. Verifying uninstaller functionality log warning "Installer validation not fully implemented" { status: "skipped" reason: "installer validation not fully implemented" validated_installers: 0 duration: ((date now) - $start_time) } } # Count created installers from results def count_created_installers [creation_results: list] -> int { let shell_count = try { let shell_result = ($creation_results | where phase == "shell" | get 0.result) $shell_result.installers_created } catch { 0 } let package_count = try { let package_result = ($creation_results | where phase == "package" | get 0.result) $package_result.installers_created } catch { 0 } let gui_count = try { let gui_result = ($creation_results | where phase == "gui" | get 0.result) $gui_result.installers_created } catch { 0 } let uninstall_count = try { let uninstall_result = ($creation_results | where phase == "uninstall" | get 0.result) $uninstall_result.uninstallers_created } catch { 0 } return ($shell_count + $package_count + $gui_count + $uninstall_count) } # Get directory size helper def get_directory_size [dir: string] -> int { if not ($dir | path exists) { return 0 } try { find $dir -type f | each {|file| ls $file | get 0.size } | math sum | if $in == null { 0 } else { $in } } catch { 0 } } # Show installer creation status def "main status" [distribution_path: string = ""] { if $distribution_path == "" { return { error: "distribution path required" usage: "main status " supported_platforms: ["linux", "macos", "windows"] installer_types: ["shell", "package", "gui"] } } let dist_path = ($distribution_path | path expand) if not ($dist_path | path exists) { return { error: "distribution path does not exist" path: $dist_path } } # Quick analysis of distribution let dist_info = { path: $dist_path type: ($dist_path | path type) name: ($dist_path | path basename) size: (get_directory_size $dist_path) } { distribution: $dist_info can_create_installers: true supported_platforms: ["linux", "macos", "windows"] installer_types: ["shell", "package", "gui"] features: { shell_installers: true package_installers: false # Not fully implemented gui_installers: false # Not fully implemented uninstallers: true service_management: true } } } # Quick installer creation with minimal options def "main quick" [ distribution_path: string # Distribution to create installer for --platform: string = "linux" # Single platform --output-dir: string = "installers" # Output directory ] { main $distribution_path --platforms $platform --installer-types shell --output-dir $output_dir }