-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 95997fd
Showing
11 changed files
with
378 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Z | ||
|
||
Simple task runner | ||
|
||
# Installation | ||
|
||
``` | ||
go get github.com/zakuro9715/z | ||
``` | ||
|
||
# Examples | ||
|
||
See [Examples](./examples) and [Examples Test](./examples_test.go) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
"strings" | ||
) | ||
|
||
var exit = os.Exit | ||
|
||
const version = "v0.1.0" | ||
const helpTextBase = ` | ||
z - Z Task runner | ||
Usage: | ||
z [OPTIONS] task... [ARGS] | ||
` | ||
|
||
func isHelpFlag(s string) bool { | ||
return s == "-h" || s == "--help" | ||
} | ||
|
||
func showTextAndExit(code int, text string) { | ||
if code == 0 { | ||
fmt.Println(text) | ||
} else { | ||
fmt.Fprintln(os.Stderr, text) | ||
} | ||
exit(code) | ||
} | ||
|
||
func fprintTasks(w io.Writer, tasks map[string]*Task) { | ||
fmt.Fprintln(w, "Tasks:") | ||
maxNameLen := 0 | ||
for k := range tasks { | ||
if len(k) > maxNameLen { | ||
maxNameLen = len(k) | ||
} | ||
} | ||
for k, t := range tasks { | ||
fmt.Fprintf(w, | ||
" %v%v - %v\n", | ||
k, | ||
strings.Repeat(" ", maxNameLen-len(k)), | ||
t.Description, | ||
) | ||
} | ||
} | ||
|
||
func fprintHelp(w io.Writer, config *Config) { | ||
var sb strings.Builder | ||
sb.WriteString(helpTextBase) | ||
if config != nil { | ||
sb.WriteString("\n") | ||
fprintTasks(&sb, config.Tasks) | ||
} | ||
fmt.Fprintln(w, sb.String()) | ||
} | ||
|
||
func fprintTaskHelp(w io.Writer, task *Task) { | ||
var sb strings.Builder | ||
sb.WriteString(task.Description) | ||
if len(task.Tasks) > 0 { | ||
fprintTasks(&sb, task.Tasks) | ||
} | ||
fmt.Fprint(w, sb.String()) | ||
} | ||
|
||
func fprintVersion(w io.Writer) { | ||
fmt.Fprintf(w, "z task runner %v\n", version) | ||
} | ||
|
||
func realMain(args []string) int { | ||
i := 0 | ||
configPath := "z.yaml" | ||
if p, ok := os.LookupEnv("ZCONFIG"); ok { | ||
configPath = p | ||
} | ||
|
||
config, err := LoadConfig(configPath) | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
return 1 | ||
} | ||
|
||
for ; i < len(args); i++ { | ||
arg := args[i] | ||
if arg[0] != '-' { | ||
break | ||
} | ||
switch { | ||
case isHelpFlag(arg): | ||
fprintHelp(os.Stdout, config) | ||
return 0 | ||
case arg == "-v" || arg == "--version": | ||
fprintVersion(os.Stdout) | ||
default: // unknow flag | ||
fprintHelp(os.Stderr, nil) | ||
return 1 | ||
} | ||
} | ||
|
||
if i >= len(args) { | ||
fprintHelp(os.Stderr, config) | ||
return 1 | ||
} | ||
|
||
task, ok := config.Tasks[args[i]] | ||
if !ok { | ||
fmt.Fprintf(os.Stderr, "Unknown task: %v\n", args[i]) | ||
exit(1) | ||
} | ||
i++ | ||
for ; i < len(args); i++ { | ||
if isHelpFlag(args[i]) { | ||
fprintTaskHelp(os.Stdout, task) | ||
return 0 | ||
} | ||
if args[i] == "--" { | ||
i += 1 | ||
break | ||
} | ||
if subtask, ok := task.Tasks[args[i]]; ok { | ||
task = subtask | ||
} else { | ||
break | ||
} | ||
} | ||
task.Run(args[i:]) | ||
return 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package main | ||
|
||
import ( | ||
"io/ioutil" | ||
|
||
"github.com/goccy/go-yaml" | ||
) | ||
|
||
type Config struct { | ||
Shell string `yaml:"shell"` | ||
Tasks Tasks `yaml:"tasks"` | ||
} | ||
|
||
func LoadConfig(filename string) (*Config, error) { | ||
data, err := ioutil.ReadFile(filename) | ||
if err != nil { | ||
return nil, err | ||
} | ||
config := new(Config) | ||
if err = yaml.Unmarshal(data, config); err != nil { | ||
return nil, err | ||
} | ||
for _, t := range config.Tasks { | ||
t.setConfig(config) | ||
} | ||
return config, nil | ||
} | ||
|
||
type Hooks struct { | ||
Pre string `yaml:"pre"` | ||
Post string `yaml:"post"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestExampleIsValid(t *testing.T) { | ||
assert.NoError(t, | ||
filepath.Walk("examples", func(path string, info os.FileInfo, err error) error { | ||
assert.NoError(t, err) | ||
if info.IsDir() { | ||
return nil | ||
} | ||
_, err = LoadConfig(path) | ||
return err | ||
}), | ||
) | ||
} | ||
|
||
func TestLoadHelloExample(t *testing.T) { | ||
expected := &Config{ | ||
Shell: "bash", | ||
Tasks: map[string]*Task{ | ||
"hello": { | ||
Cmds: []string{"echo hello"}, | ||
Hooks: Hooks{ | ||
Pre: "echo saying hello", | ||
Post: "echo said hello", | ||
}, | ||
Tasks: map[string]*Task{ | ||
"world": { | ||
Cmds: []string{"z hello -- world"}, | ||
Description: "Hello World", | ||
}, | ||
"cjk": { | ||
Cmds: []string{ | ||
"z hello japan", | ||
"z hello korea", | ||
"z hello china", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
for _, task := range expected.Tasks { | ||
task.setConfig(expected) | ||
} | ||
|
||
actual, err := LoadConfig("examples/hello.yaml") | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, expected, actual) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
tasks: | ||
compile: | ||
run: | ||
- clang $@ | ||
desc: Compile | ||
hooks: | ||
pre: echo Compiling | ||
post: echo Compiled | ||
tasks: | ||
main: | ||
run: | ||
- z -c examples/cc.yaml compile main.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
shell: bash | ||
tasks: | ||
hello: | ||
run: | ||
- echo hello | ||
hooks: | ||
pre: echo saying hello | ||
post: echo said hello | ||
tasks: | ||
world: | ||
desc: Hello World | ||
run: | ||
- z hello -- world | ||
cjk: | ||
run: | ||
- z hello japan | ||
- z hello korea | ||
- z hello china |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
) | ||
|
||
func ExampleHello() { | ||
os.Setenv("ZCONFIG", "examples/hello.yaml") | ||
realMain([]string{"hello"}) | ||
realMain([]string{"hello", "world"}) | ||
realMain([]string{"hello", "cjk"}) | ||
// Output: | ||
// hello | ||
// hello world | ||
// hello japan | ||
// hello korea | ||
// hello china | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module github.com/zakuro9715/z | ||
|
||
go 1.15 | ||
|
||
require ( | ||
github.com/goccy/go-yaml v1.8.3 | ||
github.com/stretchr/testify v1.6.1 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= | ||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= | ||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= | ||
github.com/goccy/go-yaml v1.8.3 h1:VGzw2KWSUyQX0yXai02S0nttBc+Oa4Kvh6RCFoxt8SE= | ||
github.com/goccy/go-yaml v1.8.3/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y= | ||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= | ||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= | ||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= | ||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= | ||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= | ||
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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | ||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= | ||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= | ||
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
) | ||
|
||
func main() { | ||
os.Exit(realMain(os.Args[1:])) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"os/exec" | ||
"strings" | ||
) | ||
|
||
type Tasks map[string]*Task | ||
type Task struct { | ||
Cmds []string `yaml:"run"` | ||
Config *Config | ||
Description string `yaml:"desc"` | ||
Hooks Hooks `yaml:"hooks"` | ||
Tasks Tasks `yaml:"tasks"` | ||
} | ||
|
||
func (t *Task) setConfig(c *Config) { | ||
t.Config = c | ||
for _, sub := range t.Tasks { | ||
sub.setConfig(c) | ||
} | ||
} | ||
|
||
func (t *Task) Run(args []string) error { | ||
shell := t.Config.GetShell() | ||
for _, command := range t.Cmds { | ||
cmd := exec.Command(shell, "-c", command+" "+strings.Join(args, " ")) | ||
cmd.Stdin = os.Stdin | ||
cmd.Stdout = os.Stdout | ||
cmd.Stderr = os.Stderr | ||
if err := cmd.Run(); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (c *Config) GetShell() string { | ||
if len(c.Shell) == 0 { | ||
return "sh" | ||
} | ||
return c.Shell | ||
} |