-
Couldn't load subscription status.
- Fork 20
Add fix command #80
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
Merged
Merged
Add fix command #80
Changes from all commits
Commits
Show all changes
79 commits
Select commit
Hold shift + click to select a range
3cd0da4
add gitpython as dependency
mshafer-NI 9b92744
get git import working
mshafer-NI 3f920ff
allow windows style paths
mshafer-NI 5fc3d2a
format
mshafer-NI 9053cd0
add support for handling cases with no ignored errors
mshafer-NI 8acb5aa
get initial setup working
mshafer-NI c0ae649
move git_utils to _utils.git
mshafer-NI 33238c1
un-needed
mshafer-NI 1f80f5f
fix imports
mshafer-NI 3abb625
remove the blank lines
mshafer-NI c06a5f2
cleanup some more for the linter
mshafer-NI b81dd37
extract multiline string helpers to _utils
mshafer-NI 0b6e870
typo
mshafer-NI 0a35203
format
mshafer-NI 0ba226f
make these work right
mshafer-NI b54f711
extract fixing multi-import lines
mshafer-NI 7c4c1dc
add sorting imports
mshafer-NI c3bcddc
format
mshafer-NI 2a647cd
add isort as dep
mshafer-NI 6e66b8f
make the linter happy
mshafer-NI f377be6
add some more test cases
mshafer-NI 6a08350
remove some dead code
mshafer-NI 614b99a
make it ignore imports in docstrings
mshafer-NI e5f7dd0
skip if line does not have import for from as a statement
mshafer-NI 10d0cbe
get it mostly working
mshafer-NI 34df13c
add the pyproject.toml file to the test env for getting the app name
mshafer-NI f8f97f2
cleanup the test case
mshafer-NI da9430d
get app_import_names passing down to sort correctly
mshafer-NI 96326b9
format
mshafer-NI 4c50922
extract handling single file
mshafer-NI 496c818
setup for --aggressive
mshafer-NI f5de92d
make the linter happy
mshafer-NI 1b43209
we can dog-food ourselves!
mshafer-NI ab7ea20
only suppress remaining if --aggressive
mshafer-NI e6d2ea4
get snapshots to where linter is happy with output without --aggressive
mshafer-NI e171e2a
fix var reference
mshafer-NI bfe916e
add --aggressive cases
mshafer-NI ec5f687
format
mshafer-NI 5073dee
remove unused code
mshafer-NI fbf3492
handle if dir is not in a git repo
mshafer-NI c444813
use the working tree dir
mshafer-NI a97127e
make black condense isort's output even with long comment after
mshafer-NI 1db0982
handle comments
mshafer-NI 7bf0621
cleanup tests
mshafer-NI 450a7fc
add example case of previously suppressed that is no longer needed
mshafer-NI 8b9beb3
revert testing change
mshafer-NI 4a986ad
‾\_(ツ)_/‾
mshafer-NI 243ed8a
try also locking gitdb
mshafer-NI b76d557
don't use git
mshafer-NI 77d8f24
remove deleted import
mshafer-NI b077660
just rglob with filter for excludes list
mshafer-NI 453c9eb
unextract handling the file
mshafer-NI 5e6c168
update fix to match
mshafer-NI c891708
refactor getting lint output to utils
mshafer-NI 298c164
finish extracting
mshafer-NI 6949a85
format
mshafer-NI 5e38cf3
fix terminology
mshafer-NI 558c935
move lint errors_parser in with linter utils
mshafer-NI 9c24309
update more occurances
mshafer-NI dc5c5a0
correct call
mshafer-NI 7b4a57c
dog-food the fix command
mshafer-NI fa4179a
fix another reference
mshafer-NI 77da803
document public api
mshafer-NI 1a6e878
remove broken import
mshafer-NI 4efba7e
fix indentation
mshafer-NI e0a9534
flip the indentation
mshafer-NI 12eebc3
remove some unused imports
mshafer-NI 622c82a
fix imports
mshafer-NI b5ddf54
update tests
mshafer-NI 9c458ca
handle merge differences
mshafer-NI 76ccc16
make the diff smaller
mshafer-NI 0256d6f
fix reference to get lint output
mshafer-NI 17c3807
flip that back around
mshafer-NI c9b989f
fix more references
mshafer-NI 53c8f73
fix ni-python-styleguide linter errors
mshafer-NI dd9cfff
update tests
mshafer-NI c6b6d42
remove it from the input
mshafer-NI 6ad06a4
fix verbage
mshafer-NI 2c0d20d
remove unsupported argument
mshafer-NI File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| import fileinput | ||
| import logging | ||
| import pathlib | ||
| from collections import defaultdict | ||
| from fnmatch import fnmatch | ||
| from typing import List | ||
|
|
||
| import isort | ||
|
|
||
| from ni_python_styleguide import _acknowledge_existing_errors | ||
| from ni_python_styleguide import _format | ||
| from ni_python_styleguide import _utils | ||
|
|
||
| _module_logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def _split_imports_line(lines: str, *_, **__): | ||
| r"""Split multi-import lines to multiple lines. | ||
|
|
||
| >>> _split_imports_line("import os, collections\n") | ||
| 'import os\nimport collections\n' | ||
|
|
||
| >>> _split_imports_line("import os\n") | ||
| 'import os\n' | ||
|
|
||
| >>> _split_imports_line("from ni_python_styleguide import" | ||
| ... " _acknowledge_existing_errors, _format") | ||
| 'from ni_python_styleguide import _acknowledge_existing_errors\nfrom ni_python_styleguide import _format\n' | ||
|
|
||
| >>> _split_imports_line("from ni_python_styleguide import _acknowledge_existing_errors") | ||
| 'from ni_python_styleguide import _acknowledge_existing_errors\n' | ||
|
|
||
| >>> _split_imports_line("import os, collections\nimport pathlib") | ||
| 'import os\nimport collections\nimport pathlib\n' | ||
|
|
||
| >>> _split_imports_line("import os, collections\nimport pathlib, os") | ||
| 'import os\nimport collections\nimport pathlib\nimport os\n' | ||
|
|
||
| >>> _split_imports_line("\n") | ||
| '\n' | ||
| """ # noqa W505: long lines... | ||
| result_parts = [] | ||
| for line in lines.splitlines(keepends=True): | ||
| code_portion_of_line, *non_code = line.split("#", maxsplit=1) | ||
| first, _, rest = code_portion_of_line.partition(",") | ||
| if not all( | ||
| [ | ||
| rest, | ||
| "import " in code_portion_of_line, | ||
| code_portion_of_line.strip().startswith("import ") | ||
| or code_portion_of_line.strip().startswith("from "), | ||
| ] | ||
| ): | ||
| result_parts.append(code_portion_of_line) | ||
| continue | ||
| prefix, first = " ".join(first.split()[:-1]), first.split()[-1] | ||
| split_up = [first] + rest.split(",") | ||
| result_parts.extend([prefix + " " + part.strip() for part in split_up]) | ||
| suffix = "" | ||
| if non_code: | ||
| suffix = "#" + "".join(non_code) | ||
| result = "\n".join(result_parts) + suffix | ||
| if result.strip(): | ||
| return result.rstrip() + "\n" | ||
| return result | ||
|
|
||
|
|
||
| def _sort_imports(file: pathlib.Path, app_import_names): | ||
| raw = file.read_text() | ||
| output = isort.code( | ||
| raw, | ||
| multi_line_output=3, | ||
| line_length=1, | ||
| known_first_party=filter(None, app_import_names.split(",")), | ||
| ) | ||
| file.write_text(output) | ||
|
|
||
|
|
||
| def _handle_multiple_import_lines(bad_file: pathlib.Path): | ||
| multiline_string_checker = _utils.string_helpers.InMultiLineStringChecker( | ||
| lines=bad_file.read_text(encoding=_utils.DEFAULT_ENCODING).splitlines() | ||
| ) | ||
| with fileinput.FileInput(files=[str(bad_file)], inplace=True) as f: | ||
| for line_no, line in enumerate(f): | ||
| working_line = line | ||
| if multiline_string_checker.in_multiline_string(line_no + 1): | ||
| print(working_line, end="") | ||
| continue | ||
| working_line = _split_imports_line(working_line) | ||
| print(working_line, end="") | ||
|
|
||
|
|
||
| def fix( | ||
| exclude: str, | ||
| app_import_names: str, | ||
| extend_ignore, | ||
| file_or_dir, | ||
| *_, | ||
| aggressive=False, | ||
| ): | ||
| """Fix basic linter errors and format.""" | ||
| file_or_dir = file_or_dir or ["."] | ||
| if aggressive: | ||
| all_files = [] | ||
| for file_or_dir_ in file_or_dir: | ||
| file_path = pathlib.Path(file_or_dir_) | ||
| if file_path.is_dir(): | ||
| all_files.extend(file_path.rglob("*.py")) | ||
| else: | ||
| all_files.append(file_path) | ||
| all_files = filter( | ||
| lambda o: not any([fnmatch(o, exclude_) for exclude_ in exclude.split(",")]), all_files | ||
| ) | ||
| for file in all_files: | ||
| if not file.is_file(): # doesn't really exist... | ||
| continue | ||
| _acknowledge_existing_errors.remove_auto_suppressions_from_file(file) | ||
| lint_errors_to_process = _acknowledge_existing_errors._utils.lint.get_errors_to_process( | ||
| exclude, | ||
| app_import_names, | ||
| extend_ignore, | ||
| [pathlib.Path(file_or_dir_) for file_or_dir_ in file_or_dir], | ||
| excluded_errors=[], # we fix black errors, so we don't need to filter it. | ||
| ) | ||
|
|
||
| lint_errors_by_file = defaultdict(list) | ||
| for error in lint_errors_to_process: | ||
| lint_errors_by_file[pathlib.Path(error.file)].append(error) | ||
|
|
||
| failed_files = [] | ||
| for bad_file, errors_in_file in lint_errors_by_file.items(): | ||
| errors_in_file: List[_utils.lint.LintError] | ||
| try: | ||
| _format.format(bad_file) | ||
| line_to_codes_mapping = defaultdict(set) | ||
| for error in errors_in_file: | ||
| # humans talk 1-based, enumerate is 0-based | ||
| line_to_codes_mapping[int(error.line) - 1].add(error.code) | ||
| _sort_imports(bad_file, app_import_names=app_import_names) | ||
| _format.format(bad_file, "--line-length=300") # condense any split lines | ||
| _handle_multiple_import_lines(bad_file) | ||
| _format.format(bad_file) | ||
| remaining_lint_errors_in_file = _utils.lint.get_errors_to_process( | ||
| exclude, | ||
| app_import_names, | ||
| extend_ignore, | ||
| [bad_file], | ||
| excluded_errors=[], | ||
| ) | ||
| if remaining_lint_errors_in_file and aggressive: | ||
| _acknowledge_existing_errors.acknowledge_lint_errors( | ||
| exclude=exclude, | ||
| app_import_names=app_import_names, | ||
| extend_ignore=extend_ignore, | ||
| aggressive=aggressive, | ||
| file_or_dir=[bad_file], | ||
| errors_in_file=remaining_lint_errors_in_file, | ||
| ) | ||
| except AttributeError as e: | ||
| failed_files.append((bad_file, e)) | ||
| if failed_files: | ||
| raise Exception( | ||
| "Failed to format files:\n" | ||
| + "\n".join([f"{file}: {error}" for file, error in failed_files]) | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.