From c00692625c9a20058ec6f2e3d7d9649a10ed66cb Mon Sep 17 00:00:00 2001 From: punkfairie <23287005+punkfairie@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:00:44 -0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20yaml=20>=20toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flatten.go | 29 ------- toml.go | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++ yaml.go | 120 ---------------------------- 3 files changed, 228 insertions(+), 149 deletions(-) delete mode 100644 flatten.go create mode 100644 toml.go delete mode 100644 yaml.go diff --git a/flatten.go b/flatten.go deleted file mode 100644 index ef5e379..0000000 --- a/flatten.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "reflect" -) - -func flatten(v ...interface{}) []string { - args := flattenDeep(nil, reflect.ValueOf(v)) - var strings []string - - for _, i := range args { - strings = append(strings, i.(string)) - } - return strings -} - -func flattenDeep(args []interface{}, v reflect.Value) []interface{} { - if v.Kind() == reflect.Interface { - v = v.Elem() - } - if v.Kind() == reflect.Array || v.Kind() == reflect.Slice { - for i := 0; i < v.Len(); i++ { - args = flattenDeep(args, v.Index(i)) - } - } else { - args = append(args, v.Interface()) - } - return args -} diff --git a/toml.go b/toml.go new file mode 100644 index 0000000..d08c806 --- /dev/null +++ b/toml.go @@ -0,0 +1,228 @@ +package main + +import ( + "os" + "strings" + + tea "github.com/charmbracelet/bubbletea" + "gopkg.in/yaml.v3" +) + +type YamlStructure struct { + InstallerPreference InstallerPreference `toml:"installerPreference"` + SoftwarePackages SoftwarePackages `toml:"softwarePackages"` +} + +type InstallerPreference struct { + Apt []string `toml:"apt"` + Darwin []string `toml:"darwin"` + Fedora []string `toml:"fedora"` + Freebsd []string `toml:"freebsd"` + Arch []string `toml:"arch"` + Ubuntu []string `toml:"ubuntu"` + Windows []string `toml:"windows"` + OpenSUSE []string `toml:"openSUSE"` +} + +type SoftwarePackages map[string]SoftwareDef + +type SoftwareDef struct { + App string `toml:"_app"` + Bin map[string]string `toml:"_bin"` + Deprecated bool `toml:"_deprecated"` + Desc string `toml:"_desc"` + Deps []string `toml:"_deps"` + Name string `toml:"_name"` + Post map[string]string `toml:"_post"` + Service string `toml:"_service"` + Systemd string `toml:"_systemd"` + When map[string]string `toml:"_when"` + Apk pkg `toml:"apk"` + Appimage string `toml:"appimage"` + Apt pkg `toml:"apt"` + Basher pkg `toml:"basher"` + Binary osNames `toml:"binary"` + Bpkg pkg `toml:"bpkg"` + Brew pkg `toml:"brew"` + BrewDarwin pkg `toml:"brew:darwin"` + Cargo pkg `toml:"cargo"` + Cask pkg `toml:"cask"` + Crew pkg `toml:"crew"` + Choco pkg `toml:"choco"` + Dnf pkg `toml:"dnf"` + Flatpak pkg `toml:"flatpak"` + Gem pkg `toml:"gem"` + Go pkg `toml:"go"` + Krew pkg `toml:"krew"` + Nix pkg `toml:"nix"` + Npm pkg `toml:"npm"` + Pacman pkg `toml:"pacman"` + Pipx pkg `toml:"pipx"` + PkgFreebsd pkg `toml:"pkg-freebsd"` + PkgTermux pkg `toml:"pkg-termux"` + Port pkg `toml:"port"` + Scoop pkg `toml:"scoop"` + Script osNames `toml:"script"` + Snap pkg `toml:"snap"` + Whalebrew pkg `toml:"whalebrew"` + Winget pkg `toml:"winget"` + Xbps pkg `toml:"xbps"` + Yay pkg `toml:"yay"` + Zypper pkg `toml:"zypper"` +} + +type pkg interface { + String() string + Slice() []string + Length() int +} + +type singlePkg string + +func (s singlePkg) String() string { + return string(s) +} + +func (s singlePkg) Slice() []string { + return []string{string(s)} +} + +func (s singlePkg) Length() int { + return 1 +} + +type multiPkg []string + +func (m multiPkg) String() string { + return m.String() +} + +func (m multiPkg) Slice() []string { + return m +} + +func (m multiPkg) Length() int { + return len(m) +} + +type osNames struct { + Darwin *string `toml:"darwin"` + Linux *string `toml:"linux"` + Windows *string `toml:"windows"` +} + +func (sd SoftwarePackages) UnmarshalTOML(data any) error { + d, _ := data.(map[string]any) + defs, _ := d["softwarePackages"].(map[string]map[string]any) + + for pkg, def := range defs { + decoded := &SoftwareDef{} + + if val, ok := def["_app"]; ok { + decoded.App = val.(string) + } + + if _, ok := def["_deprecated"]; ok { + decoded.Deprecated = true + } + + if val, ok := def["_deps"]; ok { + decoded.Deps = val.([]string) + } + + if val, ok := def["_name"]; ok { + decoded.Name = val.(string) + } + + if val, ok := def["_service"]; ok { + decoded.Service = val.(string) + } + + if val, ok := def["_systemd"]; ok { + decoded.Systemd = val.(string) + } + + if val, ok := def["apk"]; ok { + } + + // Complex, colon keys + for k, v := range def { + if k == "_bin" { + decoded.Bin["_"] = v.(string) + } + + if strings.HasPrefix(k, "_bin:") { + s := strings.TrimPrefix(k, "_bin:") + decoded.Bin[s] = v.(string) + } + + if k == "_post" { + decoded.Post["_"] = v.(string) + } + + if strings.HasPrefix(k, "_post:") { + s := strings.TrimPrefix(k, "_post:") + decoded.Post[s] = v.(string) + } + + if k == "_when" { + decoded.When["_"] = v.(string) + } + + if strings.HasPrefix(k, "_when:") { + s := strings.TrimPrefix(k, "_when:") + decoded.When[s] = v.(string) + } + } + + sd[pkg] = *decoded + } + + return nil +} + +type ChezmoiData struct { + SoftwareGroups SoftwareGroups `toml:"softwareGroups"` +} + +type SoftwareGroups map[string][]string + +type ordersMsg []string + +type recipesMsg SoftwarePackages + +func getOrders(file string) tea.Cmd { + return func() tea.Msg { + fileData, fileErr := os.ReadFile(file) + if fileErr != nil { + return errMsg{fileErr} + } + + var parsedYaml ChezmoiData + + yamlErr := yaml.Unmarshal(fileData, &parsedYaml) + if yamlErr != nil { + return errMsg{yamlErr} + } + + return ordersMsg(parsedYaml.SoftwareGroups[softwareGroup]) + } +} + +func getRecipes(file string) tea.Cmd { + return func() tea.Msg { + fileData, fileErr := os.ReadFile(file) + if fileErr != nil { + return errMsg{fileErr} + } + + var parsedYaml SoftwarePackages + + yamlErr := yaml.Unmarshal(fileData, &parsedYaml) + if yamlErr != nil { + return errMsg{yamlErr} + } + + return recipesMsg(parsedYaml) + } +} diff --git a/yaml.go b/yaml.go deleted file mode 100644 index 398aa5a..0000000 --- a/yaml.go +++ /dev/null @@ -1,120 +0,0 @@ -package main - -import ( - "os" - - tea "github.com/charmbracelet/bubbletea" - "gopkg.in/yaml.v3" -) - -type YamlStructure struct { - InstallerPreference InstallerPreference `yaml:"installerPreference"` - SoftwarePackages SoftwarePackages `yaml:"softwarePackages"` -} - -type InstallerPreference struct { - Apt []string `yaml:"apt"` - Darwin []string `yaml:"darwin"` - Fedora []string `yaml:"fedora"` - Freebsd []string `yaml:"freebsd"` - Arch []string `yaml:"arch"` - Ubuntu []string `yaml:"ubuntu"` - Windows []string `yaml:"windows"` - OpenSUSE []string `yaml:"openSUSE"` -} - -type SoftwarePackages map[string]SoftwareDef - -type SoftwareDef struct { - Bin *string `yaml:"_bin"` - Desc string `yaml:"_desc"` - Deps *[]string `yaml:"_deps"` - Docs *string `yaml:"_docs"` - Github *string `yaml:"_github"` - Home *string `yaml:"_home"` - Name string `yaml:"_name"` - Apk *string `yaml:"apk"` - Appimage *string `yaml:"appimage"` - Basher *string `yaml:"basher"` - Binary *osNames `yaml:"binary"` - Bpkg *string `yaml:"bpkg"` - Brew *string `yaml:"brew"` - Cargo *string `yaml:"cargo"` - Cask *string `yaml:"cask"` - Crew *string `yaml:"crew"` - Choco *string `yaml:"choco"` - Dnf *string `yaml:"dnf"` - Flatpak *string `yaml:"flatpak"` - Gem *string `yaml:"gem"` - Go *string `yaml:"go"` - Krew *string `yaml:"krew"` - Nix *string `yaml:"nix"` - Npm *string `yaml:"npm"` - Pacman *string `yaml:"pacman"` - Pipx *string `yaml:"pipx"` - PkgFreebsd *string `yaml:"pkg-freebsd"` - PkgTermux *string `yaml:"pkg-termux"` - Port *string `yaml:"port"` - Scoop *string `yaml:"scoop"` - Script *string `yaml:"string"` - Snap *string `yaml:"snap"` - Whalebrew *string `yaml:"whalebrew"` - Winget *string `yaml:"winget"` - Xbps *string `yaml:"xbps"` - Yay *string `yaml:"yay"` - Zypper *string `yaml:"zypper"` -} - -type osNames struct { - Darwin *string `yaml:"darwin"` - Linux *string `yaml:"linux"` - Windows *string `yaml:"windows"` -} - -type ChezmoiData struct { - SoftwareGroups SoftwareGroups `yaml:"softwareGroups"` -} - -type SoftwareGroups map[string]any - -type ordersMsg []string - -type recipesMsg SoftwarePackages - -func getOrders(file string) tea.Cmd { - return func() tea.Msg { - fileData, fileErr := os.ReadFile(file) - if fileErr != nil { - return errMsg{fileErr} - } - - var parsedYaml ChezmoiData - - yamlErr := yaml.Unmarshal(fileData, &parsedYaml) - if yamlErr != nil { - return errMsg{yamlErr} - } - - list := flatten(parsedYaml.SoftwareGroups[softwareGroup]) - - return ordersMsg(list) - } -} - -func getRecipes(file string) tea.Cmd { - return func() tea.Msg { - fileData, fileErr := os.ReadFile(file) - if fileErr != nil { - return errMsg{fileErr} - } - - var parsedYaml SoftwarePackages - - yamlErr := yaml.Unmarshal(fileData, &parsedYaml) - if yamlErr != nil { - return errMsg{yamlErr} - } - - return recipesMsg(parsedYaml) - } -}