From 0e1c61fa8cf434159ca1d7b7a0a42faf9759cd0d Mon Sep 17 00:00:00 2001 From: rsteube Date: Tue, 13 Feb 2024 18:24:18 +0100 Subject: [PATCH] spec: global folder --- .goreleaser.yml | 5 ++ cmd/carapace/cmd/completers/completers.go | 80 ++++++++++++++++++----- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 97627ddb3e..6246365da3 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -66,6 +66,11 @@ aurs: - carapace conflicts: - carapace + package: |- + install -Dm755 "./carapace" "${pkgdir}/usr/bin/carapace" + mkdir -p "${pkgdir}/etc/xdg/carapace/specs" + mkdir -p "${pkgdir}/etc/xdg/carapace/variables" + nfpms: - diff --git a/cmd/carapace/cmd/completers/completers.go b/cmd/carapace/cmd/completers/completers.go index d962141851..362b2ea4ef 100644 --- a/cmd/carapace/cmd/completers/completers.go +++ b/cmd/carapace/cmd/completers/completers.go @@ -1,6 +1,7 @@ package completers import ( + "errors" "fmt" "os" "path/filepath" @@ -8,6 +9,7 @@ import ( "sort" "strings" + "github.com/rsteube/carapace" "github.com/rsteube/carapace-bin/pkg/env" "github.com/rsteube/carapace/pkg/xdg" "gopkg.in/yaml.v3" @@ -42,7 +44,7 @@ func Names() []string { } } //if specNames, err := Specs(); err == nil { - if specNames, _ := Specs(); true { // TODO use and handle err + if specNames := Specs(); true { // TODO use and handle err for _, name := range specNames { unique[name] = true } @@ -57,11 +59,37 @@ func Names() []string { } func SpecPath(name string) (string, error) { - configDir, err := xdg.UserConfigDir() - if err != nil { - return "", err + userConfigDir, err := xdg.UserConfigDir() + var path string + if err == nil { + path, err = specPath(userConfigDir, name) + if err == nil { + return path, nil + } + } + + if err != nil { // TODO have another look at the error handling here + if !os.IsNotExist(err) { + carapace.LOG.Println(err.Error()) + } + + configDirs, err := xdg.ConfigDirs() + if err != nil { + return "", err + } + for _, dir := range configDirs { + path, err = specPath(dir, name) + if err != nil { + carapace.LOG.Println(err.Error()) + continue + } + return path, err + } } + return "", errors.New("no spec found") +} +func specPath(configDir string, name string) (string, error) { path := fmt.Sprintf("%v/carapace/specs/%v.yaml", configDir, name) if _, err := os.Stat(path); err != nil { return "", err @@ -93,22 +121,42 @@ func OverlayPath(name string) (string, error) { return abs, nil } -func Specs() (specs []string, dir string) { +func Specs() []string { + unique := make(map[string]bool) + + if userConfigDir, err := xdg.UserConfigDir(); err == nil { + for _, spec := range specs(userConfigDir) { + unique[spec] = true + } + } + + if configDirs, err := xdg.ConfigDirs(); err == nil { + for _, dir := range configDirs { + for _, spec := range specs(dir) { + unique[spec] = true + } + } + } + + result := make([]string, 0) + for spec := range unique { + result = append(result, spec) + } + return result +} + +func specs(configDir string) []string { r := regexp.MustCompile(`^[0-9a-zA-Z_\-.]+\.yaml$`) // sanity check - specs = make([]string, 0) - if configDir, err := xdg.UserConfigDir(); err == nil { - dir = configDir + "/carapace/specs" - if entries, err := os.ReadDir(dir); err == nil { - for _, entry := range entries { - if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".yaml") && r.MatchString(entry.Name()) { - specs = append(specs, strings.TrimSuffix(entry.Name(), ".yaml")) - } + specs := make([]string, 0) + dir := configDir + "/carapace/specs" + if entries, err := os.ReadDir(dir); err == nil { + for _, entry := range entries { + if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".yaml") && r.MatchString(entry.Name()) { + specs = append(specs, strings.TrimSuffix(entry.Name(), ".yaml")) } - } else if os.IsNotExist(err) { - os.MkdirAll(dir, os.ModePerm) } } - return + return specs } func Description(name string) string {