xetup/internal/config/config.go
X9 Dev 5b53b2a0d6 Add per-feature toggles to PS scripts and Go TUI
- 02-software.ps1: wrap wingetInstalls, pdfDefault, ateraAgent in Get-Feature guards
- 03-system-registry.ps1: add Get-Feature, restructure into 5 gated blocks
  (systemTweaks, edgePolicies, oneDriveUninstall, powercfg, proxyDisable)
- 04-default-profile.ps1: add Get-Feature, wrap taskbarTweaks, startMenuTweaks,
  explorerTweaks; add missing explorerTweaks code (ShowRecent, ShowFrequent, FullPath)
- 11-dell-update.ps1: add Get-Feature, split update run by drivers/bios feature flags
- runner.go: add Feature/StepFeatures/SelectableItem/AllSelectableItems for TUI
- config.go: add Features type and defaults for all 4 gated steps
- tui.go: use AllSelectableItems for MultiSelect, build Features map in startRun,
  remove unused stepFeaturesMap variable
- xetup.exe: Windows amd64 build

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 11:11:51 +02:00

145 lines
3.5 KiB
Go

package config
import (
"encoding/json"
"os"
"path/filepath"
)
// Config mirrors config.json structure.
type Config struct {
Deployment Deployment `json:"deployment"`
AdminAccount AdminAccount `json:"adminAccount"`
Activation Activation `json:"activation"`
Software Software `json:"software"`
Steps map[string]bool `json:"steps"`
Features Features `json:"features"`
}
type Deployment struct {
PCName string `json:"pcName"`
PCDescription string `json:"pcDescription"`
Timezone string `json:"timezone"`
ProfileType string `json:"profileType"` // default | admin | user
}
type AdminAccount struct {
Username string `json:"username"`
}
type Activation struct {
ProductKey string `json:"productKey"`
KMSServer string `json:"kmsServer"`
}
type SoftwareItem struct {
Name string `json:"name"`
WingetID string `json:"wingetId"`
}
type Software struct {
Install []SoftwareItem `json:"install"`
}
// Features holds per-step, per-feature toggle flags.
// Keys: stepID -> featureID -> enabled.
// A missing key defaults to true (feature enabled).
type Features map[string]map[string]bool
// DefaultConfig returns a config with sensible defaults.
func DefaultConfig() Config {
return Config{
Deployment: Deployment{
Timezone: "Central Europe Standard Time",
ProfileType: "default",
},
AdminAccount: AdminAccount{
Username: "adminx9",
},
Activation: Activation{
ProductKey: "",
},
Software: Software{
Install: []SoftwareItem{
{Name: "7-Zip", WingetID: "7zip.7zip"},
{Name: "Adobe Acrobat Reader 64-bit", WingetID: "Adobe.Acrobat.Reader.64-bit"},
{Name: "OpenVPN Connect", WingetID: "OpenVPNTechnologies.OpenVPNConnect"},
},
},
Steps: map[string]bool{
"adminAccount": true,
"bloatware": true,
"software": true,
"systemRegistry": true,
"defaultProfile": true,
"personalization": true,
"scheduledTasks": true,
"backinfo": true,
"activation": true,
"dellUpdate": true,
"network": true,
"pcIdentity": true,
},
Features: Features{
"software": {
"wingetInstalls": true,
"pdfDefault": true,
"ateraAgent": true,
},
"systemRegistry": {
"systemTweaks": true,
"edgePolicies": true,
"oneDriveUninstall": true,
"powercfg": true,
"proxyDisable": true,
},
"defaultProfile": {
"taskbarTweaks": true,
"startMenuTweaks": true,
"explorerTweaks": true,
},
"dellUpdate": {
"drivers": true,
"bios": true,
},
},
}
}
// Load reads config.json from the given path.
// If the file does not exist, returns DefaultConfig without error.
func Load(path string) (Config, error) {
cfg := DefaultConfig()
data, err := os.ReadFile(path)
if os.IsNotExist(err) {
return cfg, nil
}
if err != nil {
return cfg, err
}
if err := json.Unmarshal(data, &cfg); err != nil {
return cfg, err
}
return cfg, nil
}
// Save writes config to the given path (creates directories if needed).
func Save(cfg Config, path string) error {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
return os.WriteFile(path, data, 0644)
}
// ConfigPath returns the default config.json path (next to the executable).
func ConfigPath() string {
exe, err := os.Executable()
if err != nil {
return "config.json"
}
return filepath.Join(filepath.Dir(exe), "config.json")
}