diff options
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | main.go | 2 | ||||
| -rw-r--r-- | runner/just/just.go | 93 | ||||
| -rw-r--r-- | runner/just/target.go | 41 |
4 files changed, 139 insertions, 4 deletions
@@ -4,6 +4,7 @@ ## current features * run targets by their approximate name: `uwu build` will trigger `.uwu/build.sh`, or `.uwu/build.py`, or `make build` depending on what's possible. + * including external targets from `just` * specify source names to search for the target in that source explicitly: `uwu myproject build` can run `../../myproject/.uwu/build.sh` * unless overridden, targets will run in the directory where the `.uwu` folder resides. * use `--all` flag to start out-of-tree targets without having to navigate to the directory. @@ -19,6 +20,7 @@ * both the project root and `.pik` folder will be searched * values specified with `--env` will be tried as pre- and suffixes: `--env asdf` will load `.env-asdf` and `asdf.env` if they exist. * env files are reread for every trigger, meaning you can have a pre-trigger fetch credentials and save it in .env +* create any kind of target: high-level support for shell and python, and arbitrary shells with the shebang. ## planned features @@ -26,12 +28,9 @@ As this program has already gone through a number of iterations and forms, this time to catch up with all the features it used to have. This list is not exhaustive, but it is ordered by importance I attach to these features. -* python runner and indexer - * runner with support for uv and venvs - * indexer with support for `pyproject.toml` script targets * runner for executable files * this will also enable arbitrary shells like node by way of the shebang -* indexers for other target types such as `make`, `just`, and `npm` +* indexers for other target types such as `make` and `npm` * expand tui: * adding descriptions to targets based on the first comment in a target * support for categories and ordering of targets through the `.order` file @@ -10,6 +10,7 @@ import ( "pik/menu" "pik/model" "pik/run" + "pik/runner/just" "pik/runner/python" "pik/runner/shell" "pik/search" @@ -22,6 +23,7 @@ var initializers = []model.HasInit{ var indexers = []model.Indexer{ pikdex.Indexer, + just.Indexer, } var runners = []model.Runner{ diff --git a/runner/just/just.go b/runner/just/just.go new file mode 100644 index 0000000..e574536 --- /dev/null +++ b/runner/just/just.go @@ -0,0 +1,93 @@ +package just + +import ( + "io/fs" + "os/exec" + "pik/identity" + "pik/model" + "pik/runner" + "strings" +) + +type just struct { + path string +} + +var Indexer = &just{} + +func (j *just) Index(path string, f fs.FS, runners []model.Runner) ([]model.Target, error) { + + entries, err := fs.ReadDir(f, ".") + if err != nil { + return nil, err + } + hasJustfile := false + for _, e := range entries { + if !e.IsDir() && strings.ToLower(e.Name()) == "justfile" { + hasJustfile = true + break + } + } + + if !hasJustfile { + return nil, nil + } + + err = j.findJust() + if err != nil { + return nil, err + } + + cmd := exec.Command(j.path, "--list") + cmd.Dir = path + out, err := cmd.CombinedOutput() + if err != nil { + return nil, err + } + return ParseOutput(string(out)), nil +} + +func ParseOutput(input string) []model.Target { + categories := make(map[string][]string) + currentCategory := "" + for _, line := range strings.Split(input, "\n") { + // strip comment + line = strings.SplitN(line, "#", 2)[0] + line = strings.TrimSpace(line) + + if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { + currentCategory = line[1 : len(line)-1] + continue + } + + tgt := strings.SplitN(line, " ", 2)[0] + + if tgt == "" { + continue + } + + categories[currentCategory] = append(categories[currentCategory], tgt) + } + + var result []model.Target + for c, targets := range categories { + for _, t := range targets { + result = append(result, &JustTarget{ + BaseTarget: runner.BaseTarget{ + Identity: identity.New(t), + }, + Category: c, + }) + } + } + return result +} + +func (j *just) findJust() error { + loc, err := exec.LookPath("just") + if err != nil { + return err + } + j.path = loc + return nil +} diff --git a/runner/just/target.go b/runner/just/target.go new file mode 100644 index 0000000..c36e4af --- /dev/null +++ b/runner/just/target.go @@ -0,0 +1,41 @@ +package just + +import ( + "os/exec" + "pik/model" + "pik/runner" +) + +type JustTarget struct { + runner.BaseTarget + Category string +} + +func (j JustTarget) Create(s *model.Source) *exec.Cmd { + return exec.Command(Indexer.path, j.Identity.Full) +} + +func (j JustTarget) Sub() []string { + if j.Category != "" { + return []string{j.Category} + } + return nil +} + +func (j JustTarget) Label() string { + return j.Identity.Full +} + +func (j *JustTarget) Hydrate(src *model.Source) (model.HydratedTarget, error) { + return &HydratedJustTarget{ + BaseHydration: runner.Hydrated(j), + }, nil +} + +type HydratedJustTarget struct { + runner.BaseHydration[*JustTarget] +} + +func (h *HydratedJustTarget) Icon() string { + return "\uF039" +} |
