Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Runfile → Runfile.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# vim: set ft=yaml:

version: 0.0.1

tasks:
build:
cmd:
Expand All @@ -16,10 +12,14 @@ tasks:
- |+
run cook clean

test:
test:old:
cmd:
- go test -json ./pkg/runfile | gotestfmt

test:
cmd:
- go test -json ./parser/... | gotestfmt

test:only-failing:
cmd:
- go test -json ./pkg/runfile | gotestfmt --hide successful-tests
24 changes: 12 additions & 12 deletions cmd/run/completions.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"io"
"log/slog"

"github.com/nxtcoder17/runfile/pkg/runfile"
"github.com/nxtcoder17/runfile/parser"
)

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

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

m, err := runfile.ParseIncludes()
if err != nil {
slog.Error("parsing, got", "err", err)
panic(err)
}
// m, err := runfile.ParseIncludes()
// if err != nil {
// slog.Error("parsing, got", "err", err)
// panic(err)
// }

for k, v := range m {
for tn := range v.Runfile.Tasks {
fmt.Fprintf(writer, "%s:%s\n", k, tn)
}
}
// for k, v := range m {
// for tn := range v.Runfile.Tasks {
// fmt.Fprintf(writer, "%s:%s\n", k, tn)
// }
// }

return nil
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
92 changes: 58 additions & 34 deletions cmd/run/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,37 @@ import (
"path/filepath"
"strings"
"syscall"
"time"

"github.com/nxtcoder17/runfile/pkg/logging"
"github.com/nxtcoder17/runfile/pkg/runfile"
"github.com/nxtcoder17/runfile/errors"
"github.com/nxtcoder17/runfile/logging"
"github.com/nxtcoder17/runfile/runner"

// "github.com/nxtcoder17/runfile/pkg/runfile"

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

var Version string = "nightly"
var Version string = fmt.Sprintf("nightly | %s", time.Now().Format(time.RFC3339))

var runfileNames []string = []string{
"Runfile",
"Runfile.yml",
"Runfile.yaml",
}

//go:embed completions/fish/run.fish
//go:embed completions/run.fish
var shellCompletionFISH string

//go:embed completions/bash/run.bash
//go:embed completions/run.bash
var shellCompletionBASH string

//go:embed completions/zsh/run.zsh
//go:embed completions/run.zsh
var shellCompletionZSH string

//go:embed completions/ps/run.ps
//go:embed completions/run.ps
var shellCompletionPS string

func main() {
Expand Down Expand Up @@ -72,8 +79,10 @@ func main() {
Aliases: []string{"ls"},
},
},

// ShellCompletionCommandName: "completion:shell",
EnableShellCompletion: true,

// DefaultCommand: "help",
ShellComplete: func(ctx context.Context, c *cli.Command) {
if c.NArg() > 0 {
Expand All @@ -88,6 +97,33 @@ func main() {

generateShellCompletion(ctx, c.Root().Writer, runfilePath)
},

Commands: []*cli.Command{
{
Name: "shell:completion",
Suggest: true,
Action: func(ctx context.Context, c *cli.Command) error {
if c.NArg() != 2 {
return fmt.Errorf("needs argument one of [bash,zsh,fish,ps]")
}

switch c.Args().Slice()[1] {
case "fish":
fmt.Fprint(c.Writer, shellCompletionFISH)
case "bash":
fmt.Fprint(c.Writer, shellCompletionBASH)
case "zsh":
fmt.Fprint(c.Writer, shellCompletionZSH)
case "ps":
fmt.Fprint(c.Writer, shellCompletionPS)
}

return nil
},
},
},

Suggest: true,
Action: func(ctx context.Context, c *cli.Command) error {
parallel := c.Bool("parallel")
watch := c.Bool("watch")
Expand All @@ -114,7 +150,7 @@ func main() {
return err
}

rf, err2 := runfile.Parse(runfilePath)
rf, err2 := parser.Parse(runfilePath)
if err2 != nil {
slog.Error("parsing runfile, got", "err", err2)
panic(err2)
Expand Down Expand Up @@ -154,58 +190,46 @@ func main() {
}

logger := logging.New(logging.Options{
ShowCaller: true,
SlogKeyAsPrefix: "task",
ShowDebugLogs: debug,
SetAsDefaultLogger: true,
})

return rf.Run(runfile.NewContext(ctx, logger), runfile.RunArgs{
return runner.Run(runner.NewContext(ctx, logger), rf, runner.RunArgs{
Tasks: args,
ExecuteInParallel: parallel,
Watch: watch,
Debug: debug,
KVs: kv,
})
},
Commands: []*cli.Command{
{
Name: "shell:completion",
Action: func(ctx context.Context, c *cli.Command) error {
if c.NArg() != 2 {
return fmt.Errorf("needs argument one of [bash,zsh,fish,ps]")
}

switch c.Args().Slice()[1] {
case "fish":
fmt.Fprint(c.Writer, shellCompletionFISH)
case "bash":
fmt.Fprint(c.Writer, shellCompletionBASH)
case "zsh":
fmt.Fprint(c.Writer, shellCompletionZSH)
case "ps":
fmt.Fprint(c.Writer, shellCompletionPS)
}

return nil
},
},
// return rf.Run(runfile.NewContext(ctx, logger), runfile.RunArgs{
// Tasks: args,
// ExecuteInParallel: parallel,
// Watch: watch,
// Debug: debug,
// KVs: kv,
// })
},
}

ctx, cf := signal.NotifyContext(context.TODO(), os.Interrupt, syscall.SIGTERM)
ctx, cf := signal.NotifyContext(context.TODO(), syscall.SIGINT, syscall.SIGTERM)
defer cf()

go func() {
<-ctx.Done()
cf()
os.Exit(1)
}()

if err := cmd.Run(ctx, os.Args); err != nil {
errm, ok := err.(*runfile.Error)
errm, ok := err.(*errors.Error)
slog.Debug("got", "err", err)
if ok {
if errm != nil {
// errm.Error()
// TODO: change it to a better logging
// slog.Error("got", "err", errm)
errm.Log()
}
} else {
Expand Down
98 changes: 98 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package errors

import (
"fmt"
"log/slog"
"runtime"
)

type Error struct {
msg string
// kv is a slice of slog Attributes i.e. ("key", "value")
keys []string
// kv map[string]any
kv []any

traces []string

err error
}

// Error implements error.
func (e *Error) Error() string {
return fmt.Sprintf("%v {%#v}", e.err, e.kv)
}

func (e *Error) Log() {
args := make([]any, 0, len(e.kv))
args = append(args, e.kv...)
args = append(args, "traces", e.traces)
slog.Error(e.msg, args...)
}

var _ error = (*Error)(nil)

func Err(msg string) *Error {
return &Error{msg: msg}
}

func (e *Error) Wrap(err error) *Error {
_, file, line, _ := runtime.Caller(1)
e.traces = append(e.traces, fmt.Sprintf("%s:%d", file, line))
e.err = err
return e
}

func (e *Error) WrapStr(msg string) *Error {
e.err = fmt.Errorf(msg)
return e
}

func (e *Error) KV(kv ...any) *Error {
// if e.kv == nil {
// e.kv = make(map[string]any)
// }

// for i := 0; i < len(kv); i += 2 {
// // e.keys = append(e.keys, kv[i].(string))
// e.kv[kv[i].(string)] = kv[i+1]
// }
e.kv = append(e.kv, kv...)

return e
}

func WithErr(err error) *Error {
_, file, line, _ := runtime.Caller(1)
err2, ok := err.(*Error)
if !ok {
err2 = &Error{err: err}
}

err2.traces = append(err2.traces, fmt.Sprintf("%s:%d", file, line))
return err2
}

// ERROR constants
var (
ErrReadRunfile = Err("failed to read runfile")
ErrParseRunfile = Err("failed to read runfile")

ErrParseIncludes = Err("failed to parse includes")
ErrParseDotEnv = Err("failed to parse dotenv file")
ErrInvalidDotEnv = Err("invalid dotenv file")

ErrInvalidEnvVar = Err("invalid env var")
ErrRequiredEnvVar = Err("required env var")
ErrInvalidDefaultValue = Err("invalid default value for env var")

ErrEvalEnvVarSh = Err("failed while executing env-var sh script")

ErrTaskNotFound = Err("task not found")
ErrTaskFailed = Err("task failed")
ErrTaskParsingFailed = Err("task parsing failed")
ErrTaskRequirementNotMet = Err("task requirements not met")
ErrTaskInvalidWorkingDir = Err("task invalid working directory")

ErrTaskInvalidCommand = Err("task invalid command")
)
20 changes: 10 additions & 10 deletions examples/Runfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ tasks:
sh: echo -n "hello"
k4:
required: true
k5:
default:
# value: "this is default value"
# sh: echo this should be the default value
gotmpl: len "asdfadf"
# k5:
# default:
# # value: "this is default value"
# # sh: echo this should be the default value
# gotmpl: len "asdfadf"
# dotenv:
# - ../.secrets/env
cmd:
# - sleep 5
# - echo "hi hello"
# - echo "value of k1 is '$k1'"
# - echo "value of k2 is '$k2'"
# - echo "value of k3 is '$k3'"
- echo "hi hello"
- echo "value of k1 is '$k1'"
- echo "value of k2 is '$k2'"
- echo "value of k3 is '$k3'"
- echo "hello from cook"
- echo "value of key_id (from .dotenv) is '$key_id', ${#key_id}"
- echo "k4 is $k4"
- echo "k5 is $k5"
# - echo "k5 is $k5"

clean:
name: clean
Expand Down
13 changes: 13 additions & 0 deletions pkg/functions/helpers.go → functions/helpers.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package functions

import (
"fmt"
"os"
)

func DefaultIfNil[T any](v *T, dv T) T {
if v == nil {
return dv
Expand All @@ -20,3 +25,11 @@ func Must[T any](v T, err error) T {
func New[T any](v T) *T {
return &v
}

func ToEnviron(m map[string]string) []string {
results := os.Environ()
for k, v := range m {
results = append(results, fmt.Sprintf("%s=%v", k, v))
}
return results
}
File renamed without changes.
Loading