Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add verbose flag #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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: 10 additions & 0 deletions clireporter/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import (
"github.com/samsarahq/taskrunner"
)

var verbose bool

type cli struct {
Executor *taskrunner.Executor
}

func init() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we instead pass verbose in as an argument to clireporter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had talked to @stephen to get to this solution, there's no straightforward way to pass it into clireporter, as the New function is indirectly called through the RunOption system, and passed in from main.go in backend/app/taskrunner

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could alternatively have the clireporter.Option take an argument that sets verbosity, so we'd have to handle the flag in the actual binary's main function. that seems annoying, so i opted for this path. this might matter more for binaries that run multiple taskrunner instance with varying verbosities, but I didn't feel like it was worth it atm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love the idea of having distributed binary flags / plugins that have binary interfaces. Having a verbosity flag as a global run option seems nice - and like something you'd use in other potential extensions.

@stephen what makes it annoying to do this in the main binary function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@berfarah main doesn't call clireporter directly, but rather passes in options that don't provide a way to use the interface directly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK you have access to the executor via the options function, which has a config object tied to it. What if we put verbose on config?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could also do something like:

func Option(verbose bool) taskrunner.RunOption {
	return func(r *taskrunner.RunOptions) {
		r.ReporterFns = append(r.ReporterFns, func(ctx context.Context, executor *taskrunner.Executor) error {
			New(executor).Run(ctx)
			return nil
		})
	}
}

haven't really thought through how to unify the config file vs. the code configuration

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ totally makes sense. I think in this case, verbosity seems like something everyone should be able to access. Though I'm open to it not being the case ofc.

taskrunner.Flags.BoolVar(&verbose, "v", false, "Show verbose output")
}

func Option(r *taskrunner.RunOptions) {
r.ReporterFns = append(r.ReporterFns, func(ctx context.Context, executor *taskrunner.Executor) error {
New(executor).Run(ctx)
Expand Down Expand Up @@ -48,6 +54,10 @@ func (c *cli) Run(ctx context.Context) {
fmt.Fprintln(event.TaskHandler().LogStdout(), event.Error)
case *taskrunner.TaskDiagnosticEvent:
fmt.Fprintf(event.TaskHandler().LogStdout(), "Warning: %s", event.Error.Error())
case *taskrunner.TaskRunShellEvent:
if verbose {
fmt.Fprintf(event.TaskHandler().LogStdout(), "$: %s", event.Message)
}
case *taskrunner.TaskStoppedEvent:
fmt.Fprintf(event.TaskHandler().LogStdout(), "Stopped")
}
Expand Down
24 changes: 17 additions & 7 deletions events.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import "time"
type ExecutorEventKind string

const (
ExecutorEventKind_TaskStarted ExecutorEventKind = "task.started"
ExecutorEventKind_TaskCompleted = "task.completed"
ExecutorEventKind_TaskFailed = "task.failed"
ExecutorEventKind_TaskStopped = "task.stopped"
ExecutorEventKind_TaskInvalidated = "task.invalidated"
ExecutorEventKind_TaskDiagnostic = "task.diagnostic"
ExecutorEventKind_ExecutorSetup = "executor.setup"
ExecutorEventKind_TaskStarted ExecutorEventKind = "task.started"
ExecutorEventKind_TaskCompleted = "task.completed"
ExecutorEventKind_TaskFailed = "task.failed"
ExecutorEventKind_TaskStopped = "task.stopped"
ExecutorEventKind_TaskInvalidated = "task.invalidated"
ExecutorEventKind_TaskDiagnostic = "task.diagnostic"
ExecutorEventKind_TaskRunShellEvent = "task.runshell"
ExecutorEventKind_ExecutorSetup = "executor.setup"
)

type ExecutorEvent interface {
Expand Down Expand Up @@ -92,3 +93,12 @@ type TaskDiagnosticEvent struct {
func (e *TaskDiagnosticEvent) Kind() ExecutorEventKind {
return ExecutorEventKind_TaskDiagnostic
}

type TaskRunShellEvent struct {
*simpleEvent
Message string
}

func (e *TaskRunShellEvent) Kind() ExecutorEventKind {
return ExecutorEventKind_TaskRunShellEvent
}
37 changes: 22 additions & 15 deletions executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,23 +209,30 @@ func (e *Executor) Run(ctx context.Context, taskNames ...string) error {
return e.wg.Wait()
}

func (e *Executor) shellRun(ctx context.Context, command string, opts ...shell.RunOption) error {
options := []shell.RunOption{
func(r *interp.Runner) {
loggerI := ctx.Value(loggerKey{})
if loggerI == nil {
return
}
func (e *Executor) shellRun(simpleEvent func() *simpleEvent) func(ctx context.Context, command string, opts ...shell.RunOption) error {
return func(ctx context.Context, command string, opts ...shell.RunOption) error {
e.publishEvent(&TaskRunShellEvent{
simpleEvent: simpleEvent(),
Message: command,
})

logger := loggerI.(*Logger)
options := []shell.RunOption{
func(r *interp.Runner) {
loggerI := ctx.Value(loggerKey{})
if loggerI == nil {
return
}

r.Stdout = logger.Stdout
r.Stderr = logger.Stderr
},
logger := loggerI.(*Logger)

r.Stdout = logger.Stdout
r.Stderr = logger.Stderr
},
}
options = append(options, e.shellRunOptions...)
options = append(options, opts...)
return shell.Run(ctx, command, options...)
}
options = append(options, e.shellRunOptions...)
options = append(options, opts...)
return shell.Run(ctx, command, options...)
}

// runPass kicks off tasks that are in an executable state.
Expand Down Expand Up @@ -263,7 +270,7 @@ func (e *Executor) runPass() {

started := time.Now()

err = task.Run(ctx, e.shellRun)
err = task.Run(ctx, e.shellRun(execution.simpleEvent))

if ctx.Err() == context.Canceled {
e.publishEvent(&TaskStoppedEvent{
Expand Down
18 changes: 9 additions & 9 deletions runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ import (
)

var (
flags = flag.NewFlagSet("taskrunner", 0)
Flags = flag.NewFlagSet("taskrunner", 0)
configFile string
nonInteractive bool
listTasks bool
)

func init() {
flags.Usage = func() {
Flags.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage: taskrunner [task...]\n")
flags.PrintDefaults()
Flags.PrintDefaults()
}
flags.StringVar(&configFile, "config", "", "Configuration file to use")
flags.BoolVar(&nonInteractive, "non-interactive", false, "Non-interactive mode")
flags.BoolVar(&listTasks, "list", false, "List all tasks")
Flags.StringVar(&configFile, "config", "", "Configuration file to use")
Flags.BoolVar(&nonInteractive, "non-interactive", false, "Non-interactive mode")
Flags.BoolVar(&listTasks, "list", false, "List all tasks")
}

type RunOptions struct {
Expand All @@ -47,7 +47,7 @@ func Run(tasks []*Task, options ...RunOption) {
option(runOptions)
}

if err := flags.Parse(os.Args[1:]); err != nil {
if err := Flags.Parse(os.Args[1:]); err != nil {
return
}

Expand Down Expand Up @@ -77,9 +77,9 @@ func Run(tasks []*Task, options ...RunOption) {

desiredTasks := config.DesiredTasks
config.Watch = !nonInteractive
if len(flags.Args()) > 0 {
if len(Flags.Args()) > 0 {
config.Watch = false
desiredTasks = flags.Args()
desiredTasks = Flags.Args()
}

if len(tasks) == 0 {
Expand Down