about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-02-11T17·04+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-02-11T17·11+0000
commit3afb56a5e5274611c3c5d0f7e2f4a8965575ff40 (patch)
tree34f883eb1f1342ddb6c93d5f0ab6d4e59739d8b9
parenta50153c1419dd7dd1a7e3e79a016fa84e42accbb (diff)
Begin supporting run
I'd like to be able to just call `run file.py` and have a program DWIM. I'm
working on run as a step in this direction. Define a simple configuration that
maps file extensions to template strings where "$file" is replaced with the
argv[1].

It basically works but there are outstanding TODOs. See the README and source
code for more information.
-rw-r--r--run/.envrc2
-rw-r--r--run/README.md30
-rw-r--r--run/default.nix16
-rw-r--r--run/main.go49
-rw-r--r--run/shell.nix7
5 files changed, 104 insertions, 0 deletions
diff --git a/run/.envrc b/run/.envrc
new file mode 100644
index 000000000000..b80e28b4b815
--- /dev/null
+++ b/run/.envrc
@@ -0,0 +1,2 @@
+source_up
+eval "$(lorri direnv)"
diff --git a/run/README.md b/run/README.md
new file mode 100644
index 000000000000..d3cccecf910c
--- /dev/null
+++ b/run/README.md
@@ -0,0 +1,30 @@
+# run
+
+Simplify the commands you call to run scripts on the command line.
+
+```shell
+> run path/to/file.py
+> run path/to/file.ts
+```
+
+## How?
+
+Define a run.json configuration mapping commands to filename extensions like
+so:
+```json
+{
+  ".ts": "npx ts-node $file",
+  ".py": "python3 $file"
+}
+```
+
+Then call `run path/to/some/file.ts` on the command line, and `npx ts-node
+file.ts` will run.
+
+## Installation
+
+Install `run` using Nix.
+
+```shell
+> nix-env -iA briefcase.run
+```
diff --git a/run/default.nix b/run/default.nix
new file mode 100644
index 000000000000..113491536ee5
--- /dev/null
+++ b/run/default.nix
@@ -0,0 +1,16 @@
+{
+  pkgs ? import <nixpkgs> {},
+  depot ? import <depot> {},
+  briefcase ? import <briefcase> {},
+  ...
+}:
+
+depot.buildGo.program {
+  name = "run";
+  srcs = [
+    ./main.go
+  ];
+  deps = with briefcase.gopkgs; [
+    utils
+  ];
+}
diff --git a/run/main.go b/run/main.go
new file mode 100644
index 000000000000..04906ece91f7
--- /dev/null
+++ b/run/main.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"utils"
+)
+
+func main() {
+	if len(os.Args) != 2 {
+		log.Fatal("You can only call run with a single file at a time.")
+	}
+
+	rulesPath := utils.Resolve("run.json", []string{"/home/wpcarro/.config/run/run.json"})
+	b, err := ioutil.ReadFile(rulesPath)
+	if err != nil {
+		log.Fatal("Could not locate a run.json file: ", err)
+	}
+	rules := map[string]string{}
+	err = json.Unmarshal(b, &rules)
+	if err != nil {
+		log.Fatal("Could not decode run.json as JSON: ", err)
+	}
+
+	fileName := os.Args[1]
+	ext := filepath.Ext(fileName)
+	cmd, ok := rules[ext]
+
+	if !ok {
+		log.Fatalf("No rules for extension, %s, have been defined.", ext)
+	}
+
+	// TODO(wpcarro): Support more sophisticated parsing than just string
+	// splitting. To handle 'cases like this'.
+	tokens := strings.Split(strings.Replace(cmd, "$file", fileName, 1), " ")
+	c := exec.Command(tokens[0], tokens[1:]...)
+	err = c.Start()
+	// TODO(wpcarro): Forward STDERR and STDOUT.
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println(c.Wait())
+}
diff --git a/run/shell.nix b/run/shell.nix
new file mode 100644
index 000000000000..8b97f04ca446
--- /dev/null
+++ b/run/shell.nix
@@ -0,0 +1,7 @@
+{ pkgs ? import <nixpkgs> {}, ... }:
+
+pkgs.mkShell {
+  buildInputs = with pkgs; [
+    go
+  ];
+}