Skip to content

Commit 3832cc4

Browse files
authored
Merge pull request [#25](#25)
Feat: Integrate fwatcher, refactor parser, and enhance logging
2 parents 917c460 + 38bb2a1 commit 3832cc4

39 files changed

+1824
-2164
lines changed

Runfile renamed to Runfile.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# vim: set ft=yaml:
2-
3-
version: 0.0.1
4-
51
tasks:
62
build:
73
cmd:
@@ -16,10 +12,14 @@ tasks:
1612
- |+
1713
run cook clean
1814
19-
test:
15+
test:old:
2016
cmd:
2117
- go test -json ./pkg/runfile | gotestfmt
2218

19+
test:
20+
cmd:
21+
- go test -json ./parser/... | gotestfmt
22+
2323
test:only-failing:
2424
cmd:
2525
- go test -json ./pkg/runfile | gotestfmt --hide successful-tests

cmd/run/completions.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"io"
77
"log/slog"
88

9-
"github.com/nxtcoder17/runfile/pkg/runfile"
9+
"github.com/nxtcoder17/runfile/parser"
1010
)
1111

1212
func generateShellCompletion(_ context.Context, writer io.Writer, rfpath string) error {
@@ -20,7 +20,7 @@ func generateShellCompletion(_ context.Context, writer io.Writer, rfpath string)
2020
// panic(err)
2121
// }
2222

23-
runfile, err := runfile.Parse(rfpath)
23+
runfile, err := parser.Parse(rfpath)
2424
if err != nil {
2525
slog.Error("parsing, got", "err", err)
2626
panic(err)
@@ -30,17 +30,17 @@ func generateShellCompletion(_ context.Context, writer io.Writer, rfpath string)
3030
fmt.Fprintf(writer, "%s\n", k)
3131
}
3232

33-
m, err := runfile.ParseIncludes()
34-
if err != nil {
35-
slog.Error("parsing, got", "err", err)
36-
panic(err)
37-
}
33+
// m, err := runfile.ParseIncludes()
34+
// if err != nil {
35+
// slog.Error("parsing, got", "err", err)
36+
// panic(err)
37+
// }
3838

39-
for k, v := range m {
40-
for tn := range v.Runfile.Tasks {
41-
fmt.Fprintf(writer, "%s:%s\n", k, tn)
42-
}
43-
}
39+
// for k, v := range m {
40+
// for tn := range v.Runfile.Tasks {
41+
// fmt.Fprintf(writer, "%s:%s\n", k, tn)
42+
// }
43+
// }
4444

4545
return nil
4646
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

cmd/run/main.go

+58-34
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,37 @@ import (
1010
"path/filepath"
1111
"strings"
1212
"syscall"
13+
"time"
1314

14-
"github.com/nxtcoder17/runfile/pkg/logging"
15-
"github.com/nxtcoder17/runfile/pkg/runfile"
15+
"github.com/nxtcoder17/runfile/errors"
16+
"github.com/nxtcoder17/runfile/logging"
17+
"github.com/nxtcoder17/runfile/runner"
18+
19+
// "github.com/nxtcoder17/runfile/pkg/runfile"
20+
21+
// "github.com/nxtcoder17/runfile/pkg/runfile"
22+
"github.com/nxtcoder17/runfile/parser"
1623
"github.com/urfave/cli/v3"
1724
)
1825

19-
var Version string = "nightly"
26+
var Version string = fmt.Sprintf("nightly | %s", time.Now().Format(time.RFC3339))
2027

2128
var runfileNames []string = []string{
2229
"Runfile",
2330
"Runfile.yml",
2431
"Runfile.yaml",
2532
}
2633

27-
//go:embed completions/fish/run.fish
34+
//go:embed completions/run.fish
2835
var shellCompletionFISH string
2936

30-
//go:embed completions/bash/run.bash
37+
//go:embed completions/run.bash
3138
var shellCompletionBASH string
3239

33-
//go:embed completions/zsh/run.zsh
40+
//go:embed completions/run.zsh
3441
var shellCompletionZSH string
3542

36-
//go:embed completions/ps/run.ps
43+
//go:embed completions/run.ps
3744
var shellCompletionPS string
3845

3946
func main() {
@@ -72,8 +79,10 @@ func main() {
7279
Aliases: []string{"ls"},
7380
},
7481
},
82+
7583
// ShellCompletionCommandName: "completion:shell",
7684
EnableShellCompletion: true,
85+
7786
// DefaultCommand: "help",
7887
ShellComplete: func(ctx context.Context, c *cli.Command) {
7988
if c.NArg() > 0 {
@@ -88,6 +97,33 @@ func main() {
8897

8998
generateShellCompletion(ctx, c.Root().Writer, runfilePath)
9099
},
100+
101+
Commands: []*cli.Command{
102+
{
103+
Name: "shell:completion",
104+
Suggest: true,
105+
Action: func(ctx context.Context, c *cli.Command) error {
106+
if c.NArg() != 2 {
107+
return fmt.Errorf("needs argument one of [bash,zsh,fish,ps]")
108+
}
109+
110+
switch c.Args().Slice()[1] {
111+
case "fish":
112+
fmt.Fprint(c.Writer, shellCompletionFISH)
113+
case "bash":
114+
fmt.Fprint(c.Writer, shellCompletionBASH)
115+
case "zsh":
116+
fmt.Fprint(c.Writer, shellCompletionZSH)
117+
case "ps":
118+
fmt.Fprint(c.Writer, shellCompletionPS)
119+
}
120+
121+
return nil
122+
},
123+
},
124+
},
125+
126+
Suggest: true,
91127
Action: func(ctx context.Context, c *cli.Command) error {
92128
parallel := c.Bool("parallel")
93129
watch := c.Bool("watch")
@@ -114,7 +150,7 @@ func main() {
114150
return err
115151
}
116152

117-
rf, err2 := runfile.Parse(runfilePath)
153+
rf, err2 := parser.Parse(runfilePath)
118154
if err2 != nil {
119155
slog.Error("parsing runfile, got", "err", err2)
120156
panic(err2)
@@ -154,58 +190,46 @@ func main() {
154190
}
155191

156192
logger := logging.New(logging.Options{
193+
ShowCaller: true,
157194
SlogKeyAsPrefix: "task",
158195
ShowDebugLogs: debug,
159196
SetAsDefaultLogger: true,
160197
})
161198

162-
return rf.Run(runfile.NewContext(ctx, logger), runfile.RunArgs{
199+
return runner.Run(runner.NewContext(ctx, logger), rf, runner.RunArgs{
163200
Tasks: args,
164201
ExecuteInParallel: parallel,
165202
Watch: watch,
166203
Debug: debug,
167204
KVs: kv,
168205
})
169-
},
170-
Commands: []*cli.Command{
171-
{
172-
Name: "shell:completion",
173-
Action: func(ctx context.Context, c *cli.Command) error {
174-
if c.NArg() != 2 {
175-
return fmt.Errorf("needs argument one of [bash,zsh,fish,ps]")
176-
}
177206

178-
switch c.Args().Slice()[1] {
179-
case "fish":
180-
fmt.Fprint(c.Writer, shellCompletionFISH)
181-
case "bash":
182-
fmt.Fprint(c.Writer, shellCompletionBASH)
183-
case "zsh":
184-
fmt.Fprint(c.Writer, shellCompletionZSH)
185-
case "ps":
186-
fmt.Fprint(c.Writer, shellCompletionPS)
187-
}
188-
189-
return nil
190-
},
191-
},
207+
// return rf.Run(runfile.NewContext(ctx, logger), runfile.RunArgs{
208+
// Tasks: args,
209+
// ExecuteInParallel: parallel,
210+
// Watch: watch,
211+
// Debug: debug,
212+
// KVs: kv,
213+
// })
192214
},
193215
}
194216

195-
ctx, cf := signal.NotifyContext(context.TODO(), os.Interrupt, syscall.SIGTERM)
217+
ctx, cf := signal.NotifyContext(context.TODO(), syscall.SIGINT, syscall.SIGTERM)
196218
defer cf()
197219

198220
go func() {
199221
<-ctx.Done()
200222
cf()
201-
os.Exit(1)
202223
}()
203224

204225
if err := cmd.Run(ctx, os.Args); err != nil {
205-
errm, ok := err.(*runfile.Error)
226+
errm, ok := err.(*errors.Error)
206227
slog.Debug("got", "err", err)
207228
if ok {
208229
if errm != nil {
230+
// errm.Error()
231+
// TODO: change it to a better logging
232+
// slog.Error("got", "err", errm)
209233
errm.Log()
210234
}
211235
} else {

errors/errors.go

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package errors
2+
3+
import (
4+
"fmt"
5+
"log/slog"
6+
"runtime"
7+
)
8+
9+
type Error struct {
10+
msg string
11+
// kv is a slice of slog Attributes i.e. ("key", "value")
12+
keys []string
13+
// kv map[string]any
14+
kv []any
15+
16+
traces []string
17+
18+
err error
19+
}
20+
21+
// Error implements error.
22+
func (e *Error) Error() string {
23+
return fmt.Sprintf("%v {%#v}", e.err, e.kv)
24+
}
25+
26+
func (e *Error) Log() {
27+
args := make([]any, 0, len(e.kv))
28+
args = append(args, e.kv...)
29+
args = append(args, "traces", e.traces)
30+
slog.Error(e.msg, args...)
31+
}
32+
33+
var _ error = (*Error)(nil)
34+
35+
func Err(msg string) *Error {
36+
return &Error{msg: msg}
37+
}
38+
39+
func (e *Error) Wrap(err error) *Error {
40+
_, file, line, _ := runtime.Caller(1)
41+
e.traces = append(e.traces, fmt.Sprintf("%s:%d", file, line))
42+
e.err = err
43+
return e
44+
}
45+
46+
func (e *Error) WrapStr(msg string) *Error {
47+
e.err = fmt.Errorf(msg)
48+
return e
49+
}
50+
51+
func (e *Error) KV(kv ...any) *Error {
52+
// if e.kv == nil {
53+
// e.kv = make(map[string]any)
54+
// }
55+
56+
// for i := 0; i < len(kv); i += 2 {
57+
// // e.keys = append(e.keys, kv[i].(string))
58+
// e.kv[kv[i].(string)] = kv[i+1]
59+
// }
60+
e.kv = append(e.kv, kv...)
61+
62+
return e
63+
}
64+
65+
func WithErr(err error) *Error {
66+
_, file, line, _ := runtime.Caller(1)
67+
err2, ok := err.(*Error)
68+
if !ok {
69+
err2 = &Error{err: err}
70+
}
71+
72+
err2.traces = append(err2.traces, fmt.Sprintf("%s:%d", file, line))
73+
return err2
74+
}
75+
76+
// ERROR constants
77+
var (
78+
ErrReadRunfile = Err("failed to read runfile")
79+
ErrParseRunfile = Err("failed to read runfile")
80+
81+
ErrParseIncludes = Err("failed to parse includes")
82+
ErrParseDotEnv = Err("failed to parse dotenv file")
83+
ErrInvalidDotEnv = Err("invalid dotenv file")
84+
85+
ErrInvalidEnvVar = Err("invalid env var")
86+
ErrRequiredEnvVar = Err("required env var")
87+
ErrInvalidDefaultValue = Err("invalid default value for env var")
88+
89+
ErrEvalEnvVarSh = Err("failed while executing env-var sh script")
90+
91+
ErrTaskNotFound = Err("task not found")
92+
ErrTaskFailed = Err("task failed")
93+
ErrTaskParsingFailed = Err("task parsing failed")
94+
ErrTaskRequirementNotMet = Err("task requirements not met")
95+
ErrTaskInvalidWorkingDir = Err("task invalid working directory")
96+
97+
ErrTaskInvalidCommand = Err("task invalid command")
98+
)

examples/Runfile.yml

+10-10
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@ tasks:
2323
sh: echo -n "hello"
2424
k4:
2525
required: true
26-
k5:
27-
default:
28-
# value: "this is default value"
29-
# sh: echo this should be the default value
30-
gotmpl: len "asdfadf"
26+
# k5:
27+
# default:
28+
# # value: "this is default value"
29+
# # sh: echo this should be the default value
30+
# gotmpl: len "asdfadf"
3131
# dotenv:
3232
# - ../.secrets/env
3333
cmd:
3434
# - sleep 5
35-
# - echo "hi hello"
36-
# - echo "value of k1 is '$k1'"
37-
# - echo "value of k2 is '$k2'"
38-
# - echo "value of k3 is '$k3'"
35+
- echo "hi hello"
36+
- echo "value of k1 is '$k1'"
37+
- echo "value of k2 is '$k2'"
38+
- echo "value of k3 is '$k3'"
3939
- echo "hello from cook"
4040
- echo "value of key_id (from .dotenv) is '$key_id', ${#key_id}"
4141
- echo "k4 is $k4"
42-
- echo "k5 is $k5"
42+
# - echo "k5 is $k5"
4343

4444
clean:
4545
name: clean

pkg/functions/helpers.go renamed to functions/helpers.go

+13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package functions
22

3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
38
func DefaultIfNil[T any](v *T, dv T) T {
49
if v == nil {
510
return dv
@@ -20,3 +25,11 @@ func Must[T any](v T, err error) T {
2025
func New[T any](v T) *T {
2126
return &v
2227
}
28+
29+
func ToEnviron(m map[string]string) []string {
30+
results := os.Environ()
31+
for k, v := range m {
32+
results = append(results, fmt.Sprintf("%s=%v", k, v))
33+
}
34+
return results
35+
}
File renamed without changes.

0 commit comments

Comments
 (0)