254 lines
8.8 KiB
Plaintext
254 lines
8.8 KiB
Plaintext
#!/usr/bin/env nu
|
|
|
|
# Module: Installer Creation Orchestrator
|
|
# Purpose: Orchestrates platform-specific installer generation with analysis, creation, validation
|
|
# Dependencies: installer_metadata, installer_generator, installer_validator, installer_utilities
|
|
|
|
use std log
|
|
|
|
# Import refactored modules
|
|
use ./installer_metadata.nu *
|
|
use ./installer_generator.nu *
|
|
use ./installer_validator.nu *
|
|
use ./installer_utilities.nu *
|
|
|
|
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 = true # Include service installation
|
|
--create-uninstaller = true # Create uninstall scripts
|
|
--sign-packages = false # Sign installation packages
|
|
--validate-installer = true # Validate generated installers
|
|
--compression: string = "gzip" # Compression method for packages
|
|
--verbose # Enable verbose logging
|
|
] {
|
|
|
|
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 = []
|
|
|
|
let result = (do {
|
|
# 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"
|
|
|
|
$summary
|
|
} | complete)
|
|
|
|
if $result.exit_code != 0 {
|
|
log error $"Installer creation failed: ($result.stderr)"
|
|
exit 1
|
|
}
|
|
|
|
$result.stdout
|
|
}
|
|
|
|
# Analysis orchestrator - coordinates metadata analysis
|
|
def analyze_distribution [installer_config: record] {
|
|
log info "Analyzing distribution structure..."
|
|
|
|
let start_time = (date now)
|
|
|
|
let result = (do {
|
|
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)
|
|
}
|
|
} | complete)
|
|
|
|
if $result.exit_code != 0 {
|
|
{
|
|
status: "failed"
|
|
reason: $result.stderr
|
|
duration: ((date now) - $start_time)
|
|
}
|
|
} else {
|
|
$result.stdout
|
|
}
|
|
}
|
|
|
|
# Show installer creation status
|
|
def "main status" [distribution_path: string = ""] {
|
|
if $distribution_path == "" {
|
|
return {
|
|
error: "distribution path required"
|
|
usage: "main status <distribution-path>"
|
|
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
|
|
}
|