Skip to content
Closed
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
25 changes: 12 additions & 13 deletions cmd/task/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ func main() {
versionFlag bool
helpFlag bool
init bool
list bool
listAll bool
listOptions task.ListOptions
status bool
force bool
watch bool
Expand All @@ -78,8 +77,9 @@ func main() {
pflag.BoolVar(&versionFlag, "version", false, "show Task version")
pflag.BoolVarP(&helpFlag, "help", "h", false, "shows Task usage")
pflag.BoolVarP(&init, "init", "i", false, "creates a new Taskfile.yaml in the current folder")
pflag.BoolVarP(&list, "list", "l", false, "lists tasks with description of current Taskfile")
pflag.BoolVarP(&listAll, "list-all", "a", false, "lists tasks with or without a description")
pflag.BoolVarP(&listOptions.ListWithDescriptionsOnly, "list", "l", false, "lists tasks with description of current Taskfile")
pflag.BoolVarP(&listOptions.ListAll, "list-all", "a", false, "lists tasks with or without a description")
pflag.BoolVarP(&listOptions.AsJson, "json", "j", false, "lists tasks as JSON")
pflag.BoolVar(&status, "status", false, "exits with non-zero exit code if any of the given tasks is not up-to-date")
pflag.BoolVarP(&force, "force", "f", false, "forces execution even when the task is up-to-date")
pflag.BoolVarP(&watch, "watch", "w", false, "enables watch of the given task")
Expand Down Expand Up @@ -159,8 +159,12 @@ func main() {
OutputStyle: output,
}

if (list || listAll) && silent {
e.ListTaskNames(listAll)
if err := listOptions.Validate(); err != nil {
log.Fatal(err)
}

if (listOptions.ShowList()) && silent {
e.ListTaskNames(listOptions)
return
}

Expand All @@ -173,13 +177,8 @@ func main() {
return
}

if list {
e.ListTasksWithDesc()
return
}

if listAll {
e.ListAllTasks()
if listOptions.ShowList() {
e.ListTasks(listOptions)
return
}

Expand Down
69 changes: 52 additions & 17 deletions help.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package task

import (
"encoding/json"
"fmt"
"io"
"log"
Expand All @@ -13,26 +14,54 @@ import (
"github.com/go-task/task/v3/taskfile"
)

// ListTasksWithDesc reports tasks that have a description spec.
func (e *Executor) ListTasksWithDesc() {
e.printTasks(false)
type ListOptions struct {
ListWithDescriptionsOnly bool
ListAll bool
AsJson bool
}

// ListAllTasks reports all tasks, with or without a description spec.
func (e *Executor) ListAllTasks() {
e.printTasks(true)
func (o ListOptions) Validate() error {
if o.ListWithDescriptionsOnly && o.ListAll {
return fmt.Errorf("cannot use --list and --list-all at the same time")
}
if o.AsJson && !(o.ListWithDescriptionsOnly || o.ListAll) {
return fmt.Errorf("cannot use --json without --list or --list-all")
}
return nil
}

func (o ListOptions) ShowList() bool {
return o.ListWithDescriptionsOnly || o.ListAll
}

// ListTasks reports tasks.
func (e *Executor) ListTasks(o ListOptions) {
e.printTasks(o)
}

func (e *Executor) printTasks(listAll bool) {
func (e *Executor) printTasks(o ListOptions) {
var tasks []*taskfile.Task
if listAll {
if o.ListAll {
tasks = e.allTaskNames()
} else {
tasks = e.tasksWithDesc()
}

// use stdout if no output defined
var w io.Writer = os.Stdout
if e.Stdout != nil {
w = e.Stdout
}

if o.AsJson {
if err := json.NewEncoder(w).Encode(tasks); err != nil {
log.Fatal(err)
}
return
}

if len(tasks) == 0 {
if listAll {
if o.ListAll {
e.Logger.Outf(logger.Yellow, "task: No tasks available")
} else {
e.Logger.Outf(logger.Yellow, "task: No tasks with description available. Try --list-all to list all tasks")
Expand All @@ -42,11 +71,11 @@ func (e *Executor) printTasks(listAll bool) {
e.Logger.Outf(logger.Default, "task: Available tasks for this project:")

// Format in tab-separated columns with a tab stop of 8.
w := tabwriter.NewWriter(e.Stdout, 0, 8, 0, '\t', 0)
tw := tabwriter.NewWriter(w, 0, 8, 0, '\t', 0)
for _, task := range tasks {
fmt.Fprintf(w, "* %s: \t%s\n", task.Name(), task.Desc)
fmt.Fprintf(tw, "* %s: \t%s\n", task.Name(), task.Desc)
}
w.Flush()
tw.Flush()
}

func (e *Executor) allTaskNames() (tasks []*taskfile.Task) {
Expand Down Expand Up @@ -75,10 +104,10 @@ func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
return
}

// PrintTaskNames prints only the task names in a Taskfile.
// ListTaskNames prints only the task names in a Taskfile.
// Only tasks with a non-empty description are printed if allTasks is false.
// Otherwise, all task names are printed.
func (e *Executor) ListTaskNames(allTasks bool) {
func (e *Executor) ListTaskNames(o ListOptions) {
// if called from cmd/task.go, e.Taskfile has not yet been parsed
if e.Taskfile == nil {
if err := e.readTaskfile(); err != nil {
Expand All @@ -94,13 +123,19 @@ func (e *Executor) ListTaskNames(allTasks bool) {
// create a string slice from all map values (*taskfile.Task)
s := make([]string, 0, len(e.Taskfile.Tasks))
for _, t := range e.Taskfile.Tasks {
if (allTasks || t.Desc != "") && !t.Internal {
if (o.ListAll || t.Desc != "") && !t.Internal {
s = append(s, strings.TrimRight(t.Task, ":"))
}
}
// sort and print all task names
sort.Strings(s)
for _, t := range s {
fmt.Fprintln(w, t)
if o.AsJson {
if err := json.NewEncoder(w).Encode(s); err != nil {
log.Fatal(err)
}
} else {
for _, t := range s {
fmt.Fprintln(w, t)
}
}
}
4 changes: 2 additions & 2 deletions task.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error {
t, ok := e.Taskfile.Tasks[c.Task]
if !ok {
// FIXME: move to the main package
e.ListTasksWithDesc()
e.ListTasks(ListOptions{ListWithDescriptionsOnly: true})
return &taskNotFoundError{taskName: c.Task}
}
if t.Internal {
e.ListTasksWithDesc()
e.ListTasks(ListOptions{ListWithDescriptionsOnly: true})
return &taskInternalError{taskName: c.Task}
}
}
Expand Down
6 changes: 3 additions & 3 deletions task_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ func TestLabelInList(t *testing.T) {
Stderr: &buff,
}
assert.NoError(t, e.Setup())
e.ListTasksWithDesc()
e.ListTasks(task.ListOptions{ListWithDescriptionsOnly: true, ListAll: false})
assert.Contains(t, buff.String(), "foobar")
}

Expand All @@ -574,7 +574,7 @@ func TestListAllShowsNoDesc(t *testing.T) {
assert.NoError(t, e.Setup())

var title string
e.ListAllTasks()
e.ListTasks(task.ListOptions{ListWithDescriptionsOnly: false, ListAll: true})
for _, title = range []string{
"foo",
"voo",
Expand All @@ -596,7 +596,7 @@ func TestListCanListDescOnly(t *testing.T) {
}

assert.NoError(t, e.Setup())
e.ListTasksWithDesc()
e.ListTasks(task.ListOptions{ListWithDescriptionsOnly: true, ListAll: false})

var title string
assert.Contains(t, buff.String(), "foo")
Expand Down
4 changes: 2 additions & 2 deletions taskfile/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package taskfile

// Call is the parameters to a task call
type Call struct {
Task string
Vars *Vars
Task string `json:"task"`
Vars *Vars `json:"vars"`
}
16 changes: 8 additions & 8 deletions taskfile/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ package taskfile

// Cmd is a task command
type Cmd struct {
Cmd string
Silent bool
Task string
Vars *Vars
IgnoreError bool
Defer bool
Cmd string `json:"cmd"`
Silent bool `json:"silent"`
Task string `json:"task"`
Vars *Vars `json:"vars"`
IgnoreError bool `json:"ignore_error"`
Defer bool `json:"defer"`
}

// Dep is a task dependency
type Dep struct {
Task string
Vars *Vars
Task string `json:"task"`
Vars *Vars `json:"vars"`
}

// UnmarshalYAML implements yaml.Unmarshaler interface
Expand Down
18 changes: 9 additions & 9 deletions taskfile/included_taskfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ import (

// IncludedTaskfile represents information about included taskfiles
type IncludedTaskfile struct {
Taskfile string
Dir string
Optional bool
Internal bool
AdvancedImport bool
Vars *Vars
BaseDir string // The directory from which the including taskfile was loaded; used to resolve relative paths
Taskfile string `json:"taskfile"`
Dir string `json:"dir"`
Optional bool `json:"optional"`
Internal bool `json:"internal"`
AdvancedImport bool `json:"advanced_import"`
Vars *Vars `json:"vars"`
BaseDir string `json:"base_dir"` // The directory from which the including taskfile was loaded; used to resolve relative paths
}

// IncludedTaskfiles represents information about included tasksfiles
type IncludedTaskfiles struct {
Keys []string
Mapping map[string]IncludedTaskfile
Keys []string `json:"keys"`
Mapping map[string]IncludedTaskfile `json:"mapping"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
Expand Down
4 changes: 2 additions & 2 deletions taskfile/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
// Output of the Task output
type Output struct {
// Name of the Output.
Name string `yaml:"-"`
Name string `yaml:"-" json:"name"`
// Group specific style
Group OutputGroup
Group OutputGroup `json:"group"`
}

// IsSet returns true if and only if a custom output style is set.
Expand Down
4 changes: 2 additions & 2 deletions taskfile/precondition.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ var (

// Precondition represents a precondition necessary for a task to run
type Precondition struct {
Sh string
Msg string
Sh string `json:"sh"`
Msg string `json:"msg"`
}

// UnmarshalYAML implements yaml.Unmarshaler interface.
Expand Down
46 changes: 23 additions & 23 deletions taskfile/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ type Tasks map[string]*Task

// Task represents a task
type Task struct {
Task string
Cmds []*Cmd
Deps []*Dep
Label string
Desc string
Summary string
Sources []string
Generates []string
Status []string
Preconditions []*Precondition
Dir string
Vars *Vars
Env *Vars
Silent bool
Interactive bool
Internal bool
Method string
Prefix string
IgnoreError bool
Run string
IncludeVars *Vars
IncludedTaskfileVars *Vars
IncludedTaskfile *IncludedTaskfile
Task string `json:"task"`
Cmds []*Cmd `json:"cmds"`
Deps []*Dep `json:"deps"`
Label string `json:"label"`
Desc string `json:"desc"`
Summary string `json:"summary"`
Sources []string `json:"sources"`
Generates []string `json:"generates"`
Status []string `json:"status"`
Preconditions []*Precondition `json:"preconditions"`
Dir string `json:"dir"`
Vars *Vars `json:"vars"`
Env *Vars `json:"env"`
Silent bool `json:"silent"`
Interactive bool `json:"interactive"`
Internal bool `json:"internal"`
Method string `json:"method"`
Prefix string `json:"prefix"`
IgnoreError bool `json:"ignore_error"`
Run string `json:"run"`
IncludeVars *Vars `json:"include_vars"`
IncludedTaskfileVars *Vars `json:"included_taskfile_vars"`
IncludedTaskfile *IncludedTaskfile `json:"included_taskfile"`
}

func (t *Task) Name() string {
Expand Down
22 changes: 11 additions & 11 deletions taskfile/taskfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import (

// Taskfile represents a Taskfile.yml
type Taskfile struct {
Version string
Expansions int
Output Output
Method string
Includes *IncludedTaskfiles
Vars *Vars
Env *Vars
Tasks Tasks
Silent bool
Dotenv []string
Run string
Version string `json:"version"`
Expansions int `json:"expansions"`
Output Output `json:"output"`
Method string `json:"method"`
Includes *IncludedTaskfiles `json:"includes"`
Vars *Vars `json:"vars"`
Env *Vars `json:"env"`
Tasks Tasks `json:"tasks"`
Silent bool `json:"silent"`
Dotenv []string `json:"dotenv"`
Run string `json:"run"`
}

// UnmarshalYAML implements yaml.Unmarshaler interface
Expand Down
Loading