Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Console] Add of hidden and deprecation option flags #54439

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

Open
wants to merge 15 commits into
base: 7.3
Choose a base branch
Loading
from

Conversation

flkasper
Copy link

@flkasper flkasper commented Mar 29, 2024

Q A
Branch? 7.1
Bug fix? no
New feature? yes
Deprecations? no
Issues resolves #54206
License MIT

Add new InputOption flags HIDDEN and DEPRECATED.

Hidden options are not printed to the console output (or other descriptors) unless the hidden option --show-hidden-options is used.

If a deprecated flagged option is used, a deprecation message is output before execution (execute method).
Deprecated flagged options are coloured red in the help output.

Example:

#[AsCommand(name: 'test', description: 'description')]
class TestCommand extends Command
{
    protected function configure()
    {
        $this->addOption('test-hidden', null, InputOption::VALUE_NONE | InputOption::HIDDEN, 'HIDDEN option');
        $this->addOption('test-deprecated', null, InputOption::VALUE_NONE | InputOption::DEPRECATED, 'DEPRECATED option');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        // ...
        return self::SUCCESS;
    }
}

Example usage:
image
image

@carsonbot
Copy link

Hey!

I see that this is your first PR. That is great! Welcome!

Symfony has a contribution guide which I suggest you to read.

In short:

  • Always add tests
  • Keep backward compatibility (see https://symfony.com/bc).
  • Bug fixes must be submitted against the lowest maintained branch where they apply (see https://symfony.com/releases)
  • Features and deprecations must be submitted against the 7.1 branch.

Review the GitHub status checks of your pull request and try to solve the reported issues. If some tests are failing, try to see if they are failing because of this change.

When two Symfony core team members approve this change, it will be merged and you will become an official Symfony contributor!
If this PR is merged in a lower version branch, it will be merged up to all maintained branches within a few days.

I am going to sit back now and wait for the reviews.

Cheers!

Carsonbot

@flkasper flkasper force-pushed the feature/7.1-hidden-and-deprecated-options branch from bfd9bfc to 6639321 Compare March 29, 2024 18:45
@94noni
Copy link
Contributor

94noni commented Mar 30, 2024

Waw very nice :)
Passing by, i would just split the PR commits into 2 separated PRs
Feature addition and cs fix on the other

@flkasper
Copy link
Author

@94noni I actually only wanted to fix my commit via ecs and had therefore limited ecs to the console bundle only.
Who would have thought that the code would differ in so many places :)

@94noni
Copy link
Contributor

94noni commented Mar 30, 2024

Got it :)
Lets wait other reviews 👌🏼

@smnandre
Copy link
Member

Love the idea... but i feel really agressed by the red, and i feel it makes the option an unwanted point of attention.

Did you try with other colors ? Something muted maybe to get the opposite effect ?

I think we should not rely only on colors (for accessibility reasons but also technical ones),

What about an automatic [deprecated] prefix in the description ?

Options:
    -test-deprecated            [deprecated] Lorem ipsum ...

With [deprecated] not having to be set in the option description

@flkasper
Copy link
Author

flkasper commented Mar 31, 2024

Love the idea... but i feel really agressed by the red, and i feel it makes the option an unwanted point of attention.
Did you try with other colors ? Something muted maybe to get the opposite effect ?

I had originally thought of yellow (warning), but this is already used in the headings such as "Options:".

I have now simply output in every available style and colour for comparison.
Personally, I think that yellow, gray and white would suit both in light and dark mode.

image
image

@flkasper
Copy link
Author

flkasper commented Mar 31, 2024

What about an automatic [deprecated] prefix in the description ?

I had also thought of this and it is actually a nice idea, but it has the disadvantage that you cannot simply customise this prefix.
See screenshots for the colours.

You would then have to add something like this (either to set the prefix or the message):

private array $optionDeprecationPrefix = [];

public function setOptionDeprecationPrefix(string $optionName, string $deprecationPrefix) {
    $this->optionDeprecationPrefix[$optionName] = $deprecationPrefix;
}

// On output:
$deprecationPrefix =  $this->optionDeprecationPrefix[$optionName] ??  'deprecated';
"[$deprecationPrefix] $optionDescription"

@smnandre
Copy link
Member

[...] grey [...]

Would be my personal choices, but colors are subjective, so let's see what others think about it ? :)

the disadvantage that you cannot simply customise this prefix.

That was not (in my mind) something configurable so i did not add the constraint.

But if you have commands from your app and bundles, that would be better to not allow a different style per command, no ?

I guess i'd do something like

sf list 

lorem:list            [deprecated] List all lorem from ipsum


sf list -v

lorem:list            [deprecated since 2.0] List all lorem from ipsum


sf list -vv

lorem:list            [deprecated since 2.0] List all lorem from ipsum  [Use foo:bar instead]

@GromNaN
Copy link
Member

GromNaN commented Mar 31, 2024

I like the grey too. We want this options to be less visible in the list, not highlight them.

And I don't see any reason for customizing the description prefix either. Consistency across commands is better.

Copy link
Member

@GromNaN GromNaN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this feature. I did a few tests on an application. It works very well, congratulations for your work.

There's a comment about the depreciation message display. It may take a deeper work to detect if an option has been passed. This could be a feature in its own.

The large number of style changes unrelated to the PR make review more difficult. These changes should be made in dedicated PRs with arguments. They can have an impact on maintenance (and upmerges from old branches to new ones).

src/Symfony/Component/Console/Command/Command.php Outdated Show resolved Hide resolved
src/Symfony/Component/Console/.editorconfig Outdated Show resolved Hide resolved
src/Symfony/Component/Console/Command/Command.php Outdated Show resolved Hide resolved
src/Symfony/Component/Console/Helper/ProgressIndicator.php Outdated Show resolved Hide resolved
src/Symfony/Component/Console/Input/InputOption.php Outdated Show resolved Hide resolved
@@ -0,0 +1 @@
NULL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a NULL char here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have extended the existing test providers with corresponding test cases for hidden options.

NULL is a valid json (string) and unfortunately necessary, as otherwise JsonDescriptorTest::testDescribeInputOption would fail.

src/Symfony/Component/Console/Tests/Helper/TableTest.php Outdated Show resolved Hide resolved
src/Symfony/Component/Console/Command/Command.php Outdated Show resolved Hide resolved
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it php-cs-fixer that caused this license block to be added? That can't be done in this PR because it makes it look like there are a lot more modified files than actually necessary for this feature.
Please revert all formatting changes not related to the PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the config of php-cs-fixer should be ignoring all files in Fixtures folder, so I doubt it is the case (unless a custom config was used, which would be a no-go)

Copy link
Author

@flkasper flkasper Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it php-cs-fixer that caused this license block to be added?

Yes, this is due to the php-cs-fixer.

I have used the config .php-cs-fixer.dist.php from the root.
Rule header_comment is being configured there.
No idea why the fixtures are also changed.

#Executed command:
php tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php <folder>

I'll look over it again and remove all unrelated changes to the PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you pass a directory, you need to use --path-mode=intersection (from memory, maybe some typo there) or phpcs ignores the previously defined paths .. and exclusions.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smnandre phpcs is a different tool. I think you mean php-cs-fixer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed sorry *

php php-cs-fixer.phar fix --path-mode=intersection /path/to/dir

https://cs.symfony.com/doc/usage.html#the-fix-command

(* my local alias for php-cs-fixer is... phpcs 😶 )

@stof
Copy link
Member

stof commented Apr 11, 2024

I haven't checked the current state of the PR yet. But for sure, we cannot rely on color only:

  • color blind people won't see them, causing accessibility issues
  • not all terminals support colors

@flkasper
Copy link
Author

I have added @smnandre's suggestion for "[deprecated] prefix to the option description in the TextDescriptor.

Copy link
Member

@GromNaN GromNaN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with a last suggestion.

src/Symfony/Component/Console/Input/InputOption.php Outdated Show resolved Hide resolved
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I just have minor comments. Can you please rebase also?

@@ -273,6 +275,10 @@ public function run(InputInterface $input, OutputInterface $output): int

$input->validate();

if (isset($inputDefinition)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the isset?

Suggested change
if (isset($inputDefinition)) {
if ($inputDefinition) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$inputDefinition is defined in a try..catch, but should be outside.

Copy link
Author

@flkasper flkasper Aug 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @GromNaN has already explained, $inputDefinition is defined within a try...catch:

try {
    $inputDefinition = $this->getDefinition();
    $input->bind($inputDefinition);
} catch (ExceptionInterface $e) {
    if (!$this->ignoreValidationErrors) {
        throw $e;
    }
}

Since getDefinition can also throw an exception (if the parent constructor call is missing), moving it outside the try...catch makes little sense.

Therefore, isset must be used to check whether $inputDefinition is defined.

src/Symfony/Component/Console/Command/Command.php Outdated Show resolved Hide resolved
src/Symfony/Component/Console/Command/Command.php Outdated Show resolved Hide resolved
*
* @return bool true if mode is $mode, false otherwise
*/
protected function hasMode(int $mode): bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not add a new method, it's unrelated to the proposed feature

Copy link
Author

@flkasper flkasper Aug 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is an internal function and simplifies and reduces duplicate/similar code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not added as an internal method. You added it as part of the semver API.

If you want to keep the helper, make it private instead.

@@ -70,6 +70,7 @@ protected function describeInputOption(InputOption $option, array $options = [])
.'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
.'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
.'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
.($option->isDeprecated() ? ('* Is deprecated: yes'."\n") : '')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we have a line Is deprecated: no instead ?

'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
'default' => \INF === $option->getDefault() ? 'INF' : $option->getDefault(),
];
if (!$option->isDeprecated()) {
unset($data['is_deprecated']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not unset this. The json is easier to use if we don't have conditional keys in it.

@fabpot fabpot modified the milestones: 7.2, 7.3 Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for Hidden Options in Console
Morty Proxy This is a proxified and sanitized view of the page, visit original site.