mirror of
https://github.com/go-task/task.git
synced 2025-11-23 22:24:45 +02:00
refactor: lazy load fuzzy model & ability to disable it
This commit is contained in:
@@ -36,9 +36,10 @@ end
|
||||
complete -c $GO_TASK_PROGNAME -d 'Runs the specified task(s). Falls back to the "default" task if no task name was specified, or lists all tasks if an unknown task name was
|
||||
specified.' -xa "(__task_get_tasks)"
|
||||
|
||||
complete -c $GO_TASK_PROGNAME -s c -l color -d 'colored output (default true)'
|
||||
complete -c $GO_TASK_PROGNAME -s d -l dir -d 'sets directory of execution'
|
||||
complete -c $GO_TASK_PROGNAME -l dry -d 'compiles and prints tasks in the order that they would be run, without executing them'
|
||||
complete -c $GO_TASK_PROGNAME -s c -l color -d 'colored output (default true)'
|
||||
complete -c $GO_TASK_PROGNAME -s d -l dir -d 'sets directory of execution'
|
||||
complete -c $GO_TASK_PROGNAME -l disable-fuzzy -d 'disables fuzzy matching for task names'
|
||||
complete -c $GO_TASK_PROGNAME -l dry -d 'compiles and prints tasks in the order that they would be run, without executing them'
|
||||
complete -c $GO_TASK_PROGNAME -s f -l force -d 'forces execution even when the task is up-to-date'
|
||||
complete -c $GO_TASK_PROGNAME -s h -l help -d 'shows Task usage'
|
||||
complete -c $GO_TASK_PROGNAME -s i -l init -d 'creates a new Taskfile.yml in the current folder'
|
||||
|
||||
@@ -8,6 +8,7 @@ Register-ArgumentCompleter -CommandName task -ScriptBlock {
|
||||
[CompletionResult]::new('--list-all ', '--list-all ', [CompletionResultType]::ParameterName, 'list all tasks'),
|
||||
[CompletionResult]::new('--color ', '--color', [CompletionResultType]::ParameterName, '--color'),
|
||||
[CompletionResult]::new('--concurrency=', '--concurrency=', [CompletionResultType]::ParameterName, 'concurrency'),
|
||||
[CompletionResult]::new('--disable-fuzzy ', '--disable-fuzzy', [CompletionResultType]::ParameterName, '--disable-fuzzy'),
|
||||
[CompletionResult]::new('--interval=', '--interval=', [CompletionResultType]::ParameterName, 'interval'),
|
||||
[CompletionResult]::new('--output=interleaved ', '--output=interleaved', [CompletionResultType]::ParameterName, '--output='),
|
||||
[CompletionResult]::new('--output=group ', '--output=group', [CompletionResultType]::ParameterName, '--output='),
|
||||
|
||||
@@ -42,6 +42,7 @@ _task() {
|
||||
'(-f --force)'{-f,--force}'[run even if task is up-to-date]' \
|
||||
'(-c --color)'{-c,--color}'[colored output]' \
|
||||
'(-d --dir)'{-d,--dir}'[dir to run in]:execution dir:_dirs' \
|
||||
'(--disable-fuzzy)--disable-fuzzy[disables fuzzy matching for task names]' \
|
||||
'(--dry)--dry[dry-run mode, compile and print tasks only]' \
|
||||
'(-o --output)'{-o,--output}'[set output style]:style:(interleaved group prefixed)' \
|
||||
'(--output-group-begin)--output-group-begin[message template before grouped output]:template text: ' \
|
||||
|
||||
14
executor.go
14
executor.go
@@ -39,6 +39,7 @@ type (
|
||||
Watch bool
|
||||
Verbose bool
|
||||
Silent bool
|
||||
DisableFuzzy bool
|
||||
AssumeYes bool
|
||||
AssumeTerm bool // Used for testing
|
||||
Dry bool
|
||||
@@ -296,6 +297,19 @@ func (o *silentOption) ApplyToExecutor(e *Executor) {
|
||||
e.Silent = o.silent
|
||||
}
|
||||
|
||||
// WithDisableFuzzy tells the [Executor] to disable fuzzy matching for task names.
|
||||
func WithDisableFuzzy(disableFuzzy bool) ExecutorOption {
|
||||
return &disableFuzzyOption{disableFuzzy}
|
||||
}
|
||||
|
||||
type disableFuzzyOption struct {
|
||||
disableFuzzy bool
|
||||
}
|
||||
|
||||
func (o *disableFuzzyOption) ApplyToExecutor(e *Executor) {
|
||||
e.DisableFuzzy = o.disableFuzzy
|
||||
}
|
||||
|
||||
// WithAssumeYes tells the [Executor] to assume "yes" for all prompts.
|
||||
func WithAssumeYes(assumeYes bool) ExecutorOption {
|
||||
return &assumeYesOption{assumeYes}
|
||||
|
||||
@@ -58,6 +58,7 @@ var (
|
||||
Watch bool
|
||||
Verbose bool
|
||||
Silent bool
|
||||
DisableFuzzy bool
|
||||
AssumeYes bool
|
||||
Dry bool
|
||||
Summary bool
|
||||
@@ -123,6 +124,7 @@ func init() {
|
||||
pflag.BoolVarP(&Watch, "watch", "w", false, "Enables watch of the given task.")
|
||||
pflag.BoolVarP(&Verbose, "verbose", "v", getConfig(config, func() *bool { return config.Verbose }, false), "Enables verbose mode.")
|
||||
pflag.BoolVarP(&Silent, "silent", "s", false, "Disables echoing.")
|
||||
pflag.BoolVar(&DisableFuzzy, "disable-fuzzy", getConfig(config, func() *bool { return config.DisableFuzzy }, false), "Disables fuzzy matching for task names.")
|
||||
pflag.BoolVarP(&AssumeYes, "yes", "y", false, "Assume \"yes\" as answer to all prompts.")
|
||||
pflag.BoolVarP(&Parallel, "parallel", "p", false, "Executes tasks provided on command line in parallel.")
|
||||
pflag.BoolVarP(&Dry, "dry", "n", false, "Compiles and prints tasks in the order that they would be run, without executing them.")
|
||||
@@ -243,6 +245,7 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) {
|
||||
task.WithWatch(Watch),
|
||||
task.WithVerbose(Verbose),
|
||||
task.WithSilent(Silent),
|
||||
task.WithDisableFuzzy(DisableFuzzy),
|
||||
task.WithAssumeYes(AssumeYes),
|
||||
task.WithDry(Dry || Status),
|
||||
task.WithSummary(Summary),
|
||||
|
||||
33
setup.go
33
setup.go
@@ -5,10 +5,12 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/sajari/fuzzy"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
@@ -34,7 +36,6 @@ func (e *Executor) Setup() error {
|
||||
if err := e.readTaskfile(node); err != nil {
|
||||
return err
|
||||
}
|
||||
e.setupFuzzyModel()
|
||||
e.setupStdFiles()
|
||||
if err := e.setupOutput(); err != nil {
|
||||
return err
|
||||
@@ -105,21 +106,21 @@ func (e *Executor) setupFuzzyModel() {
|
||||
if e.Taskfile == nil {
|
||||
return
|
||||
}
|
||||
//
|
||||
//model := fuzzy.NewModel()
|
||||
//model.SetThreshold(1) // because we want to build grammar based on every task name
|
||||
//
|
||||
//var words []string
|
||||
//for name, task := range e.Taskfile.Tasks.All(nil) {
|
||||
// if task.Internal {
|
||||
// continue
|
||||
// }
|
||||
// words = append(words, name)
|
||||
// words = slices.Concat(words, task.Aliases)
|
||||
//}
|
||||
//
|
||||
//model.Train(words)
|
||||
//e.fuzzyModel = model
|
||||
|
||||
model := fuzzy.NewModel()
|
||||
model.SetThreshold(1) // because we want to build grammar based on every task name
|
||||
|
||||
var words []string
|
||||
for name, task := range e.Taskfile.Tasks.All(nil) {
|
||||
if task.Internal {
|
||||
continue
|
||||
}
|
||||
words = append(words, name)
|
||||
words = slices.Concat(words, task.Aliases)
|
||||
}
|
||||
|
||||
model.Train(words)
|
||||
e.fuzzyModel = model
|
||||
}
|
||||
|
||||
func (e *Executor) setupTempDir() error {
|
||||
|
||||
10
task.go
10
task.go
@@ -452,8 +452,14 @@ func (e *Executor) GetTask(call *Call) (*ast.Task, error) {
|
||||
// If we found no tasks
|
||||
if len(aliasedTasks) == 0 {
|
||||
didYouMean := ""
|
||||
if e.fuzzyModel != nil {
|
||||
didYouMean = e.fuzzyModel.SpellCheck(call.Task)
|
||||
if !e.DisableFuzzy {
|
||||
// Lazy initialization of fuzzy model
|
||||
if e.fuzzyModel == nil {
|
||||
e.setupFuzzyModel()
|
||||
}
|
||||
if e.fuzzyModel != nil {
|
||||
didYouMean = e.fuzzyModel.SpellCheck(call.Task)
|
||||
}
|
||||
}
|
||||
return nil, &errors.TaskNotFoundError{
|
||||
TaskName: call.Task,
|
||||
|
||||
@@ -9,11 +9,12 @@ import (
|
||||
)
|
||||
|
||||
type TaskRC struct {
|
||||
Version *semver.Version `yaml:"version"`
|
||||
Verbose *bool `yaml:"verbose"`
|
||||
Concurrency *int `yaml:"concurrency"`
|
||||
Remote Remote `yaml:"remote"`
|
||||
Experiments map[string]int `yaml:"experiments"`
|
||||
Version *semver.Version `yaml:"version"`
|
||||
Verbose *bool `yaml:"verbose"`
|
||||
DisableFuzzy *bool `yaml:"disable-fuzzy"`
|
||||
Concurrency *int `yaml:"concurrency"`
|
||||
Remote Remote `yaml:"remote"`
|
||||
Experiments map[string]int `yaml:"experiments"`
|
||||
}
|
||||
|
||||
type Remote struct {
|
||||
@@ -44,5 +45,6 @@ func (t *TaskRC) Merge(other *TaskRC) {
|
||||
t.Remote.CacheExpiry = cmp.Or(other.Remote.CacheExpiry, t.Remote.CacheExpiry)
|
||||
|
||||
t.Verbose = cmp.Or(other.Verbose, t.Verbose)
|
||||
t.DisableFuzzy = cmp.Or(other.DisableFuzzy, t.DisableFuzzy)
|
||||
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
|
||||
}
|
||||
|
||||
@@ -108,6 +108,16 @@ Disable command echoing.
|
||||
task deploy --silent
|
||||
```
|
||||
|
||||
#### `--disable-fuzzy`
|
||||
|
||||
Disable fuzzy matching for task names. When enabled, Task will not suggest similar task names when you mistype a task name.
|
||||
|
||||
```bash
|
||||
task buidl --disable-fuzzy
|
||||
# Output: Task "buidl" does not exist
|
||||
# (without "Did you mean 'build'?" suggestion)
|
||||
```
|
||||
|
||||
### Execution Control
|
||||
|
||||
#### `-f, --force`
|
||||
|
||||
@@ -91,6 +91,17 @@ experiments:
|
||||
verbose: true
|
||||
```
|
||||
|
||||
### `disable-fuzzy`
|
||||
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
- **Description**: Disable fuzzy matching for task names. When enabled, Task will not suggest similar task names when you mistype a task name.
|
||||
- **CLI equivalent**: [`--disable-fuzzy`](./cli.md#--disable-fuzzy)
|
||||
|
||||
```yaml
|
||||
disable-fuzzy: true
|
||||
```
|
||||
|
||||
### `concurrency`
|
||||
|
||||
- **Type**: `integer`
|
||||
@@ -109,6 +120,7 @@ Here's a complete example of a `.taskrc.yml` file with all available options:
|
||||
```yaml
|
||||
# Global settings
|
||||
verbose: true
|
||||
disable-fuzzy: false
|
||||
concurrency: 2
|
||||
|
||||
# Enable experimental features
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Enable verbose output"
|
||||
},
|
||||
"disable-fuzzy": {
|
||||
"type": "boolean",
|
||||
"description": "Disable fuzzy matching for task names"
|
||||
},
|
||||
"concurrency": {
|
||||
"type": "integer",
|
||||
"description": "Number of concurrent tasks to run",
|
||||
|
||||
Reference in New Issue
Block a user