- embed.go: root package exposes Scripts/Assets embed.FS - internal/config: Config struct, Load/Save/Default - internal/runner: Step list, Runner with context cancel, log streaming - internal/tui: bubbletea model - huh form (phase 1) + live log view (phase 2) + summary (phase 3) - cmd/xetup/main.go: main binary, extracts embedded content to tmpdir, runs TUI - Builds to 5.2 MB xetup.exe (GOOS=windows GOARCH=amd64) spec/index.html: - arch-xetup section: mark 5 items flag-done (code now exists) - Add "Nove nastaveni" section linked to Forgejo issue #15 - Add sidebar link for new-requests - Add CSS + JS for request widget (loads/posts to issue #15 comments) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
115 lines
2.8 KiB
Go
115 lines
2.8 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"`
|
|
}
|
|
|
|
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"`
|
|
}
|
|
|
|
// 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,
|
|
"network": true,
|
|
"pcIdentity": 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")
|
|
}
|