1
0
mirror of https://github.com/go-task/task.git synced 2024-12-12 10:45:49 +02:00

refactor: better sort package

This commit is contained in:
Pete Davison 2024-09-09 16:19:01 +00:00
parent 31b369ba4f
commit dd55d6e96b
No known key found for this signature in database
5 changed files with 77 additions and 78 deletions

View File

@ -100,12 +100,12 @@ func run() error {
dir = home
}
var taskSorter sort.TaskSorter
var taskSorter sort.Sorter
switch flags.TaskSort {
case "none":
taskSorter = &sort.Noop{}
taskSorter = nil
case "alphanumeric":
taskSorter = &sort.AlphaNumeric{}
taskSorter = sort.AlphaNumeric
}
e := task.Executor{

14
help.go
View File

@ -128,18 +128,20 @@ func (e *Executor) ListTaskNames(allTasks bool) error {
w = e.Stdout
}
// Get the list of tasks and sort them
tasks := e.Taskfile.Tasks.Values()
// Sort the tasks
if e.TaskSorter == nil {
e.TaskSorter = &sort.AlphaNumericWithRootTasksFirst{}
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
}
e.TaskSorter.Sort(tasks)
keys := e.Taskfile.Tasks.Keys()
e.TaskSorter(keys, nil)
// Create a list of task names
taskNames := make([]string, 0, e.Taskfile.Tasks.Len())
for _, task := range tasks {
for _, key := range keys {
task, ok := e.Taskfile.Tasks.Get(key)
if !ok {
continue
}
if (allTasks || task.Desc != "") && !task.Internal {
taskNames = append(taskNames, strings.TrimRight(task.Task, ":"))
for _, alias := range task.Aliases {

View File

@ -3,42 +3,38 @@ package sort
import (
"sort"
"strings"
"github.com/go-task/task/v3/taskfile/ast"
)
type TaskSorter interface {
Sort([]*ast.Task)
}
// A Sorter is any function that sorts a set of tasks.
type Sorter func(items []string, namespaces []string) []string
type Noop struct{}
func (s *Noop) Sort(tasks []*ast.Task) {}
type AlphaNumeric struct{}
// Tasks that are not namespaced should be listed before tasks that are.
// We detect this by searching for a ':' in the task name.
func (s *AlphaNumeric) Sort(tasks []*ast.Task) {
sort.Slice(tasks, func(i, j int) bool {
return tasks[i].Task < tasks[j].Task
// AlphaNumeric sorts the JSON output so that tasks are in alpha numeric order
// by task name.
func AlphaNumeric(items []string, namespaces []string) []string {
sort.Slice(items, func(i, j int) bool {
return items[i] < items[j]
})
return items
}
type AlphaNumericWithRootTasksFirst struct{}
// Tasks that are not namespaced should be listed before tasks that are.
// We detect this by searching for a ':' in the task name.
func (s *AlphaNumericWithRootTasksFirst) Sort(tasks []*ast.Task) {
sort.Slice(tasks, func(i, j int) bool {
iContainsColon := strings.Contains(tasks[i].Task, ":")
jContainsColon := strings.Contains(tasks[j].Task, ":")
// AlphaNumericWithRootTasksFirst sorts the JSON output so that tasks are in
// alpha numeric order by task name. It will also ensure that tasks that are not
// namespaced will be listed before tasks that are. We detect this by searching
// for a ':' in the task name.
func AlphaNumericWithRootTasksFirst(items []string, namespaces []string) []string {
if len(namespaces) > 0 {
return AlphaNumeric(items, namespaces)
}
sort.Slice(items, func(i, j int) bool {
iContainsColon := strings.Contains(items[i], ":")
jContainsColon := strings.Contains(items[j], ":")
if iContainsColon == jContainsColon {
return tasks[i].Task < tasks[j].Task
return items[i] < items[j]
}
if !iContainsColon && jContainsColon {
return true
}
return false
})
return items
}

View File

@ -4,74 +4,70 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/go-task/task/v3/taskfile/ast"
)
func TestAlphaNumericWithRootTasksFirst_Sort(t *testing.T) {
task1 := &ast.Task{Task: "task1"}
task2 := &ast.Task{Task: "task2"}
task3 := &ast.Task{Task: "ns1:task3"}
task4 := &ast.Task{Task: "ns2:task4"}
task5 := &ast.Task{Task: "task5"}
task6 := &ast.Task{Task: "ns3:task6"}
item1 := "a-item1"
item2 := "m-item2"
item3 := "ns1:item3"
item4 := "ns2:item4"
item5 := "z-item5"
item6 := "ns3:item6"
tests := []struct {
name string
tasks []*ast.Task
want []*ast.Task
items []string
want []string
}{
{
name: "no namespace tasks sorted alphabetically first",
tasks: []*ast.Task{task3, task2, task1},
want: []*ast.Task{task1, task2, task3},
name: "no namespace items sorted alphabetically first",
items: []string{item3, item2, item1},
want: []string{item1, item2, item3},
},
{
name: "namespace tasks sorted alphabetically after non-namespaced tasks",
tasks: []*ast.Task{task3, task4, task5},
want: []*ast.Task{task5, task3, task4},
name: "namespace items sorted alphabetically after non-namespaced items",
items: []string{item3, item4, item5},
want: []string{item5, item3, item4},
},
{
name: "all tasks sorted alphabetically with root tasks first",
tasks: []*ast.Task{task6, task5, task4, task3, task2, task1},
want: []*ast.Task{task1, task2, task5, task3, task4, task6},
name: "all items sorted alphabetically with root items first",
items: []string{item6, item5, item4, item3, item2, item1},
want: []string{item1, item2, item5, item3, item4, item6},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &AlphaNumericWithRootTasksFirst{}
s.Sort(tt.tasks)
assert.Equal(t, tt.want, tt.tasks)
AlphaNumericWithRootTasksFirst(tt.items, nil)
assert.Equal(t, tt.want, tt.items)
})
}
}
func TestAlphaNumeric_Sort(t *testing.T) {
task1 := &ast.Task{Task: "task1"}
task2 := &ast.Task{Task: "task2"}
task3 := &ast.Task{Task: "ns1:task3"}
task4 := &ast.Task{Task: "ns2:task4"}
task5 := &ast.Task{Task: "task5"}
task6 := &ast.Task{Task: "ns3:task6"}
item1 := "a-item1"
item2 := "m-item2"
item3 := "ns1:item3"
item4 := "ns2:item4"
item5 := "z-item5"
item6 := "ns3:item6"
tests := []struct {
name string
tasks []*ast.Task
want []*ast.Task
items []string
want []string
}{
{
name: "all tasks sorted alphabetically",
tasks: []*ast.Task{task3, task2, task5, task1, task4, task6},
want: []*ast.Task{task3, task4, task6, task1, task2, task5},
name: "all items sorted alphabetically",
items: []string{item3, item2, item5, item1, item4, item6},
want: []string{item1, item2, item3, item4, item6, item5},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &AlphaNumeric{}
s.Sort(tt.tasks)
assert.Equal(t, tt.tasks, tt.want)
AlphaNumeric(tt.items, nil)
assert.Equal(t, tt.want, tt.items)
})
}
}

21
task.go
View File

@ -74,7 +74,7 @@ type Executor struct {
Compiler *compiler.Compiler
Output output.Output
OutputStyle ast.Output
TaskSorter sort.TaskSorter
TaskSorter sort.Sorter
UserWorkingDir string
fuzzyModel *fuzzy.Model
@ -498,8 +498,19 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) {
// Create an error group to wait for each task to be compiled
var g errgroup.Group
// Sort the tasks
if e.TaskSorter == nil {
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
}
keys := e.Taskfile.Tasks.Keys()
e.TaskSorter(keys, nil)
// Filter tasks based on the given filter functions
for _, task := range e.Taskfile.Tasks.Values() {
for _, key := range keys {
task, ok := e.Taskfile.Tasks.Get(key)
if !ok {
continue
}
var shouldFilter bool
for _, filter := range filters {
if filter(task) {
@ -528,12 +539,6 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) {
return nil, err
}
// Sort the tasks
if e.TaskSorter == nil {
e.TaskSorter = &sort.AlphaNumericWithRootTasksFirst{}
}
e.TaskSorter.Sort(tasks)
return tasks, nil
}