Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Console] Option -e prod is interpreted as a command when no command is specified #23343

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

Closed
ghost opened this issue Jun 30, 2017 · 29 comments · Fixed by symfony/recipes#481
Closed
Labels
Bug Console Help wanted Issues and PRs which are looking for volunteers to complete them. Status: Reviewed

Comments

@ghost
Copy link

ghost commented Jun 30, 2017

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 3.3.2

I usually use the short command bin/console to list all available options. But on a production server, I have to set the env option to avoid default dev environment and missing debug vendors.

But, if I type only bin/console -e prod the command report the following error:

  [Symfony\Component\Console\Exception\CommandNotFoundException]  
  Command "prod" is not defined.                                  
  Did you mean this?                                              
      doctrine:ensure-production-settings

As soon as I set a command, there is no problem (for example bin/console list -e prod. The word prod is interpreted as the command instead of the value of the -e option.

@chalasr
Copy link
Member

chalasr commented Jul 2, 2017

Note that you can set the SYMFONY_ENV environment variable to avoid the need for passing the option every time.

@ghost
Copy link
Author

ghost commented Jul 3, 2017

Hi, yes absolutely. In my use case it's more safe to rely on the command parameter. Obviously this is not a major bug. I will try to investigate in the next days.

@magnetik
Copy link
Contributor

magnetik commented Jul 5, 2017

It's because of the Application::getCommandName() that returns the first argument as command name: https://github.com/symfony/symfony/blame/master/src/Symfony/Component/Console/Application.php#L832

@ghost
Copy link
Author

ghost commented Jul 7, 2017

Suggest (also reminder for me): If an option have the mode VALUE_REQUIRED, the argument just after should be attached to its value, if not already an option.

@yceruto
Copy link
Member

yceruto commented Jul 7, 2017

To avoid this issue you could try this syntax bin/console -e=prod?

@ghost
Copy link
Author

ghost commented Jul 7, 2017

Yes, it's true. This is not a big issue, but the console does not behave as it should. In other cases, putting the value after a space is not a problem, so it should be also not here :)

@javiereguiluz
Copy link
Member

Even if there are alternative solutions (SYMFONY_ENV var or -e=prod) I think @romain-pierre is right and we should consider this a bug.

@chalasr
Copy link
Member

chalasr commented Jul 11, 2017

Indeed, I'll give it a try this week.

@Simperfit
Copy link
Contributor

@chalasr did you already implemented it, or could I look into it ?

@HeahDude
Copy link
Contributor

HeahDude commented Aug 5, 2017

Isn't it somehow expected? I guess in such case bin/console -- -e prod should be used right?

@Simperfit
Copy link
Contributor

Simperfit commented Aug 5, 2017

@HeahDude IMO it should be working and return the available command in prod env, like kubectl for exemple with the -n (for --namespace)

@chalasr
Copy link
Member

chalasr commented Aug 5, 2017

@Simperfit I started to look into, the issue starts from ArgvInput::getFirstArgument(). It should consider a space as separator for option values, but it doesn't (considers = only). The right fix would be to check that the previous token starts with -, and if it does, check that the option is part of the definition and accepts a value (otherwise we could consider a real argument as if it is the value of an option). Problem is that at this point (of the application run process) the --env option is not yet part of the input definition, it is only after that mergeApplicationDefinition has been called, which happens later.
I have to look deeper into, but if you want to give it a try feel free to do so! :)
Thanks for the ping.

@ghost
Copy link
Author

ghost commented Nov 6, 2017

This is the only way I've found at this time to resolve this issue: https://github.com/romain-pierre/symfony/commit/e76a597fb8ef898bc27a62a146cd04f4a2d0b7bc

@Simperfit
Copy link
Contributor

@romain-pierre Do you want to create the pull request ? You already did the feature, you may have to add test ;).

@ghost
Copy link
Author

ghost commented Nov 13, 2017

I would like to have an advise from @chalasr before, because I don't know the impact of calling bind() twice.

@chalasr
Copy link
Member

chalasr commented Nov 13, 2017

👍 for fixing getFirstArgument() and binding the input before checking for global options.
We need to wrap the call it in a try-catch though, bind() would throw for any input argument that is not part of the application definition (i.e. the command args).
PR with test case welcomed, should target 2.7

@issei-m
Copy link
Contributor

issei-m commented Nov 20, 2017

Any news?

@fabpot
Copy link
Member

fabpot commented Nov 20, 2017

For Symfony 4.1, I would recommend to deprecate both -e and --no-debug as they are redundant with the new env vars (APP_ENV and APP_DEBUG).

@Simperfit
Copy link
Contributor

@romain-pierre Do you want to fix the behaviour for 2.7 to 4.0 ?
And for 4.1 we should deprecate it.

@chalasr
Copy link
Member

chalasr commented Dec 5, 2017

@Simperfit Userland applications can have similar options, the behavior should not be deprecated (only some core global options should be).

@steve-todorov
Copy link

How exactly should I start the server:start command if I would like to test the prod environment?

# SYMFONY_ENV=prod bin/console server:start 0.0.0.0:8000
 [ERROR] The document root directory must be either passed as first argument of the constructor or through the "docroot"
         input option.                                                                                                  

# SYMFONY_ENV=prod bin/console server:start 0.0.0.0:8000
 [ERROR] The document root directory must be either passed as first argument of the constructor or through the "docroot"
         input option.                                                                                                  
                                                                                                                        
# export SYMFONY_ENV=prod ; bin/console server:start 0.0.0.0:8000
 [ERROR] The document root directory must be either passed as first argument of the constructor or through the "docroot"
         input option.                                                                                                  
                                                                                                                        
# export SYMFONY_ENV=prod ; bin/console server:start 0.0.0.0:8000 --docroot ./web/
 [ERROR] The environment must be passed as second argument of the constructor.                                          

# SYMFONY_ENV=prod bin/console server:start 0.0.0.0:8000 --docroot ./web/
 [ERROR] The environment must be passed as second argument of the constructor.                                          

# SYMFONY_ENV=prod bin/console -e=prod server:start 0.0.0.0:8000 --docroot ./web/
 [ERROR] The environment must be passed as second argument of the constructor.  

# bin/console server:start 0.0.0.0:8000 --docroot ./web/ --env=prod                                                                                                                        
 [ERROR] The environment must be passed as second argument of the constructor.   

It doesn't seem like you could export the SYMFONY_ENV and then execute the symfony command at all?

@nicodemuz
Copy link
Contributor

I'm also facing the same problem as @steve-todorov .. can't seem to use the web server bundle ..

@nicodemuz
Copy link
Contributor

Managed to solve the problem. The problem for me was that I was mixing Symfony 3.4 and 4.0 bundles together. Surprisingly this was not caught by the package manager (composer) as a conflict.

After removing the distribution-bundle, all other bundles got correctly upgraded to correct versions.

@LinkingYou
Copy link

I have the same issue, that i can't set the environment through the command line option.

Works fine:
php bin/console app:doit

Works fine too:
php bin/console app:doit --env=dev

Fails with "There are no commands defined in the "app" namespace.":
php bin/console app:doit --env=prod

To set this by an environment variable is no option for me, because my command-line-tool should run twice on the same machine. One version in dev and the other in prod.

I am using symfony 4.1.3.

@stof
Copy link
Member

stof commented Aug 17, 2018

@LinkingYou you can set env variables for each call too

@ghost
Copy link
Author

ghost commented Oct 10, 2018

I think this issue can be closed since #28653

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Nov 14, 2018

#28653 has been reverted, re-opening.
To fix this one, we could make ArgvInput::getParameterOption() accept a new bool $consume = false argument. When set to true, the corrsponding parameter would be removed from the ArgvInput instance.

@chalasr
Copy link
Member

chalasr commented Nov 15, 2018

Having Input::hasOption() returning false for those? Options defined at the application level are meant to be available to all registered commands

@nicolas-grekas
Copy link
Member

Options defined at the application level are meant to be available to all registered commands

Unless one opts in to a different meaning by using the proposed extra argument. I'd really prefer no hard coded special edge case btw.

@nicolas-grekas nicolas-grekas added the Help wanted Issues and PRs which are looking for volunteers to complete them. label Feb 14, 2019
@fabpot fabpot closed this as completed Feb 21, 2019
fabpot added a commit that referenced this issue Feb 21, 2019
…ning an option value (chalasr)

This PR was merged into the 3.4 branch.

Discussion
----------

[Console] Prevent ArgvInput::getFirstArgument() from returning an option value

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #23343
| License       | MIT
| Doc PR        | n/a

Fixes the case where the passed input string contains no command name but one or more global (i.e. application-defined) options accepting values.

Commits
-------

46461e9 [Console] Prevent ArgvInput::getFirstArgument() from returning an option value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Console Help wanted Issues and PRs which are looking for volunteers to complete them. Status: Reviewed
Projects
None yet
Development

Successfully merging a pull request may close this issue.