diff options
Diffstat (limited to 'runner/js')
| -rw-r--r-- | runner/js/indexer.go | 39 | ||||
| -rw-r--r-- | runner/js/js.go | 106 | ||||
| -rw-r--r-- | runner/js/runner.go | 28 | ||||
| -rw-r--r-- | runner/js/target_npm.go | 42 | ||||
| -rw-r--r-- | runner/js/target_script.go | 55 |
5 files changed, 270 insertions, 0 deletions
diff --git a/runner/js/indexer.go b/runner/js/indexer.go new file mode 100644 index 0000000..8a2a6b2 --- /dev/null +++ b/runner/js/indexer.go @@ -0,0 +1,39 @@ +package js + +import ( + "encoding/json" + "errors" + "github.com/ewy1/pik/model" + "io/fs" + "os" + "path/filepath" +) + +type Package struct { + Scripts map[string]string `json:"scripts"` +} + +func (n *js) Index(path string, f fs.FS, runners []model.Runner) ([]model.Target, error) { + p := &Package{} + // are there any other package.jsons? i hope not, because i don't know them + content, err := os.ReadFile(filepath.Join(path, "package.json")) + if errors.Is(err, fs.ErrNotExist) { + return nil, nil + } else if err != nil { + return nil, err + } + err = json.Unmarshal(content, p) + if err != nil { + return nil, err + } + + var targets []model.Target + if n.Npm == "" { + return nil, NoNpm + } + for k, s := range p.Scripts { + targets = append(targets, n.CreateRun(k, s)) + } + + return targets, nil +} diff --git a/runner/js/js.go b/runner/js/js.go new file mode 100644 index 0000000..7c2af58 --- /dev/null +++ b/runner/js/js.go @@ -0,0 +1,106 @@ +package js + +import ( + "errors" + "github.com/ewy1/pik/identity" + "github.com/ewy1/pik/model" + "github.com/ewy1/pik/runner" + "os/exec" + "path/filepath" + "slices" +) + +var jsExtensions = []string{ + ".js", + ".cjs", +} + +var tsExtensions = []string{ + ".ts", +} + +var extensions = append(jsExtensions, tsExtensions...) + +var managers = []string{ + "pnpm", + "yarn", + "npm", +} + +var jsInterpreters = []string{ + "node", + "bun", +} + +var tsInterpeters = []string{ + "ts", + "ts-node", + "bun", +} + +type js struct { + JsInterpreter string + TsInterpreter string + Npm string +} + +var Js = &js{} + +var UnsupportedFile = errors.New("unsupported file") +var NoJsInterpreter = errors.New("no js interpreter found in $PATH") +var NoTsInterpreter = errors.New("no ts interpreter found in $PATH") +var NoNpm = errors.New("npm not found in $PATH") + +func (n *js) Interpreter(file string) (string, error) { + ext := filepath.Ext(file) + if slices.Contains(jsInterpreters, ext) { + if n.JsInterpreter == "" { + return "", NoJsInterpreter + } + return n.JsInterpreter, nil + } + if slices.Contains(tsInterpeters, ext) { + if n.TsInterpreter == "" { + return "", NoTsInterpreter + } + return n.TsInterpreter, nil + } + return "", UnsupportedFile +} + +func (n *js) Init() error { + for _, p := range jsInterpreters { + if r, err := exec.LookPath(p); err != nil { + n.JsInterpreter = r + } + } + for _, p := range tsInterpeters { + if r, err := exec.LookPath(p); err != nil { + n.TsInterpreter = r + } + } + + for _, m := range managers { + if r, err := exec.LookPath(m); err == nil { + n.Npm = r + } + } + + return nil +} + +var npmSub = []string{ + "npm", +} + +func (n *js) CreateRun(name, cmd string) model.Target { + return &Npm{ + BaseTarget: runner.BaseTarget{ + Identity: identity.New(cmd), + MyTags: model.TagsFromFilename(cmd), + MySub: npmSub, + }, + Name: name, + Cmd: cmd, + } +} diff --git a/runner/js/runner.go b/runner/js/runner.go new file mode 100644 index 0000000..8b5f4f1 --- /dev/null +++ b/runner/js/runner.go @@ -0,0 +1,28 @@ +package js + +import ( + "github.com/ewy1/pik/identity" + "github.com/ewy1/pik/model" + "github.com/ewy1/pik/runner" + "io/fs" + "path/filepath" + "slices" +) + +func (n *js) Wants(fs fs.FS, file string, entry fs.DirEntry) (bool, error) { + ext := filepath.Ext(entry.Name()) + return slices.Contains(extensions, ext), nil +} + +func (n *js) CreateTarget(fs fs.FS, source string, file string, entry fs.DirEntry) (model.Target, error) { + ext := filepath.Ext(entry.Name()) + typed := slices.Contains(tsExtensions, ext) + return &Script{ + BaseTarget: runner.BaseTarget{ + Identity: identity.New(entry.Name()), + MyTags: model.TagsFromFilename(entry.Name()), + MySub: runner.SubFromFile(file), + }, + Typed: typed, + }, nil +} diff --git a/runner/js/target_npm.go b/runner/js/target_npm.go new file mode 100644 index 0000000..8319fad --- /dev/null +++ b/runner/js/target_npm.go @@ -0,0 +1,42 @@ +package js + +import ( + "github.com/ewy1/pik/model" + "github.com/ewy1/pik/runner" + "os/exec" + "path/filepath" +) + +type Npm struct { + runner.BaseTarget + Name string + Cmd string +} + +func (n *Npm) Icon() string { + return "\uE60B" +} + +func (n *Npm) Description(src *model.HydratedSource) string { + return n.Cmd +} + +func (n *Npm) Target() model.Target { + return n +} + +func (n *Npm) Create(s *model.Source) *exec.Cmd { + return exec.Command(Js.Npm, "run", n.Name) +} + +func (n *Npm) Label() string { + return n.Name +} + +func (n *Npm) Hydrate(src *model.Source) (model.HydratedTarget, error) { + return n, nil +} + +func (n *Npm) File(src *model.Source) string { + return filepath.Join(src.Path, "package.json") +} diff --git a/runner/js/target_script.go b/runner/js/target_script.go new file mode 100644 index 0000000..6ad213d --- /dev/null +++ b/runner/js/target_script.go @@ -0,0 +1,55 @@ +package js + +import ( + "github.com/ewy1/pik/describe" + "github.com/ewy1/pik/model" + "github.com/ewy1/pik/runner" + "github.com/ewy1/pik/spool" + "os/exec" + "path/filepath" +) + +type Script struct { + runner.BaseTarget + Typed bool +} + +func (t *Script) Icon() string { + if t.Typed { + return "\uE628" + } else { + return "\uE60C" + } +} + +func (t *Script) Description(src *model.HydratedSource) string { + d, err := describe.Describe(t, t.File(src.Source)) + if err != nil { + _, _ = spool.Warn("%v\n", err) + } + return d +} + +func (t *Script) Target() model.Target { + return t +} + +func (t *Script) Create(s *model.Source) *exec.Cmd { + if t.Typed { + return exec.Command(Js.TsInterpreter, t.File(s)) + } else { + return exec.Command(Js.JsInterpreter, t.File(s)) + } +} + +func (t *Script) Label() string { + return t.Identity.Full +} + +func (t *Script) Hydrate(src *model.Source) (model.HydratedTarget, error) { + return t, nil +} + +func (t *Script) File(src *model.Source) string { + return filepath.Join(src.Path, "package.json") +} |
