mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 19:50:15 +08:00
[v3] Support task flags pass through
[v3] `wails build` -> `wails task build`
This commit is contained in:
parent
8239964c28
commit
82287a4758
@ -10,11 +10,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := clir.NewCli("Wails", "The Wails CLI", "v3")
|
||||
app := clir.NewCli("wails", "The Wails CLI", "v3")
|
||||
app.NewSubCommandFunction("build", "Build the project", commands.Build)
|
||||
app.NewSubCommandFunction("init", "Initialise a new project", commands.Init)
|
||||
task := app.NewSubCommand("task", "Run and list tasks")
|
||||
task.NewSubCommandFunction("run", "Run a task", commands.RunTask)
|
||||
task.NewSubCommandFunction("list", "List tasks", commands.ListTasks)
|
||||
var taskFlags commands.RunTaskOptions
|
||||
task.AddFlags(&taskFlags)
|
||||
task.Action(func() error {
|
||||
return commands.RunTask(&taskFlags, task.OtherArgs())
|
||||
})
|
||||
task.LongDescription("\nUsage: wails task [taskname] [flags]\n\nTasks are defined in the `Taskfile.yaml` file. See https://taskfile.dev for more information.")
|
||||
generate := app.NewSubCommand("generate", "Generation tools")
|
||||
generate.NewSubCommandFunction("defaults", "Generate default build assets", commands.Defaults)
|
||||
generate.NewSubCommandFunction("icons", "Generate icons", commands.GenerateIcons)
|
||||
|
@ -5,7 +5,7 @@ go 1.19
|
||||
require (
|
||||
github.com/go-task/task/v3 v3.20.0
|
||||
github.com/jackmordaunt/icns/v2 v2.2.1
|
||||
github.com/leaanthony/clir v1.5.0
|
||||
github.com/leaanthony/clir v1.6.0
|
||||
github.com/leaanthony/gosod v1.0.3
|
||||
github.com/leaanthony/winicon v1.0.0
|
||||
github.com/pterm/pterm v0.12.51
|
||||
|
@ -47,8 +47,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/clir v1.5.0 h1:zaH7fgsZ5OLfr0YwJBwQ+EYxCjXQsHF+CRudIiZb0KQ=
|
||||
github.com/leaanthony/clir v1.5.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/clir v1.6.0 h1:mLV9thGkmqFqJU7ozmqlER8sBtGdZlz6H3gKsfIiB3o=
|
||||
github.com/leaanthony/clir v1.6.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
|
||||
github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
|
||||
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
|
||||
|
12
v3/internal/commands/build.go
Normal file
12
v3/internal/commands/build.go
Normal file
@ -0,0 +1,12 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/wailsapp/wails/v3/internal/flags"
|
||||
)
|
||||
|
||||
func Build(_ *flags.Build) error {
|
||||
os.Args = []string{"wails", "task", "build"}
|
||||
return RunTask(&RunTaskOptions{}, []string{})
|
||||
}
|
@ -3,67 +3,173 @@ package commands
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pterm/pterm"
|
||||
|
||||
"github.com/go-task/task/v3/args"
|
||||
|
||||
"github.com/go-task/task/v3"
|
||||
"github.com/go-task/task/v3/taskfile"
|
||||
)
|
||||
|
||||
type RunTaskOptions struct {
|
||||
Name string `name:"n" description:"The name of the task to run"`
|
||||
Name string `pos:"1"`
|
||||
Help bool `name:"h" description:"shows Task usage"`
|
||||
Init bool `name:"i" description:"creates a new Taskfile.yml"`
|
||||
List bool `name:"list" description:"tasks with description of current Taskfile"`
|
||||
ListAll bool `name:"list-all" description:"lists tasks with or without a description"`
|
||||
ListJSON bool `name:"json" description:"formats task list as json"`
|
||||
Status bool `name:"status" description:"exits with non-zero exit code if any of the given tasks is not up-to-date"`
|
||||
Force bool `name:"f" description:"forces execution even when the task is up-to-date"`
|
||||
Watch bool `name:"w" description:"enables watch of the given task"`
|
||||
Verbose bool `name:"v" description:"enables verbose mode"`
|
||||
Silent bool `name:"s" description:"disables echoing"`
|
||||
Parallel bool `name:"p" description:"executes tasks provided on command line in parallel"`
|
||||
Dry bool `name:"dry" description:"compiles and prints tasks in the order that they would be run, without executing them"`
|
||||
Summary bool `name:"summary" description:"show summary about a task"`
|
||||
ExitCode bool `name:"x" description:"pass-through the exit code of the task command"`
|
||||
Dir string `name:"dir" description:"sets directory of execution"`
|
||||
EntryPoint string `name:"taskfile" description:"choose which Taskfile to run."`
|
||||
OutputName string `name:"output" description:"sets output style: [interleaved|group|prefixed]"`
|
||||
OutputGroupBegin string `name:"output-group-begin" description:"message template to print before a task's grouped output"`
|
||||
OutputGroupEnd string `name:"output-group-end" description:"message template to print after a task's grouped output"`
|
||||
Color bool `name:"c" description:"colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable" default:"true"`
|
||||
Concurrency int `name:"C" description:"limit number tasks to run concurrently"`
|
||||
Interval int64 `name:"interval" description:"interval to watch for changes"`
|
||||
}
|
||||
|
||||
func RunTask(options *RunTaskOptions) error {
|
||||
if options.Name == "" {
|
||||
return fmt.Errorf("name of task required")
|
||||
}
|
||||
func RunTask(options *RunTaskOptions, otherArgs []string) error {
|
||||
|
||||
e := task.Executor{}
|
||||
err := e.Setup()
|
||||
if options.Init {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
build := taskfile.Call{
|
||||
Task: options.Name,
|
||||
Vars: nil,
|
||||
}
|
||||
return e.Run(context.Background(), build)
|
||||
return task.InitTaskfile(os.Stdout, wd)
|
||||
}
|
||||
|
||||
type ListTaskOptions struct {
|
||||
if options.Dir != "" && options.EntryPoint != "" {
|
||||
return fmt.Errorf("task: You can't set both --dir and --taskfile")
|
||||
}
|
||||
|
||||
func ListTasks(options *ListTaskOptions) error {
|
||||
e := task.Executor{}
|
||||
if err := e.Setup(); err != nil {
|
||||
return err
|
||||
if options.EntryPoint != "" {
|
||||
options.Dir = filepath.Dir(options.EntryPoint)
|
||||
options.EntryPoint = filepath.Base(options.EntryPoint)
|
||||
}
|
||||
tasks, err := e.GetTaskList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(tasks) == 0 {
|
||||
return fmt.Errorf("no tasks found. Ensure there is a `Taskfile.tmpl.yml` in your project. You can generate a default takfile by running `wails generate defaults`")
|
||||
}
|
||||
tableData := [][]string{
|
||||
{"Task", "Summary"},
|
||||
}
|
||||
println()
|
||||
|
||||
for _, thisTask := range tasks {
|
||||
if thisTask.Internal {
|
||||
continue
|
||||
if options.OutputName != "group" {
|
||||
if options.OutputGroupBegin != "" {
|
||||
return fmt.Errorf("task: You can't set --output-group-begin without --output=group")
|
||||
}
|
||||
var thisRow = make([]string, 2)
|
||||
thisRow[0] = thisTask.Task
|
||||
thisRow[1] = thisTask.Summary
|
||||
tableData = append(tableData, thisRow)
|
||||
if options.OutputGroupBegin != "" {
|
||||
return fmt.Errorf("task: You can't set --output-group-end without --output=group")
|
||||
}
|
||||
err = pterm.DefaultTable.WithHasHeader(true).WithHeaderRowSeparator("-").WithData(tableData).Render()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
println()
|
||||
|
||||
e := task.Executor{
|
||||
Force: options.Force,
|
||||
Watch: options.Watch,
|
||||
Verbose: options.Verbose,
|
||||
Silent: options.Silent,
|
||||
Dir: options.Dir,
|
||||
Dry: options.Dry,
|
||||
Entrypoint: options.EntryPoint,
|
||||
Summary: options.Summary,
|
||||
Parallel: options.Parallel,
|
||||
Color: options.Color,
|
||||
Concurrency: options.Concurrency,
|
||||
Interval: time.Duration(options.Interval) * time.Second,
|
||||
|
||||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
|
||||
OutputStyle: taskfile.Output{
|
||||
Name: options.OutputName,
|
||||
Group: taskfile.OutputGroup{
|
||||
Begin: options.OutputGroupBegin,
|
||||
End: options.OutputGroupEnd,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var listOptions = task.NewListOptions(options.List, options.ListAll, options.ListJSON)
|
||||
if err := listOptions.Validate(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if (listOptions.ShouldListTasks()) && options.Silent {
|
||||
e.ListTaskNames(options.ListAll)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := e.Setup(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
v, err := e.Taskfile.ParsedVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if listOptions.ShouldListTasks() {
|
||||
if foundTasks, err := e.ListTasks(listOptions); !foundTasks || err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
calls []taskfile.Call
|
||||
globals *taskfile.Vars
|
||||
)
|
||||
|
||||
var taskAndVars []string
|
||||
for _, taskAndVar := range os.Args[2:] {
|
||||
if taskAndVar == "--" {
|
||||
break
|
||||
}
|
||||
taskAndVars = append(taskAndVars, taskAndVar)
|
||||
}
|
||||
|
||||
if len(taskAndVars) > 0 && len(otherArgs) > 0 {
|
||||
if taskAndVars[0] == otherArgs[0] {
|
||||
otherArgs = otherArgs[1:]
|
||||
}
|
||||
}
|
||||
|
||||
if v >= 3.0 {
|
||||
calls, globals = args.ParseV3(taskAndVars...)
|
||||
} else {
|
||||
calls, globals = args.ParseV2(taskAndVars...)
|
||||
}
|
||||
|
||||
globals.Set("CLI_ARGS", taskfile.Var{Static: strings.Join(otherArgs, " ")})
|
||||
e.Taskfile.Vars.Merge(globals)
|
||||
|
||||
if !options.Watch {
|
||||
e.InterceptInterruptSignals()
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if options.Status {
|
||||
return e.Status(ctx, calls...)
|
||||
}
|
||||
|
||||
if err := e.Run(ctx, calls...); err != nil {
|
||||
pterm.Error.Println(err.Error())
|
||||
|
||||
if options.ExitCode {
|
||||
if err, ok := err.(*task.TaskRunError); ok {
|
||||
os.Exit(err.ExitCode())
|
||||
}
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import "testing"
|
||||
func TestBuild(t *testing.T) {
|
||||
type args struct {
|
||||
options *RunTaskOptions
|
||||
otherArgs []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -30,7 +31,7 @@ func TestBuild(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := RunTask(tt.args.options); (err != nil) != tt.wantErr {
|
||||
if err := RunTask(tt.args.options, tt.args.otherArgs); (err != nil) != tt.wantErr {
|
||||
t.Errorf("Run() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
|
5
v3/internal/flags/build.go
Normal file
5
v3/internal/flags/build.go
Normal file
@ -0,0 +1,5 @@
|
||||
package flags
|
||||
|
||||
type Build struct {
|
||||
Common
|
||||
}
|
Loading…
Reference in New Issue
Block a user