diff options
| -rw-r--r-- | cache/cache.go | 12 | ||||
| -rw-r--r-- | cache/cache_test.go | 10 | ||||
| -rw-r--r-- | completion/completion.go | 4 | ||||
| -rw-r--r-- | main.go | 13 | ||||
| -rw-r--r-- | modes.go | 16 |
5 files changed, 29 insertions, 26 deletions
diff --git a/cache/cache.go b/cache/cache.go index 2784e23..9f25af0 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -12,18 +12,13 @@ import ( "strings" ) +// Cache is a wrapper for its entries. I guess it could be a plain type. type Cache struct { Entries []Entry } type cacheInit struct{} -var Init model.Initializer = &cacheInit{} - -func (i *cacheInit) Init() error { - return nil -} - // Merge combines two caches and filters duplicate keys func (c *Cache) Merge(other *Cache) *Cache { switch { @@ -46,11 +41,13 @@ func (c *Cache) Merge(other *Cache) *Cache { return result } +// Entry is a cache entry containing a path and name type Entry struct { Path string Label string } +// String returns the string representation of this cache entry func (e Entry) String() string { return e.Path + " # " + e.Label } @@ -104,6 +101,7 @@ func (c *Cache) Marshal() []byte { return []byte(b.String()) } +// String returns the string representation of the Cache func (c *Cache) String() string { return string(c.Marshal()) } @@ -118,6 +116,8 @@ func New(st *model.State) *Cache { return c } +// MergeAndSave creates a cache from a state, combines it with +// a potential saved context file, and writes it to disk func MergeAndSave(in *model.State) error { root := "/" f := os.DirFS(root) diff --git a/cache/cache_test.go b/cache/cache_test.go index 204f670..7746be4 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -207,16 +207,6 @@ func TestMergeNilNormal(t *testing.T) { _ = e.Merge(c) } -func TestCacheInit_Init(t *testing.T) { - d := t.TempDir() - paths.SetAll(d) - defer paths.Reset() - c := &cacheInit{} - err := c.Init() - assert.NoError(t, err) - assert.Contains(t, paths.ContextsFile.String(), d) -} - func TestInsert(t *testing.T) { d := t.TempDir() st := TState(TSource("source", "target")) diff --git a/completion/completion.go b/completion/completion.go index 641eb8a..9d3ae72 100644 --- a/completion/completion.go +++ b/completion/completion.go @@ -31,8 +31,10 @@ var completionFileByShell = map[string]string{ "zsh": ".zshrc", } +// AlreadyInstalledError is returned when we already found completion code in your shell rc file var AlreadyInstalledError = errors.New("completion already installed") +// Add finds the right file to append the completion code to and does that func Add(shell string) error { f := filepath.Join(paths.HomeDir.String(), completionFileByShell[shell]) content, err := os.ReadFile(f) @@ -59,6 +61,8 @@ func successMessage(shell string, file string) { _, _ = spool.Print("Installed completion for %s in %s\n", shell, file) } +// Echo prints the actual completion script +// because it is baked in with the program it should always be version-appropriate func Echo() error { _, err := spool.Print("%s", completionCode) return err @@ -30,7 +30,6 @@ import ( // useful for initializing stuff like paths, preparing directories, and reading the environment var syncInitializers = ComponentList[model.Initializer]{ paths.Component, - cache.Init, } // initializers are ran before indexing with the indexers, @@ -108,17 +107,23 @@ func mode[T any](list ModeMap[T], fire func(mode T) error) *int { func pik() int { pflag.Parse() - syncInitializers.RunSync(func(initializer model.Initializer) error { - return initializer.Init() + code := mode(uninitializedModes, func(mode func() error) error { + return mode() }) + if code != nil { + return *code + } - code := mode(statelessModes, func(mode func() error) error { + code = mode(statelessModes, func(mode func() error) error { return mode() }) if code != nil { return *code } + syncInitializers.RunSync(func(initializer model.Initializer) error { + return initializer.Init() + }) initializers.RunAsync(func(initializer model.Initializer) error { return initializer.Init() }) @@ -46,13 +46,20 @@ var profileFd *os.File var UnknownShellError = errors.New("$SHELL not set or empty") -// statelessModes are program modes which do not require state to operate. -// like --version and --completion -var statelessModes = ModeMap[func() error]{ +// uninitializedModes are modes which can run before the program runs initializers +var uninitializedModes = ModeMap[func() error]{ flags.Version: func() error { _, err := spool.Print("%s\n", version) return err }, + flags.Completion: func() error { + return completion.Echo() + }, +} + +// statelessModes are program modes which do not require state to operate. +// like --version and --completion +var statelessModes = ModeMap[func() error]{ flags.InstallCompletion: func() error { sh := os.Getenv("SHELL") if sh == "" { @@ -61,9 +68,6 @@ var statelessModes = ModeMap[func() error]{ _, sh = filepath.Split(sh) return completion.Add(sh) }, - flags.Completion: func() error { - return completion.Echo() - }, flags.Profile: func() error { fd, err := os.Create("pik-profile.out") if err != nil { |
