diff --git a/.gitignore b/.gitignore index 9a1b1a6..cbad690 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ bin/ .secrets/ Taskfile.yml go.work* +tags diff --git a/cmd/run/main.go b/cmd/run/main.go index cc1f876..2b58015 100644 --- a/cmd/run/main.go +++ b/cmd/run/main.go @@ -202,13 +202,15 @@ func main() { return err } - rf, err2 := parser.ParseRunfile(types.NewContext(ctx, logger), runfilePath) + runfileCtx := types.NewContext(ctx, logger) + + rf, err2 := parser.ParseRunfile(runfileCtx, runfilePath) if err2 != nil { slog.Error("parsing runfile, got", "err", err2) panic(err2) } - if err := runner.Run(types.NewContext(ctx, logger), rf, runner.RunArgs{ + if err := runner.Run(runfileCtx, rf, runner.RunArgs{ Tasks: args, ExecuteInParallel: parallel, Watch: watch, diff --git a/flake.lock b/flake.lock index 7e1ccce..f4a3138 100644 --- a/flake.lock +++ b/flake.lock @@ -19,11 +19,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1739446958, - "narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", + "lastModified": 1744463964, + "narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2ff53fe64443980e139eaa286017f53f88336dd0", + "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650", "type": "github" }, "original": { diff --git a/go.mod b/go.mod index a883e87..9532e80 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,15 @@ module github.com/nxtcoder17/runfile -go 1.24 +go 1.24.1 + +toolchain go1.24.2 require ( github.com/alecthomas/chroma/v2 v2.15.0 github.com/charmbracelet/lipgloss v1.0.0 github.com/joho/godotenv v1.5.1 github.com/muesli/termenv v0.15.2 + github.com/nxtcoder17/fastlog v0.0.0-20250416154215-c6aac24aebcb github.com/nxtcoder17/fwatcher v1.2.2-0.20250318121757-bfc2065fa9f5 github.com/nxtcoder17/go.pkgs v0.0.0-20250216034729-39e2d2cd48da github.com/urfave/cli/v3 v3.0.0-beta1 diff --git a/go.sum b/go.sum index 99ea35f..d1fde7d 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= -github.com/nxtcoder17/fwatcher v1.2.0 h1:Nn5NQZrd6tnY0aFIUmpHCysLDbIsUYn4oyHaxEaVj60= -github.com/nxtcoder17/fwatcher v1.2.0/go.mod h1:SMwIdCpyi5fBygrkCX8hIIUeILzgoxJFaDSlhFBOWWQ= +github.com/nxtcoder17/fastlog v0.0.0-20250416154215-c6aac24aebcb h1:BHKArf9In3jINU2B3mTLQb75F5PMoJ5fnOlRD7dOq/w= +github.com/nxtcoder17/fastlog v0.0.0-20250416154215-c6aac24aebcb/go.mod h1:EWaIRNdsxHdqCv53XcNw9H9QMwhEV3LTWfsSQZCiiC4= github.com/nxtcoder17/fwatcher v1.2.2-0.20250318121757-bfc2065fa9f5 h1:6BulIAQBv2FZqUFZcKtFEhc1vMOeOdeMS+S5d874FMY= github.com/nxtcoder17/fwatcher v1.2.2-0.20250318121757-bfc2065fa9f5/go.mod h1:SMwIdCpyi5fBygrkCX8hIIUeILzgoxJFaDSlhFBOWWQ= github.com/nxtcoder17/go.pkgs v0.0.0-20250216034729-39e2d2cd48da h1:Y6GILHFlrihVfDqDPQ98y2kdUeI0SQc8tnoXh2NbEIA= diff --git a/parser/parse-command.go b/parser/parse-command.go index 3a75e56..2740d09 100644 --- a/parser/parse-command.go +++ b/parser/parse-command.go @@ -44,7 +44,11 @@ func parseCommand(ctx types.Context, prf *types.ParsedRunfile, taskEnv map[strin switch { case cj.Run != nil: { + if ctx.TaskNamespace != "" { + *cj.Run = ctx.TaskNamespace + ":" + *cj.Run + } pcj.Run = cj.Run + if _, ok := prf.Tasks[*cj.Run]; !ok { err := errors.ErrTaskNotFound.Wrap(fmt.Errorf("run target, not found")).KV("command", command, "run-target", cj.Run) return nil, err diff --git a/parser/parse-task.go b/parser/parse-task.go index a3406e4..2c9cc1a 100644 --- a/parser/parse-task.go +++ b/parser/parse-task.go @@ -118,6 +118,7 @@ func ParseTask(ctx types.Context, prf *types.ParsedRunfile, task types.Task) (*t } return &types.ParsedTask{ + Namespace: task.Metadata.Namespace, Name: task.Name, Shell: task.Shell, WorkingDir: *task.Dir, diff --git a/parser/parser-runfile.go b/parser/parser-runfile.go index ff51045..ba3e89f 100644 --- a/parser/parser-runfile.go +++ b/parser/parser-runfile.go @@ -1,12 +1,10 @@ package parser import ( - "context" "fmt" "os" "path/filepath" - "github.com/nxtcoder17/go.pkgs/log" "github.com/nxtcoder17/runfile/errors" fn "github.com/nxtcoder17/runfile/functions" "github.com/nxtcoder17/runfile/types" @@ -18,25 +16,28 @@ func parseRunfile(ctx types.Context, runfile *types.Runfile) (*types.ParsedRunfi Env: make(map[string]string), Tasks: make(map[string]types.Task), } + prf.Metadata.RunfilePath = runfile.Filepath for k, task := range runfile.Tasks { task.Name = k + task.Metadata.RunfilePath = &prf.Metadata.RunfilePath prf.Tasks[k] = task } - m, err := parseIncludes(ctx, runfile.Includes) + includes, err := parseIncludes(ctx, runfile.Includes) if err != nil { return nil, err } - for k, iprf := range m { - for taskName, task := range iprf.Tasks { - task.Name = k - task.Metadata.RunfilePath = &iprf.Metadata.RunfilePath + for k, included := range includes { + for taskName, task := range included.Tasks { + task.Name = taskName + task.Metadata.RunfilePath = &included.Metadata.RunfilePath + task.Metadata.Namespace = k prf.Tasks[fmt.Sprintf("%s:%s", k, taskName)] = task } - for k, v := range iprf.Env { + for k, v := range included.Env { prf.Env[k] = v } } @@ -58,7 +59,7 @@ func parseRunfile(ctx types.Context, runfile *types.Runfile) (*types.ParsedRunfi return nil, err } - envVars, err := parseEnvVars(types.Context{Context: context.TODO(), Logger: log.New()}, runfile.Env, evaluationParams{Env: dotenvVars}) + envVars, err := parseEnvVars(ctx, runfile.Env, evaluationParams{Env: dotenvVars}) if err != nil { return nil, err } @@ -86,9 +87,6 @@ func parseRunfileFromFile(ctx types.Context, file string) (*types.ParsedRunfile, if err != nil { return nil, err } - - // prf.Metadata.RunfilePath = file - prf.Metadata.RunfilePath = fn.Must(filepath.Abs(file)) return prf, nil } diff --git a/runner/run-task.go b/runner/run-task.go index f02326e..a74c77b 100644 --- a/runner/run-task.go +++ b/runner/run-task.go @@ -56,7 +56,7 @@ func isTTY() bool { func hasANSISupport() bool { term := os.Getenv("TERM") - return strings.Contains(term, "xterm") || strings.Contains(term, "screen") || strings.Contains(term, "vt100") + return strings.Contains(term, "xterm") || strings.Contains(term, "screen") || strings.Contains(term, "vt100") || strings.Contains(term, "tmux") } func printCommand(writer io.Writer, prefix, lang, cmd string) { @@ -187,25 +187,19 @@ func createCommandGroups(ctx types.Context, args CreateCommandGroupArgs) ([]exec } func runTask(ctx types.Context, prf *types.ParsedRunfile, args runTaskArgs) error { - runfilePath := prf.Metadata.RunfilePath task := prf.Tasks[args.taskName] - - if task.Metadata.RunfilePath != nil { - runfilePath = *task.Metadata.RunfilePath - } - args.taskTrail = append(args.taskTrail, args.taskName) - logger := ctx.With("task", args.taskName, "runfile", fn.Must(filepath.Rel(fn.Must(os.Getwd()), runfilePath))) - logger.Debug("running task") + logger := ctx.With("task", args.taskName, "runfile", fn.Must(filepath.Rel(fn.Must(os.Getwd()), *task.Metadata.RunfilePath)), "namespace", task.Metadata.Namespace) + logger.Debug("running") + + ctx.TaskNamespace = task.Metadata.Namespace task, ok := prf.Tasks[args.taskName] if !ok { return errors.ErrTaskNotFound } - task.Name = args.taskName - pt, err := parser.ParseTask(ctx, prf, task) if err != nil { return errors.WithErr(err) diff --git a/runner/run-task_test.go b/runner/run-task_test.go index 9c798bc..a50f22b 100644 --- a/runner/run-task_test.go +++ b/runner/run-task_test.go @@ -1,34 +1,34 @@ package runner -import ( - "context" - "log/slog" - "testing" +// import ( +// "context" +// "testing" +// +// "github.com/nxtcoder17/fwatcher/pkg/executor" +// "github.com/nxtcoder17/go.pkgs/log" +// "github.com/nxtcoder17/runfile/types" +// ) - "github.com/nxtcoder17/fwatcher/pkg/executor" - "github.com/nxtcoder17/runfile/types" -) - -func TestCreateCommands(t *testing.T) { - tests := []struct { - prf types.ParsedRunfile - pt types.ParsedTask - rta runTaskArgs - - want []executor.CommandGroup - }{ - { - prf: types.ParsedRunfile{}, - pt: types.ParsedTask{}, - }, - } - - for _, tt := range tests { - cg, err := createCommandGroups(Context{Context: context.TODO(), Logger: slog.Default()}, &tt.prf, &tt.pt, tt.rta) - if err != nil { - t.Error(err) - } - - _ = cg - } -} +// func TestCreateCommands(t *testing.T) { +// tests := []struct { +// prf types.ParsedRunfile +// pt types.ParsedTask +// rta runTaskArgs +// +// want []executor.CommandGroup +// }{ +// { +// prf: types.ParsedRunfile{}, +// pt: types.ParsedTask{}, +// }, +// } +// +// for _, tt := range tests { +// cg, err := createCommandGroups(types.Context{Context: context.TODO(), Logger: log.New()}, &tt.prf, &tt.pt, tt.rta) +// if err != nil { +// t.Error(err) +// } +// +// _ = cg +// } +// } diff --git a/types/context.go b/types/context.go index 559a14a..2e8adaa 100644 --- a/types/context.go +++ b/types/context.go @@ -9,7 +9,8 @@ import ( type Context struct { context.Context log.Logger - TaskName string + TaskName string + TaskNamespace string } func NewContext(ctx context.Context, logger log.Logger) Context { diff --git a/types/parsed-types.go b/types/parsed-types.go index 9686aa4..1a9d988 100644 --- a/types/parsed-types.go +++ b/types/parsed-types.go @@ -1,15 +1,19 @@ package types type ParsedRunfile struct { - Env map[string]string `json:"env,omitempty"` - Tasks map[string]Task `json:"tasks"` + Env map[string]string + Includes map[string]Task + Tasks map[string]Task Metadata struct { RunfilePath string - } `json:"-"` + } } type ParsedTask struct { + // Namespace for a task is auto set, when it is imported under a name + Namespace string `json:"-"` + // Name should be resolved from key itself Name string `json:"-"` diff --git a/types/types.go b/types/types.go index ddbce90..d7a56b3 100644 --- a/types/types.go +++ b/types/types.go @@ -1,7 +1,7 @@ package types type Runfile struct { - Filepath string + Filepath string `json:"-"` Version string `json:"version,omitempty"` Includes map[string]IncludeSpec `json:"includes"` Env EnvVar `json:"env,omitempty"` @@ -51,6 +51,7 @@ type TaskWatch struct { type Task struct { Metadata struct { RunfilePath *string + Namespace string } Name string `json:"-"`