83 lines
2.5 KiB
Go
83 lines
2.5 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// Phase identifies a resumable unit of Windows provisioning work.
|
|
type Phase string
|
|
|
|
const (
|
|
PhaseOS Phase = "os"
|
|
PhaseHost Phase = "host"
|
|
PhaseCustom Phase = "custom"
|
|
PhaseConfig Phase = "config"
|
|
PhaseWSL Phase = "wsl"
|
|
)
|
|
|
|
var PhaseOrder = []Phase{PhaseOS, PhaseHost, PhaseCustom, PhaseConfig, PhaseWSL}
|
|
|
|
type Options struct {
|
|
Only Phase
|
|
NoAI bool
|
|
NoWSL bool
|
|
Yes bool
|
|
DryRun bool
|
|
Headless bool
|
|
LinuxReleaseRepo string
|
|
}
|
|
|
|
func ParseOptions(args []string, stderr io.Writer) (Options, error) {
|
|
var opts Options
|
|
var only string
|
|
fs := flag.NewFlagSet("bootstrap_windows_env", flag.ContinueOnError)
|
|
fs.SetOutput(stderr)
|
|
fs.StringVar(&only, "only", "", "run one phase: os, host, custom, config, or wsl")
|
|
fs.BoolVar(&opts.NoAI, "no-ai", false, "omit native AI CLIs and pass --no-ai to the Fedora guest")
|
|
fs.BoolVar(&opts.NoWSL, "no-wsl", false, "omit Fedora WSL provisioning and guest bootstrap")
|
|
fs.BoolVar(&opts.Yes, "yes", false, "execute the displayed plan without confirmation")
|
|
fs.BoolVar(&opts.DryRun, "dry-run", false, "detect state and display work without making changes")
|
|
fs.BoolVar(&opts.Headless, "headless", false, "disable interactive login offers and require --yes to execute")
|
|
fs.StringVar(&opts.LinuxReleaseRepo, "linux-release-repo", "JMR-dev/bootstrap_dev_env", "GitHub repository containing Linux bootstrap releases")
|
|
if err := fs.Parse(args); err != nil {
|
|
return Options{}, err
|
|
}
|
|
if fs.NArg() != 0 {
|
|
return Options{}, fmt.Errorf("unexpected arguments: %v", fs.Args())
|
|
}
|
|
if only != "" {
|
|
opts.Only = Phase(only)
|
|
switch opts.Only {
|
|
case PhaseOS, PhaseHost, PhaseCustom, PhaseConfig, PhaseWSL:
|
|
default:
|
|
return Options{}, fmt.Errorf("invalid --only value %q: use os, host, custom, config, or wsl", only)
|
|
}
|
|
}
|
|
if opts.NoWSL && opts.Only == PhaseWSL {
|
|
return Options{}, fmt.Errorf("--only wsl cannot be combined with --no-wsl")
|
|
}
|
|
if opts.Headless && !opts.Yes && !opts.DryRun {
|
|
return Options{}, fmt.Errorf("--headless execution requires --yes or --dry-run")
|
|
}
|
|
return opts, nil
|
|
}
|
|
|
|
func (o Options) Includes(phase Phase) bool {
|
|
if o.NoWSL && phase == PhaseWSL {
|
|
return false
|
|
}
|
|
return o.Only == "" || o.Only == phase
|
|
}
|
|
|
|
func SelectedPhases(opts Options) []Phase {
|
|
phases := make([]Phase, 0, len(PhaseOrder))
|
|
for _, phase := range PhaseOrder {
|
|
if opts.Includes(phase) {
|
|
phases = append(phases, phase)
|
|
}
|
|
}
|
|
return phases
|
|
}
|