summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md7
-rw-r--r--main.go2
-rw-r--r--runner/just/just.go93
-rw-r--r--runner/just/target.go41
4 files changed, 139 insertions, 4 deletions
diff --git a/README.md b/README.md
index e06fe5c..3f2ead3 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/main.go b/main.go
index fbc6ca4..4b0dcee 100644
--- a/main.go
+++ b/main.go
@@ -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"
+}