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 support for delegating CLI arguments with "--" and a special CLI_ARGS variable #327

Closed
huy-nguyen opened this issue May 14, 2020 · 27 comments
Labels
area: variables Changes related to variables.

Comments

@huy-nguyen
Copy link

huy-nguyen commented May 14, 2020

Does go-task currently offer the option of "passthrough" arguments? For example, if I have currently have a task to run the AWS CLI out of a Docker container:

tasks:
  aws:
    cmds:
      - docker-compose run --rm aws		

Is it possible to have the ability for a command like task aws -- ls s3://my-bucket to be translated to docker-compose run --rm aws ls s3://my-bucket, meaning task will pass through anything after -- to the underlying shell command?

This is a more convenient way to pass extra variables compared to the current approach: task write-file FILE=file.txt "CONTENT=Hello, World!". Currently, using this approach allows me to write task aws CMD="ls s3://my-bucket" but the extra variable definition and quotes creates a lot of friction that I think can be alleviated with my proposal.

If this is not possible, it would be a really nice capability to have in the future.

@andreynering andreynering added type: feature A new feature or functionality. proposal area: variables Changes related to variables. labels May 16, 2020
@andreynering
Copy link
Member

andreynering commented May 16, 2020

Hi @huy-nguyen, thanks for opening this issue!

This is something that already came up recently by @mbertschler at #316.

Since more people think this would be important, I'll keep this issue open so this could be considered in the future.

I think that what would work is a mixture of these both proposals. We'd both require -- in the CLI to separate these args from other tasks and flags, and also require a special var to be concatenated in the right task[s]:

task yarn -- test-ci
version: '3'

tasks:
  yarn:
    dir: js
    cmds:
      - yarn {{.CLI_ARGS}}

@huy-nguyen
Copy link
Author

@andreynering Your proposal sounds great. The one inconvenience with my current workaround of declaring variables on the command line (task write-file FILE=file.txt "CONTENT=Hello, World!") is that the shell doesn't offer tab completions within quoted strings. Because of that, allowing pass through arguments after -- is the superior solution.

@hyperupcall
Copy link

hyperupcall commented Jul 16, 2020

I am also in strong support of this feature. In my case, I would be appending {{.CLI_ARGS}} to most of my commands because I tag on extra arguments ad-hoc pretty frequently. Maybe there could be a way to make enable it as default with some option to reduce duplication?

like so:

version: '3'

passthroughArgs: true

tasks:
   yarn:
...

@stephencheng

This comment was marked as off-topic.

@huy-nguyen
Copy link
Author

huy-nguyen commented Jul 18, 2020

@stephencheng upcmd looks very nice and solves a lot of my use cases. How long have you worked on it?

@stephencheng

This comment was marked as off-topic.

@JulienBreux
Copy link

🆙 Do you have any news about this killer feature?

@JulienBreux
Copy link

JulienBreux commented Oct 16, 2020

My point of view:

We have this: task firstTask secondTask

We want this: task firstTaks [ARGS] or task firstTaks secondTask [ARGS].

The question is: how to detect args vs task?

@JulienBreux
Copy link

@andreynering do you think if we havepassthroughArgs: true we can cancel the last error and pass arguments to each tasks?

For example:

  1. task taskExists0 taskExists1 taskNotExists0 with passthroughArgs: true = exec taskExists0 with args taskNotExists0 and exec taskExists1 with args taskNotExists0 but no error
  2. task taskExists0 taskExists1 taskNotExists0 without passthroughArgs: true = error taskNotExists0 doesn't exists?

@andreynering
Copy link
Member

Hi @JulienBreux,

I proposed a solution in this comment that I think it'll work well.

@andreynering andreynering changed the title "Passthrough" arguments to tasks Add support for delegating CLI arguments with "--" and a special CLI_ARGS variable Nov 8, 2020
@andreynering
Copy link
Member

This was implemented in e6c4706 and will be available in the next release

@endorama
Copy link

endorama commented Apr 1, 2021

Hello, I tried using this feature, but I get an error. I tried the proposed YAML config from the configuration, but it's notworking.

Usage:

task yarn -- install
task: Available tasks for this project:
* run:          Build and run the web app
* tests:        Run entire testsuite
* tests:single: Run a single test, specify with RUN
task: Task "install" not found

Taskfile.yaml

[...]
tasks:
  yarn:
    cmds:
      - yarn {{.CLI_ARGS}}
[...]

To check the behaviour I added a test case to the args module (you can look at it in my fork), but I get an error. It may be because my test case is wrong, but this is the test result, that suggest the parsing for CLI_ARGS is not working.

    --- FAIL: TestArgsV3/TestArgs8 (0.00s)
        args_test.go:110: 
            	Error Trace:	args_test.go:110
            	Error:      	Not equal: 
            	            	expected: []taskfile.Call{taskfile.Call{Task:"task", Vars:(*taskfile.Vars)(nil)}}
            	            	actual  : []taskfile.Call{taskfile.Call{Task:"task", Vars:(*taskfile.Vars)(nil)}, taskfile.Call{Task:"--", Vars:(*taskfile.Vars)(nil)}, taskfile.Call{Task:"arg", Vars:(*taskfile.Vars)(nil)}}
            	            	
            	            	Diff:
            	            	--- Expected
            	            	+++ Actual
            	            	@@ -1,4 +1,12 @@
            	            	-([]taskfile.Call) (len=1) {
            	            	+([]taskfile.Call) (len=3) {
            	            	  (taskfile.Call) {
            	            	   Task: (string) (len=4) "task",
            	            	+  Vars: (*taskfile.Vars)(<nil>)
            	            	+ },
            	            	+ (taskfile.Call) {
            	            	+  Task: (string) (len=2) "--",
            	            	+  Vars: (*taskfile.Vars)(<nil>)
            	            	+ },
            	            	+ (taskfile.Call) {
            	            	+  Task: (string) (len=3) "arg",
            	            	   Vars: (*taskfile.Vars)(<nil>)
            	Test:       	TestArgsV3/TestArgs8
        args_test.go:112: 
            	Error Trace:	args_test.go:112
            	Error:      	Not equal: 
            	            	expected: &taskfile.Vars{Keys:[]string{"CLI_ARGS"}, Mapping:map[string]taskfile.Var{"CLI_ARGS":taskfile.Var{Static:"arg", Live:interface {}(nil), Sh:"", Dir:""}}}
            	            	actual  : &taskfile.Vars{Keys:[]string(nil), Mapping:map[string]taskfile.Var(nil)}
            	            	
            	            	Diff:
            	            	--- Expected
            	            	+++ Actual
            	            	@@ -1,13 +1,4 @@
            	            	 (*taskfile.Vars)({
            	            	- Keys: ([]string) (len=1) {
            	            	-  (string) (len=8) "CLI_ARGS"
            	            	- },
            	            	- Mapping: (map[string]taskfile.Var) (len=1) {
            	            	-  (string) (len=8) "CLI_ARGS": (taskfile.Var) {
            	            	-   Static: (string) (len=3) "arg",
            	            	-   Live: (interface {}) <nil>,
            	            	-   Sh: (string) "",
            	            	-   Dir: (string) ""
            	            	-  }
            	            	- }
            	            	+ Keys: ([]string) <nil>,
            	            	+ Mapping: (map[string]taskfile.Var) <nil>
            	            	 })
            	Test:       	TestArgsV3/TestArgs8

Is this expected? Thanks

@andreynering
Copy link
Member

Hi @endorama,

Can you confirm you're using the latest release? I have the impression that you may be using an older release.

Also, a test case like you wrote wouldn't work because the variable (for technical reasons) is added on the main package, here:

e6c4706#diff-73fe859c349d50c0779c1c52c76d9c0c736905a058675d37294a447b60e0e693R172

@endorama
Copy link

Can you confirm you're using the latest release? I have the impression that you may be using an older release.

@andreynering Sorry for the long wait, but I can confirm this is not happening anymore on 3.4.3. So everything's good 👍 thank you for the support!

@xorander00
Copy link

Using a source-build on FreeBSD (13.0) of tags/v3.4.3, -- args aren't being set on CLI_ARGS. In addition to the below, I also tried quoting it as '{{.CLI_ARGS}}', but to no avail.

I'm not well-versed in Go at all, but not a beginner coder either. I'm willing to give it a shot later this week to try figuring this out. Any potential pointers anyone could give me to get started would be much appreciated, thanks! :)

Taskfile.yml

version: '3'

tasks:
  petri0: echo {{.CLI_ARGS}}

  petri1:
    desc: Petri Dish 1
    cmds:
      - echo {{.CLI_ARGS}}

Execution

$ task petri0
task: echo

$ task petri1
❯ task petri1
task: echo

$ task petri0 -- a b c
task: Available tasks for this project:
* petri1:    Petri Dish 1
task: Task "a" not found

$ task petri1 -- a b c
task: Available tasks for this project:
* petri1:    Petri Dish 1
task: Task "a" not found

@xorander00
Copy link

Tested again. It's a cross-platform issue between Linux & FreeBSD. Whether it's due to a compile option on my part or an API/library inconsistency between the two platforms , I'm not sure yet.

@xorander00
Copy link

Ignore, works with latest.

@dulataldazharov
Copy link

Is it possible to pass several named or at least indexed CLI arguments?
For example, if I want to pass username and password arguments, and treat them separately.

@andreynering
Copy link
Member

@dulataldazharov You can pass multiple arguments after --, but them all will be joined in the same CLI_ARGS:

task default -- arg1 arg2 'arg number 3'
cmd: echo {{.CLI_ARGS}}
echo arg1 arg2 'arg number 3'

If you need to treat them separately, you need different variables.

@titpetric
Copy link

@andreynering it doesn't seem to be working with v3@latest (go install): Task version: v3.20.0 (h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc=);

# cat Taskfile.yml | grep CLI_ARGS
      - go build {{.CLI_ARGS}} -tags=goplugin -trimpath .
      - go build {{.CLI_ARGS}} -buildmode=plugin -trimpath -o plugin.so .
# task -- -buildvcs=false
task: [build-gateway] go build  -tags=goplugin -trimpath .
task: [build-plugin] go build  -buildmode=plugin -trimpath -o plugin.so .

Should I file a separate issue for it?

@titpetric
Copy link

Nevermind, it was on my end - the tasks were invoked with task name rather than task: name, so CLI_ARGS did not carry

@stevensgarcia
Copy link

Hi.

Is it possible to isolate a specific argument from .CLI_ARGS? I've been trying this, but I got numbers, I guess the index, but not the value.
(BTW I'm not a golang dev)

# Task
demo:
    cmds:
      - echo "{{index .CLI_ARGS 0}}"`

# Command
task demo -- arg0 arg1 arg2

# Output
task: [demo] echo "105"
105`

Thanks

@andreynering
Copy link
Member

@stevensgarcia I suggest you to ask for different variable names instead of trying to use CLI_ARGS for that. CLI_ARGS is meant to keep all arguments on a single string.

@vaclav-dvorak
Copy link

vaclav-dvorak commented Mar 7, 2023

Hi
this maybe should never been used...

seems go-task is somehow sprig complaint (similar to helm) and this hack seem to be working:

cmds:
      - echo {{(split " " .CLI_ARGS)._0}}
      - echo {{(split " " .CLI_ARGS)._1}}

@andreynering
Copy link
Member

@vaclav-dvorak Yes, we use slim-sprig, a stripped down version of sprig (maintained by ourselves).

Keep in mind that split may not work 100% of the time. If you happen to have an argument with spaces inside.

task default -- foo bar 'foo bar baz' means CLI_ARGS will be foo bar 'foo bar baz' and your split would become ["foo", "bar", "'foo", "bar", "baz'"].

We might want to add a function splitArgs to parse that, which should be relatively simple to implement.

@vaclav-dvorak
Copy link

Keep in mind that split may not work 100% of the time. If you happen to have an argument with spaces inside.

This is 100% true... ive posted it as a hack that was usefull for my usecase where i want to pass multiple single word arguments to script :)

having a dedicated "safe" template function for it would be perfect.

@andreynering
Copy link
Member

Issue created: #1040

@pd93 pd93 removed type: feature A new feature or functionality. type: proposal labels Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: variables Changes related to variables.
Projects
None yet
Development

No branches or pull requests