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

Implement quiet mode, silent on skipped hooks (WIP) #1560

Draft
wants to merge 9 commits into
base: master
from

Conversation

@peterjc
Copy link

@peterjc peterjc commented Aug 15, 2020

I would like to see pre-commit be less verbose, issue #823.

Version 3

Based on feedback this no longer alters the "Passed" lines at all, only "Skipped" lines are silenced in the new --quiet mode, and only when there were no files to check (not silenced if skipped via configuration).

The core functionality seems to be working, the test suite needs updating still.

Example:

$ SKIP=mypy pre-commit run --files pre_commit/*.py 
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Check JSON...........................................(no files to check)Skipped
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)................................................Passed
Tests should end in _test.py.........................(no files to check)Skipped
Fix requirements.txt.................................(no files to check)Skipped
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
Validate Pre-Commit Manifest.........................(no files to check)Skipped
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
setup-cfg-fmt........................................(no files to check)Skipped
mypy....................................................................Skipped
Check hooks apply to the repository..................(no files to check)Skipped
Check for useless excludes...........................(no files to check)Skipped

versus:

$ SKIP=mypy pre-commit run --files pre_commit/*.py -q
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Debug Statements (Python)................................................Passed
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
mypy....................................................................Skipped
All 19 pre-commit hook(s) passed or skipped

Version 2

I would like to see pre-commit be less verbose, issue #823. The core functionality seems to be working, the test suite needs updating still.

I looked at #1218, but here I am trying to be less invasive. The idea here is in quiet mode never print the skipped or passed lines. Attempting to silence the "Passed" lines is more complicated since the initial part is normally printed before we know if it will pass or fail. This takes the pragmatic approach in quiet mode of not even printing the hook name until we know it failed.

As per discussion on #823, success is not silent - a one line summary is shown instead. This could report the number passed vs skipped but would need minor changes to the _run_single_hook function.

Example:

$ pre-commit run --files pre_commit/*.py
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Check JSON...........................................(no files to check)Skipped
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)................................................Passed
Tests should end in _test.py.........................(no files to check)Skipped
Fix requirements.txt.................................(no files to check)Skipped
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
Validate Pre-Commit Manifest.........................(no files to check)Skipped
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
setup-cfg-fmt........................................(no files to check)Skipped
mypy.....................................................................Passed
Check hooks apply to the repository..................(no files to check)Skipped
Check for useless excludes...........................(no files to check)Skipped

versus:

$ pre-commit run --files pre_commit/*.py -q
All 19 pre-commit hook(s) passed or skipped

Typical usage would be pre-commit install --quiet which will write the .git/hooks/pre-commit script with the --quiet argument included, ready to be triggered via git commit ... as usual.


Version 1 - Original description

I would like to see pre-commit be less verbose, issue #823. This is a work in progress, since I got stuck - but shared for comment/feedback.

I looked at #1218, but here I am trying to be less invasive. The idea here is in quiet mode never print the skipped lines. Attempting to silence the "Passed" lines would be more complicated since the initial part is printed before we know if it will pass or fail.

This works:

$ pre-commit run 
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Check JSON...........................................(no files to check)Skipped
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)................................................Passed
Tests should end in _test.py.........................(no files to check)Skipped
Fix requirements.txt.................................(no files to check)Skipped
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
Validate Pre-Commit Manifest.........................(no files to check)Skipped
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
setup-cfg-fmt........................................(no files to check)Skipped
mypy.....................................................................Passed
Check hooks apply to the repository..................(no files to check)Skipped
Check for useless excludes...........................(no files to check)Skipped

versus with -q or --quiet:

$ pre-commit run -q
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Debug Statements (Python)................................................Passed
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
mypy.....................................................................Passed

However, when called via git the git pre-commit hook, I'm missing something with the arg setup:

$ git commit -m "Implement quiet mode, silent on skipped hooks" pre_commit/commands/run.py pre_commit/main.py
An unexpected error has occurred: AttributeError: 'Namespace' object has no attribute 'quiet'
Check the log at /Users/xxx/.cache/pre-commit/pre-commit.log

The log file says:

Traceback (most recent call last):
  File "/Users/pc40583/repositories/pre-commit/pre_commit/error_handler.py", line 63, in error_handler
    yield
  File "/Users/pc40583/repositories/pre-commit/pre_commit/main.py", line 373, in main
    args=args.rest[1:],
  File "/Users/pc40583/repositories/pre-commit/pre_commit/commands/hook_impl.py", line 217, in hook_impl
    return retv | run(config, store, ns)
  File "/Users/pc40583/repositories/pre-commit/pre_commit/commands/run.py", line 386, in run
    return _run_hooks(config, hooks, args, environ)
  File "/Users/pc40583/repositories/pre-commit/pre_commit/commands/run.py", line 271, in _run_hooks
    quiet=False if args.verbose else args.quiet,
AttributeError: 'Namespace' object has no attribute 'quiet'

I am puzzled why "args.verbose" works, but "args.quiet" fails since both are defined in the same place.

(As an aside, --verbose and --quiet could be setup as mutually exclusive)

I have not yet attempted to set quiet mode at install time (which is how I would likely use it myself).

@peterjc peterjc marked this pull request as draft Aug 15, 2020
@peterjc peterjc mentioned this pull request Aug 16, 2020
1 of 4 tasks complete
@asottile
Copy link
Member

@asottile asottile commented Aug 22, 2020

fwiw the namespace for git hooks is constructed inside hook-impl:

def _ns(
hook_type: str,
color: bool,
*,
all_files: bool = False,
from_ref: Optional[str] = None,
to_ref: Optional[str] = None,
remote_name: Optional[str] = None,
remote_url: Optional[str] = None,
commit_msg_filename: Optional[str] = None,
checkout_type: Optional[str] = None,
) -> argparse.Namespace:
return argparse.Namespace(
color=color,
hook_stage=hook_type.replace('pre-', ''),
from_ref=from_ref,
to_ref=to_ref,
remote_name=remote_name,
remote_url=remote_url,
commit_msg_filename=commit_msg_filename,
all_files=all_files,
checkout_type=checkout_type,
files=(),
hook=None,
verbose=False,
show_diff_on_failure=False,
)

@peterjc
Copy link
Author

@peterjc peterjc commented Aug 22, 2020

Thank you for the namespace pointer - that fixed my exception.

I think the next step is to add --quiet to the pre-commit hook-impl comment, and then the scripts like .git/hooks/pre-commit can be manually changed from:

# start templated
INSTALL_PYTHON = '/Users/pc40583/miniconda3/bin/python3.7'
ARGS = ['hook-impl', '--config=.pre-commit-config.yaml', '--hook-type=pre-commit']
# end template

to:

# start templated
INSTALL_PYTHON = '/Users/pc40583/miniconda3/bin/python3.7'
ARGS = ['hook-impl', '--config=.pre-commit-config.yaml', '--hook-type=pre-commit', '--quiet']
# end template

And finally from a configuration point of view, update precommit install to allow pre-commit install --quiet for writing the hooks like that.

(That still leaves the desired behaviour of quiet mode to be refined)

@peterjc
Copy link
Author

@peterjc peterjc commented Aug 22, 2020

Any preference on the command line help listing -q, --quiet versus --quiet, -q versus just just one?

I ask since currently the existing command lines are not 100% consistent here, something perhaps worth addressing separately?

@peterjc peterjc force-pushed the peterjc:quiet_skip branch from 0005920 to cf56c8c Aug 22, 2020
@peterjc peterjc changed the title Implement quiet mode, silent on skipped hooks (WIP) Implement quiet mode, silent on skipped or passed hooks (WIP) Aug 22, 2020
peterjc added 4 commits Aug 22, 2020
Can now add --quiet to the scripts like
.git/hooks/pre-commit to run in quiet mode.
Downside is delay output on failed hooks
Adding a new summary line if all hooks passed
or were skipped in either --quiet mode (where
it may be the only output) or --verbose mode
(since the summary seems worth showing here).
@peterjc peterjc force-pushed the peterjc:quiet_skip branch from cf56c8c to f8c8b7e Aug 22, 2020
@peterjc
Copy link
Author

@peterjc peterjc commented Aug 22, 2020

The tests are failing during Tox, lots of AttributeError: 'auto_namedtuple' object has no attribute 'quiet' errors. I'm happy to work on that later given some positive feedback on the work thus far.

Copy link
Member

@asottile asottile left a comment

I believe the next key to the puzzle is testing.util.run_opts

pre_commit/commands/run.py Outdated Show resolved Hide resolved
pre_commit/commands/run.py Outdated Show resolved Hide resolved
peterjc added 2 commits Aug 24, 2020
This reverts commit 5c1a749.

Feedback from Anthony Sottile was to focus on the skipped
messages only for now.
e.g.

$ SKIP=mypy pre-commit run --files pre_commit/*.py
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Check JSON...........................................(no files to check)Skipped
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)................................................Passed
Tests should end in _test.py.........................(no files to check)Skipped
Fix requirements.txt.................................(no files to check)Skipped
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
Validate Pre-Commit Manifest.........................(no files to check)Skipped
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
setup-cfg-fmt........................................(no files to check)Skipped
mypy....................................................................Skipped
Check hooks apply to the repository..................(no files to check)Skipped
Check for useless excludes...........................(no files to check)Skipped

Versus:

$ SKIP=mypy pre-commit run --files pre_commit/*.py -q
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check docstring is first.................................................Passed
Debug Statements (Python)................................................Passed
Fix double quoted strings................................................Passed
flake8...................................................................Passed
autopep8.................................................................Passed
pyupgrade................................................................Passed
Reorder python imports...................................................Passed
Add trailing commas......................................................Passed
mypy....................................................................Skipped

Here we still show mypy which the user had said to skip.
@peterjc peterjc changed the title Implement quiet mode, silent on skipped or passed hooks (WIP) Implement quiet mode, silent on skipped hooks (WIP) Aug 24, 2020
Placed next to verbose due to logical connection.
This is not part of a public API so the change
should not matter - the tests all seem to pass
arguments by name anyway.
@peterjc
Copy link
Author

@peterjc peterjc commented Aug 24, 2020

Modified as per comments. Some tests still failing (likely due to my addition of a one line summary in verbose mode).

If we are going to leave the passed lines, then the one line summary to prevent a silent run is only really needed if all the hooks were silent passes. Are you open to adding another return value to _run_single_hook function? A boolean for if the hook silent is enough for right now (but you might want a status flag capturing skip/pass/fail as well?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants
You can’t perform that action at this time.