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.
This commit is contained in:
William Carroll 2020-02-11 17:04:03 +00:00
parent a50153c141
commit 3afb56a5e5
5 changed files with 104 additions and 0 deletions

2
run/.envrc Normal file
View file

@ -0,0 +1,2 @@
source_up
eval "$(lorri direnv)"

30
run/README.md Normal file
View file

@ -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
```

16
run/default.nix Normal file
View file

@ -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
];
}

49
run/main.go Normal file
View file

@ -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())
}

7
run/shell.nix Normal file
View file

@ -0,0 +1,7 @@
{ pkgs ? import <nixpkgs> {}, ... }:
pkgs.mkShell {
buildInputs = with pkgs; [
go
];
}