heroku / cli

Heroku CLI
https://devcenter.heroku.com/articles/heroku-cli
ISC License
851 stars 223 forks source link

`heroku run` command arguments are incorrectly sorted, breaking command functionality #2961

Closed timfjord closed 1 month ago

timfjord commented 2 months ago

This project is for the Heroku CLI only and issues are reviewed as we are able. If you need more immediate assistance or help with anything not specific to the CLI itself, please use https://help.heroku.com.

Do you want to request a feature or report a bug?

🪲 Bug

What is the current behaviour?

When running the command heroku run -a <app> -- smth --arg val --arg val, the arguments get sorted and passed to the Heroku application as smth --arg --arg val val. This reordering changes the intended structure of the arguments, causing the command to break and potentially fail to execute as expected.

What is the expected behaviour?

The arguments should be passed to the Heroku application in the exact order they are provided in the command. Specifically, the command heroku run -a <app> -- smth --arg val --arg val should be passed to the application as smth --arg val --arg val, preserving the original order and structure of the arguments.

rhussmann commented 2 months ago

Can confirm I'm seeing something similar with a Heroku task I'm running. Here's a sample excerpt from my terminal:

heroku run -a myapp "task" "translate_firmware" "string1" "string2" "3" "1" "2" "7" "1" "1593010317016"

Running task translate_firmware string1 string2 3 1 1 2 7 1593010317016

Notice the ordering of the numbers gets jumbled up from 3 1 2 7 1 1593010317016 to 3 1 1 2 7 1593010317016.

Running on MacOS Sonoma 14.5, heroku CLI installed via Homebrew

brew info heroku
==> heroku/brew/heroku: stable 9.1.0
rhussmann commented 2 months ago

A co-worker suggested I try another syntax, and it appears to work for me:

heroku run -a appName 'arg1 arg2 arg3 arg4 arg5 arg6...'

Enclosing all arguments (including the first) in single-quotes appears to work. Double-quotes seem to work as well if you're into shell interpolation.

k80bowman commented 2 months ago

We have not been able to reproduce this, unfortunately. @timfjord and @rhussmann, can you think of any details that might help us?

rhussmann commented 2 months ago

The only other thing I can think of is I'm running ZSH with OhMyZSH. I'm pretty sure Homebrew has installed some completions as a part of that.

k80bowman commented 2 months ago

I'm running ZSH with OhMyZSH as well. I can tell you what I did to try and reproduce it, if that helps. I created a simple node app and added a bash script that prints any args it receives. I deployed that to heroku and ran heroku run -a <app-name> -- ./print-args.sh --flag1 val1 --flag2 val2. The flags and values all appeared in order for me.

brettelliot commented 2 months ago

Dunno if this helps but i recently started experiencing an error with heroku run... it get "Error: Nonexistent flag" messages now. I too am running ohmyzsh. Enclosing the args in double quotes worked.

timfjord commented 2 months ago

I'm running ZSH with OhMyZSH as well. I can tell you what I did to try and reproduce it, if that helps. I created a simple node app and added a bash script that prints any args it receives. I deployed that to heroku and ran heroku run -a <app-name> -- ./print-args.sh --flag1 val1 --flag2 val2. The flags and values all appeared in order for me.

The original issue was about flags with the same name, @k80bowman could you please try the following: heroku run -a <app-name> -- ./print-args.sh --flag1 val1 --flag1 val2 (--flag1 should be present twice)

k80bowman commented 2 months ago

@brettelliot your issue is due to a known breaking change in v9. Enclosing the additional args or flags you want to pass on to the operation you are running through the heroku run command is a good way of separating them from the args and flags that apply to the run command itself. You can also separate them by using a --. Please refer to our Heroku Changelog entry for the release notes and other breaking changes.

k80bowman commented 2 months ago

@timfjord thank you for the hint, I was able to reproduce the problem. I'll look into it and get back to you.

k80bowman commented 2 months ago

Internal work item

We've found where the bug is and we will prioritize fixing it. For now, the best workaround seems to be to use single quotes as a separator rather than the double-dash.

timfjord commented 2 months ago

Thanks for the update @k80bowman

I can also confirm, that using single quotes as a separator solves the problem 👍🏻

k80bowman commented 1 month ago

A fix for this was released in v9.2.0 of the CLI. I'm going to go ahead and close this, but if it continues to be a problem please feel free to reopen.

G-Rath commented 4 weeks ago

@k80bowman it looks like this has introduced a bug:

❯ heroku --version
heroku/9.1.0 wsl-x64 node-v16.20.2

❯ heroku run --app my-app bash -- --help
Running bash --help on ⬢ my-app... up, run.1234
Running: bash --help
GNU bash, version 5.1.4(1)-release-(x86_64-pc-linux-gnu)
Usage:  bash [GNU long option] [option] ...
        bash [GNU long option] [option] script-file ...
GNU long options:
        --debug
        --debugger
        --dump-po-strings
        --dump-strings
        --help
        --init-file
        --login
        --noediting
        --noprofile
        --norc
        --posix
        --pretty-print
        --rcfile
        --restricted
        --verbose
        --version
Shell options:
        -ilrsD or -c command or -O shopt_option         (invocation only)
        -abefhkmnptuvxBCHP or -o option
Type `bash -c "help set"' for more information about shell options.
Type `bash -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.

bash home page: <http://www.gnu.org/software/bash>
General help using GNU software: <http://www.gnu.org/gethelp/>

❯ ~/heroku-cli-tmp/heroku/bin/heroku --version
heroku/9.2.1 wsl-x64 node-v16.20.2

❯ ~/heroku-cli-tmp/heroku/bin/heroku run --app my-app bash -- --help'
Running --help on ⬢ my-app... up, run.4567
Running: --help
exec: exec [-cl] [-a name] [command [argument ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive shell exits, unless
    the shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

This is causing our deployments to fail since our commands just don't end up being run - it looks like the fix might be to move the -- to be before the actual command itself (i.e. -- bash --help), which to me feels a bit safer anyway (as I'm saying "cli, ignore everything after the --, pass all of that to the dyno", rather than having to give it the commend before then saying "ignore everything after the --, pass that instead to the command I gave you"), but its at least at odds with the documentation you linked.