package main import ( "context" "flag" "fmt" "io" "os" "path/filepath" "strings" "time" "softbox.local/app-modern/platform/windows" "softbox.local/core/updater" ) func main() { if err := run(os.Args[1:]); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func run(arguments []string) error { for _, option := range []string{"--pid", "--staging", "--target"} { if err := requireOneOption(arguments, option); err != nil { return err } } flags := flag.NewFlagSet("SoftBoxUpdater", flag.ContinueOnError) flags.SetOutput(io.Discard) pid := flags.Int("pid", 0, "main SoftBox PID") staging := flags.String("staging", "", "prepared staging directory") target := flags.String("target", "", "fixed app target directory") if err := flags.Parse(arguments); err != nil { return fmt.Errorf("parse updater arguments: %w", err) } if flags.NArg() != 0 || *pid <= 0 || *staging == "" || *target == "" || !filepath.IsAbs(*staging) || !filepath.IsAbs(*target) { return fmt.Errorf("usage: SoftBoxUpdater --pid --staging --target ") } requestID := filepath.Base(filepath.Clean(*staging)) platform := windows.New() service := updater.NewService(platform, platform, platform, updater.FileHealthWaiter{}, updater.Timeouts{ ParentExit: 2 * time.Minute, Health: 45 * time.Second, }) return service.Update(context.Background(), updater.Request{ ParentPID: *pid, StagingDir: *staging, TargetDir: *target, RequestID: requestID, }) } func requireOneOption(arguments []string, option string) error { count := 0 for _, argument := range arguments { if argument == option || strings.HasPrefix(argument, option+"=") { count++ } } if count != 1 { return fmt.Errorf("%s must appear exactly once", option) } return nil }