mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
171 lines
4.1 KiB
Go
Executable File
171 lines
4.1 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
_ "embed"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
|
|
"github.com/chenasraf/sofmani/appconfig"
|
|
"github.com/chenasraf/sofmani/cmd"
|
|
"github.com/chenasraf/sofmani/installer"
|
|
"github.com/chenasraf/sofmani/logger"
|
|
"github.com/chenasraf/sofmani/machine"
|
|
"github.com/chenasraf/sofmani/summary"
|
|
"github.com/chenasraf/sofmani/utils"
|
|
)
|
|
|
|
//go:embed version.txt
|
|
var appVersion []byte // appVersion is embedded from version.txt and contains the application version.
|
|
|
|
func init() {
|
|
cmd.RunMain = runMain
|
|
}
|
|
|
|
// main is the entry point of the application.
|
|
func main() {
|
|
cmd.SetVersion(strings.TrimSpace(string(appVersion)))
|
|
cmd.Execute()
|
|
}
|
|
|
|
// runMain runs the main application logic with the given CLI config.
|
|
func runMain(cliConfig *appconfig.AppCliConfig) {
|
|
// Set custom log file if provided
|
|
if cliConfig.LogFile != nil {
|
|
logger.SetLogFile(*cliConfig.LogFile)
|
|
}
|
|
|
|
cfg, err := loadConfigFromCli(cliConfig)
|
|
if err != nil {
|
|
fmt.Println(fmt.Errorf("error loading config: %v", err))
|
|
return
|
|
}
|
|
isDebug := false
|
|
if cfg.Debug != nil {
|
|
isDebug = *cfg.Debug
|
|
}
|
|
logger.InitLogger(isDebug)
|
|
|
|
logger.Debug("Sofmani version %s", appconfig.AppVersion)
|
|
logger.Debug("Log directory: %s", logger.GetLogDir())
|
|
logger.Debug("Log file: %s", logger.GetLogFile())
|
|
if cacheDir, err := utils.GetCacheDir(); err == nil {
|
|
logger.Debug("Cache directory: %s", cacheDir)
|
|
}
|
|
logger.Debug("Config:")
|
|
for _, line := range cfg.GetConfigDesc() {
|
|
logger.Debug("%s", line)
|
|
}
|
|
|
|
// Set MACHINE_ID environment variable
|
|
machineID := machine.GetMachineID()
|
|
logger.Debug("Setting env MACHINE_ID=%s", machineID)
|
|
if err := os.Setenv("MACHINE_ID", machineID); err != nil {
|
|
logger.Error("failed to set environment variable MACHINE_ID: %v", err)
|
|
return
|
|
}
|
|
|
|
if cfg.Env != nil {
|
|
for k, v := range *cfg.Env {
|
|
logger.Debug("Setting env %s=%s", k, v)
|
|
err := os.Setenv(k, v)
|
|
if err != nil {
|
|
logger.Error("failed to set environment variable %s: %v", k, err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.Info("Checking all installers...")
|
|
|
|
// First pass: validate all installers (skip category entries)
|
|
type installItem struct {
|
|
installer installer.IInstaller
|
|
isCategory bool
|
|
data *appconfig.InstallerData
|
|
}
|
|
items := []installItem{}
|
|
hasValidationErrors := false
|
|
|
|
for idx := range cfg.Install {
|
|
i := &cfg.Install[idx]
|
|
|
|
// Handle category entries specially - they don't need validation
|
|
if i.IsCategory() {
|
|
items = append(items, installItem{isCategory: true, data: i})
|
|
continue
|
|
}
|
|
|
|
installerInstance, err := installer.GetInstaller(cfg, i)
|
|
if err != nil {
|
|
logger.Error("%s", err)
|
|
return
|
|
}
|
|
if installerInstance == nil {
|
|
logger.Warn("Installer type %s is not supported, skipping", i.Type)
|
|
} else {
|
|
errors := installerInstance.Validate()
|
|
if len(errors) > 0 {
|
|
hasValidationErrors = true
|
|
for _, e := range errors {
|
|
logger.Error("%s", e.Error())
|
|
}
|
|
} else {
|
|
items = append(items, installItem{installer: installerInstance, data: i})
|
|
}
|
|
}
|
|
}
|
|
|
|
if hasValidationErrors {
|
|
logger.Error("Validation errors found, exiting. Please fix the errors and try again.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Set up signal handling for graceful shutdown
|
|
sigChan := make(chan os.Signal, 1)
|
|
signal.Notify(sigChan, os.Interrupt)
|
|
interrupted := false
|
|
|
|
installSummary := summary.NewSummary()
|
|
for _, item := range items {
|
|
// Check for interrupt before each item
|
|
select {
|
|
case <-sigChan:
|
|
interrupted = true
|
|
logger.Warn("Interrupted by user")
|
|
default:
|
|
}
|
|
if interrupted {
|
|
break
|
|
}
|
|
|
|
// Handle category entries - just log the header
|
|
if item.isCategory {
|
|
logger.Category(*item.data.Category, item.data.Desc, logger.CategoryDisplayMode(cfg.GetCategoryDisplay()))
|
|
continue
|
|
}
|
|
|
|
result, err := installer.RunInstaller(cfg, item.installer)
|
|
if err != nil {
|
|
logger.Error("%s", err)
|
|
break
|
|
}
|
|
if result != nil {
|
|
installSummary.Add(*result)
|
|
}
|
|
}
|
|
|
|
// Print summary if enabled (default: true)
|
|
showSummary := cfg.Summary == nil || *cfg.Summary
|
|
if showSummary {
|
|
installSummary.Print()
|
|
}
|
|
|
|
if interrupted {
|
|
logger.Info("Cancelled")
|
|
os.Exit(130) // Standard exit code for SIGINT
|
|
}
|
|
logger.Info("Complete")
|
|
}
|