summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorewy <ewy0@protonmail.com>2026-04-22 21:51:29 +0200
committerewy <ewy0@protonmail.com>2026-04-22 21:51:29 +0200
commitd88661935fa2b6e2c0fe93345800113e1a71b451 (patch)
tree0002f1152a4eebafee6e3dea4065964a50d786c0
parentdeebd135ffcb1c167f12ecf2d4c0aebdc14cbc86 (diff)
docs
-rw-r--r--cache/cache.go6
-rw-r--r--crawl/crawl.go5
-rw-r--r--describe/describe.go3
-rw-r--r--env/env.go4
-rw-r--r--flags/flags.go31
-rw-r--r--git/git.go3
-rw-r--r--identity/identity.go4
-rw-r--r--search/search.go19
8 files changed, 60 insertions, 15 deletions
diff --git a/cache/cache.go b/cache/cache.go
index c51acbc..328b1e9 100644
--- a/cache/cache.go
+++ b/cache/cache.go
@@ -101,6 +101,7 @@ func (c Cache) String() string {
return string(c.Marshal())
}
+// New creates a new Cache from a model.State
func New(st *model.State) Cache {
c := &Cache{}
for _, s := range st.Sources {
@@ -112,6 +113,7 @@ func New(st *model.State) Cache {
return *c
}
+// SaveFile helps you use Save with a file path instead of a reader
func SaveFile(path string, s *model.State, loaded Cache) error {
fd, err := os.Create(path)
if err != nil {
@@ -123,6 +125,7 @@ func SaveFile(path string, s *model.State, loaded Cache) error {
return Save(s, fd, loaded)
}
+// Save writes the cache combined with the "loaded" cache to the writer.
func Save(s *model.State, w io.Writer, loaded Cache) error {
result := New(s).Merge(loaded)
_, err := w.Write([]byte(result.Marshal()))
@@ -130,6 +133,7 @@ func Save(s *model.State, w io.Writer, loaded Cache) error {
}
+// LoadState creates a state with model.NewState based on cache content
func LoadState(f fs.FS, cache Cache, indexers []model.Indexer, runners []model.Runner) (*model.State, []error) {
var locs []string
for _, e := range cache.Entries {
@@ -138,6 +142,8 @@ func LoadState(f fs.FS, cache Cache, indexers []model.Indexer, runners []model.R
return model.NewState(f, locs, indexers, runners)
}
+// Strip removes the needle's entries from the receiver's entries when they have matching paths.
+// used to skip already indexed locations when auto-all-ing
func (c Cache) Strip(needle Cache) Cache {
var result []Entry
outer:
diff --git a/crawl/crawl.go b/crawl/crawl.go
index fccd81d..cc3d16c 100644
--- a/crawl/crawl.go
+++ b/crawl/crawl.go
@@ -7,10 +7,12 @@ import (
"strings"
)
+// Evaluated returns a path with evaluated symlinks
func Evaluated(loc string) (string, error) {
return filepath.EvalSymlinks(loc)
}
+// RichLocations combines the path and Evaluated path Locations
func RichLocations(origin string) []string {
locs := Locations(origin)
@@ -24,6 +26,8 @@ func RichLocations(origin string) []string {
return locs
}
+// Locations returns a slice of increasingly shorter file paths,
+// losing a segment each time.
func Locations(origin string) []string {
origin = path.Clean(origin)
var locs = []string{
@@ -40,6 +44,7 @@ func Locations(origin string) []string {
return locs
}
+// ParentDir returns a path with the top element missing
func ParentDir(origin string) string {
trimmedOrigin := strings.TrimSuffix(origin, "/")
dir, _ := path.Split(trimmedOrigin)
diff --git a/describe/describe.go b/describe/describe.go
index 0863b6d..a7070a1 100644
--- a/describe/describe.go
+++ b/describe/describe.go
@@ -15,6 +15,7 @@ var DescriptionPrefixes = []string{
var descriptions = make(map[model.Target]*string)
+// Describe attempts to read a description from a file and stores it in the cache
func Describe(key model.Target, file string) (string, error) {
if d := descriptions[key]; d != nil {
return *d, nil
@@ -35,6 +36,8 @@ func Describe(key model.Target, file string) (string, error) {
return text, err
}
+// FromReader reads a description from an io.Reader and returns it.
+// this is not stored in the cache.
func FromReader(reader io.Reader) (string, error) {
scanner := bufio.NewScanner(reader)
scanner.Split(bufio.ScanLines)
diff --git a/env/env.go b/env/env.go
index 2a76e33..f1bd9d8 100644
--- a/env/env.go
+++ b/env/env.go
@@ -12,6 +12,8 @@ import (
"slices"
)
+// IsEnv returns whether a given file is suitable for environment loading
+// this method respects the --env flag
func IsEnv(file string) bool {
options := []string{
".env",
@@ -26,6 +28,7 @@ func IsEnv(file string) bool {
return slices.Contains(options, file)
}
+// Files returns a list of files (that exist) that should be indexed and used as environment files
func Files(f fs.FS, p string, deep bool) []string {
var result []string
dir, err := fs.ReadDir(f, p)
@@ -43,6 +46,7 @@ func Files(f fs.FS, p string, deep bool) []string {
return result
}
+// Get returns all environment key-value pairs we should index for a source
func Get(src *model.Source) []string {
f := os.DirFS(src.Path)
var result []string
diff --git a/flags/flags.go b/flags/flags.go
index c500356..9fb8d44 100644
--- a/flags/flags.go
+++ b/flags/flags.go
@@ -3,15 +3,26 @@ package flags
import "github.com/spf13/pflag"
var (
- Here = pflag.BoolP("here", "h", false, "run target in current directory instead of source location")
- At = pflag.StringP("at", "@", "", "override run location")
- Single = pflag.BoolP("single", "s", false, "do not run any triggers")
- All = pflag.BoolP("all", "a", false, "get sources from cache instead of crawling")
- Dry = pflag.BoolP("dry", "d", false, "print cmdlines instead of running them")
- Root = pflag.BoolP("root", "r", false, "run targets (including triggers) with sudo")
- Yes = pflag.BoolP("yes", "y", false, "auto-confirm y/n confirmations")
- Env = pflag.StringArray("env", nil, "environment files or pre- or suffix")
+ // Here makes pik run the target at the current location instead of in its source directory
+ Here = pflag.BoolP("here", "h", false, "run target in current directory instead of source location")
+ // At makes pik run in an arbitrary location
+ At = pflag.StringP("at", "@", "", "override run location")
+ // Single will make pik skip triggers
+ Single = pflag.BoolP("single", "s", false, "do not run any triggers")
+ // All will make pik load cached state instead of crawling
+ All = pflag.BoolP("all", "a", false, "get sources from cache instead of crawling")
+ // Dry will prevent pik from running targets and output the command as text instead
+ Dry = pflag.BoolP("dry", "d", false, "print cmdlines instead of running them")
+ // Root will prefix the target with sudo to run it as root
+ Root = pflag.BoolP("root", "r", false, "run targets (including triggers) with sudo")
+ // Yes will skip y/n prompts and always answer yes
+ Yes = pflag.BoolP("yes", "y", false, "auto-confirm y/n confirmations")
+ // Env can be used to load additional .env files
+ Env = pflag.StringArray("env", nil, "environment files or pre- or suffix")
+ // Version means we should print the pik version and exit
Version = pflag.BoolP("version", "v", false, "print version and exit")
- List = pflag.BoolP("list", "l", false, "list available targets and exit")
- Inline = pflag.BoolP("inline", "i", false, "do not use terminal alt screen")
+ // List means we should output available targets separated by $IFS
+ List = pflag.BoolP("list", "l", false, "list available targets and exit")
+ // Inline means pik does not go to the terminal alt screen
+ Inline = pflag.BoolP("inline", "i", false, "do not use terminal alt screen")
)
diff --git a/git/git.go b/git/git.go
index 163922b..2b5130e 100644
--- a/git/git.go
+++ b/git/git.go
@@ -28,6 +28,7 @@ func (g *gitMod) Init() error {
var Git = &gitMod{}
+// Mod is the git hydration mod
func (g *gitMod) Mod(source *model.Source, result *model.HydratedSource) error {
gitFolder := filepath.Join(source.Path, ".git")
if st, err := os.Stat(gitFolder); err == nil && st.IsDir() {
@@ -56,6 +57,7 @@ func (g *gitMod) Mod(source *model.Source, result *model.HydratedSource) error {
return nil
}
+// Branch returns the git branch of a given source
func (g *gitMod) Branch(source *model.Source) (string, error) {
cmd := exec.Command(g.Git, "branch", "--show-current")
cmd.Dir = source.Path
@@ -65,6 +67,7 @@ func (g *gitMod) Branch(source *model.Source) (string, error) {
var UnknownResponseError = errors.New("unknown response")
+// Diff returns the number of changes of a given source
func (g *gitMod) Diff(source *model.Source) (changes int, insertions int, deletions int, err error) {
cmd := exec.Command(g.Git, "diff", "--shortstat")
cmd.Dir = source.Path
diff --git a/identity/identity.go b/identity/identity.go
index 06bd421..e1cd74d 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -7,15 +7,18 @@ type Identity struct {
Reduced string
}
+// I return whether the other identity "means the same" as this one
func (i Identity) I(other Identity) bool {
return i.Reduced == other.Reduced
}
+// Is returns whether the other string "means the same" as this one
func (i Identity) Is(input string) bool {
reduced := Reduce(input)
return i.Reduced == reduced
}
+// New creates a new Identity with default reduction
func New(input string) Identity {
reduced := Reduce(input)
return Identity{
@@ -25,6 +28,7 @@ func New(input string) Identity {
}
+// Reduce normalizes input (commands and filenames) to simplify them
func Reduce(input string) string {
reduced := input
reduced = strings.TrimPrefix(input, ".")
diff --git a/search/search.go b/search/search.go
index fd06ab5..7d863b9 100644
--- a/search/search.go
+++ b/search/search.go
@@ -5,16 +5,25 @@ import (
"slices"
)
+// Result is a struct containing information about the search and search results
type Result struct {
- Target model.Target
- Source *model.Source
+ // Target is the target selected by the search
+ Target model.Target
+ // Source is the source belonging to the selected Target
+ Source *model.Source
+ // NeedsConfirmation is true when there are discrepancies between expected and actual invocation
NeedsConfirmation bool
- Overridden bool
- Sub []string
- Args []string
+ // Overridden is whether it was overridden by a .override target
+ Overridden bool
+ // Sub is the subcategory or -folder
+ Sub []string
+ // Args are the remaining arguments which we should pass to the target
+ Args []string
}
// Search is the meat of pik
+// since there are a ton of different ways to invoke targets, leave a unit test
+// when you change this
func Search(s *model.State, args ...string) *Result {
var target model.Target
var targetSource *model.Source