Skip to content

Commit

Permalink
feat: working version of Runfile
Browse files Browse the repository at this point in the history
  • Loading branch information
nxtcoder17 committed Sep 15, 2024
0 parents commit dc024fb
Show file tree
Hide file tree
Showing 15 changed files with 494 additions and 0 deletions.
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake .
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.direnv
bin/
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Runfile is a super simple task runner

All it does is run some pre-configured tasks for you, like running your applications, tests, building binaries, or some other scripts.

It is inspired by other task runners like Taskfile, Make etc.

But source code of those tools are like super big, and complex. So I decided to make a simpler one.

## Installation

```bash
go install github.com/nxtcoder17/runfile/cmd/run@latest
```

## Usage

### Runfile

Create a `Runfile` in the root of your project, and add tasks to it.

### Features

- [x] Run tasks
- [x] Run tasks with Key-Value environment variables
- [x] Run tasks with dynamic environment variables (by shell execution)

### Example

```yaml
version: 0.0.1

tasks:
build:
cmd:
- go build -o bin/run ./cmd/run
test:
cmd:
- go test ./...
12 changes: 12 additions & 0 deletions Runfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# vim: set ft=yaml:

version: 0.0.1

tasks:
build:
# dir: ./cmd/run
cmd:
- |+
echo "building ..."
go build -o bin/run ./cmd/run
echo "DONE"
25 changes: 25 additions & 0 deletions cmd/run/completions/fish/run.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# run fish shell completion
set PROGNAME run

function __fetch_runnable_tasks --description 'fetches all runnable tasks'
for i in (commandline -opc)
if contains -- $i help h
return 1
end
end

# Grab names and descriptions (if any) of the tasks
set -l output (run --generate-shell-completion | string split0)
echo "$output" > /tmp/test.txt
if test $output
echo $output
end

return 0
end

complete -c run -d "runs a task with given name" -xa "(__fish_run_no_subcommand)"
complete -c run -n '__fish_run_no_subcommand' -f -l help -s h -d 'show help'
complete -c run -n '__fish_run_no_subcommand' -f -l help -s h -d 'show help'
complete -r -c run -n '__fish_run_no_subcommand' -a 'help h' -d 'Shows a list of commands or help for one command'

110 changes: 110 additions & 0 deletions cmd/run/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"context"
"fmt"
"log"
"os"
"os/signal"
"path/filepath"
"syscall"

"github.com/nxtcoder17/runfile/pkg/runfile"
"github.com/urfave/cli/v3"
)

var Version string = "0.0.1"

func main() {
cmd := cli.Command{
Name: "run",
Version: Version,
Description: "A simple task runner",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Aliases: []string{"f"},
Value: "",
},
},
EnableShellCompletion: true,
ShellComplete: func(ctx context.Context, c *cli.Command) {
if c.NArg() > 0 {
return
}

runfilePath, err := locateRunfile(c)
if err != nil {
panic(err)
}

runfile, err := runfile.ParseRunFile(runfilePath)
if err != nil {
panic(err)
}

for k := range runfile.Tasks {
fmt.Fprintf(c.Root().Writer, "%s\n", k)
}
},
Action: func(ctx context.Context, c *cli.Command) error {
if c.Args().Len() > 1 {
return fmt.Errorf("too many arguments")
}
if c.Args().Len() != 1 {
return fmt.Errorf("missing argument")
}

runfilePath, err := locateRunfile(c)
if err != nil {
return err
}

runfile, err := runfile.ParseRunFile(runfilePath)
if err != nil {
panic(err)
}

s := c.Args().First()
return runfile.Run(ctx, s)
},
}

ctx, cf := context.WithCancel(context.TODO())

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
fmt.Println("\n\rcanceling...")
cf()
os.Exit(1)
}()

if err := cmd.Run(ctx, os.Args); err != nil {
log.Fatal(err)
}
}

func locateRunfile(c *cli.Command) (string, error) {
var runfilePath string
switch {
case c.IsSet("file"):
runfilePath = c.String("file")
default:
dir, err := os.Getwd()
if err != nil {
return "", err
}
for {
_, err := os.Stat(filepath.Join(dir, "Runfile"))
if err != nil {
dir = filepath.Dir(dir)
continue
}
runfilePath = filepath.Join(dir, "Runfile")
break
}
}
return runfilePath, nil
}
38 changes: 38 additions & 0 deletions examples/Runfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# vim: set ft=yaml:

version: 0.0.1

tasks:
cook:
env:
k1: v1
k2: 'f"\( asfsadfssdfas asfd $Asdfasdfa'
k3:
sh: echo "hello"
cmd:
- echo "cook"
- "echo k1: $k1, k2: $k2, k3: $k3"
clean:
name: clean
shell: ["python", "-c"]
cmd:
- |+
import secrets
print(secrets.token_hex(32))
laundry:
name: laundry
shell: ["node", "-e"]
cmd:
- console.log("laundry")
eat:
name: eat
cmd:
- echo "eat"
sleep:
name: sleep
cmd:
- echo "sleep"
code:
name: code
cmd:
- echo "code"
60 changes: 60 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
description = "RunFile dev workspace";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};

outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in
{
devShells.default = pkgs.mkShell {
# hardeningDisable = [ "all" ];

buildInputs = with pkgs; [
# cli tools
curl
jq
yq

pre-commit

# programming tools
go_1_22

upx
];

shellHook = ''
'';
};
}
);
}


10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/nxtcoder17/runfile

go 1.22.7

require (
github.com/urfave/cli/v3 v3.0.0-alpha9
sigs.k8s.io/yaml v1.4.0
)

require github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo=
github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "fmt"

func main() {
fmt.Println("RUN FILE")
}
20 changes: 20 additions & 0 deletions pkg/runfile/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package runfile

import (
"os"

"sigs.k8s.io/yaml"
)

func ParseRunFile(file string) (*RunFile, error) {
var runfile RunFile
f, err := os.ReadFile(file)
if err != nil {
return &runfile, err
}
err = yaml.Unmarshal(f, &runfile)
if err != nil {
return &runfile, err
}
return &runfile, nil
}
Loading

0 comments on commit dc024fb

Please sign in to comment.