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

Add --required-version #2238

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/configuration/options.md
Expand Up @@ -1651,6 +1651,19 @@ Displays the currently installed version of isort.

`isort --version`

## Required Version

Require a specific version of isort to be running. This is useful for ensuring that all contributors to your project are using the same version, because different versions of isort may format code a little differently. This option can be set in a configuration file for consistent results across environments.

**Type:** String
**Default:** ` `
**Config default:** ` `
**Python & Config File Name:** required_version
**CLI Flags:**

- --rv
- --required-version

## Version Number

Returns just the current version number without the logo
Expand Down
24 changes: 24 additions & 0 deletions isort/main.py
@@ -1,4 +1,5 @@
"""Tool for sorting imports alphabetically, and automatically separated into sections."""

import argparse
import functools
import json
Expand Down Expand Up @@ -164,6 +165,18 @@ def _build_arg_parser() -> argparse.ArgumentParser:
dest="show_version",
help="Displays the currently installed version of isort.",
)
general_group.add_argument(
"--rv",
"--required-version",
default="",
dest="required_version",
type=str,
help="Require a specific version of isort to be running. This is useful for"
" ensuring that all contributors to your project are using the same"
" version, because different versions of isort may format code a little"
" differently. This option can be set in a configuration file for consistent"
" results across environments.",
)
general_group.add_argument(
"--vn",
"--version-number",
Expand Down Expand Up @@ -1124,6 +1137,17 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] =
if show_config:
print(json.dumps(config.__dict__, indent=4, separators=(",", ": "), default=_preconvert))
return

if (
config.required_version
and config.required_version != __version__
and config.required_version != __version__.split(".")[0]
):
sys.exit(
f"Error: the required version `{config.required_version}` does not match the running"
f" version `{__version__}`!"
)

if file_names == ["-"]:
file_path = Path(stream_filename) if stream_filename else None
if show_files:
Expand Down
5 changes: 3 additions & 2 deletions isort/settings.py
Expand Up @@ -145,6 +145,7 @@ class _Config:
"""

py_version: str = "3"
required_version: str = ""
force_to_top: FrozenSet[str] = frozenset()
skip: FrozenSet[str] = DEFAULT_SKIP
extend_skip: FrozenSet[str] = frozenset()
Expand Down Expand Up @@ -553,8 +554,8 @@ def is_supported_filetype(self, file_name: str) -> bool:
line = fp.readline(100)
except OSError:
return False
else:
return bool(_SHEBANG_RE.match(line))

return bool(_SHEBANG_RE.match(line))

def _check_folder_git_ls_files(self, folder: str) -> Optional[Path]:
env = {**os.environ, "LANG": "C.UTF-8"}
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/test_main.py
Expand Up @@ -103,6 +103,46 @@ def test_ascii_art(capsys):
assert error == ""


def test_required_version_matches_version(capsys, tmpdir):
python_file = tmpdir.join("file.py")
python_file.write("import os")

main.main(["--required-version", __version__, str(python_file)])
out, error = capsys.readouterr()
assert out == ""
assert error == ""


def test_required_version_matches_partial_version(capsys, tmpdir):
python_file = tmpdir.join("file.py")
python_file.write("import os")

main.main(["--required-version", __version__.split(".")[0], str(python_file)])
out, error = capsys.readouterr()
assert out == ""
assert error == ""


def test_required_version_does_not_match_on_minor_version(tmpdir):
python_file = tmpdir.join("file.py")
python_file.write("import os")

required_version = __version__.split(".")[0] + ".999"
error_msg = f"Error: the required version `{required_version}` does not match the running version `{__version__}`!"
with pytest.raises(SystemExit, match=error_msg):
main.main(["--required-version", required_version, str(python_file)])


def test_required_version_does_not_match_version(tmpdir):
python_file = tmpdir.join("file.py")
python_file.write("import os")

required_version = "0.13.2b"
error_msg = f"Error: the required version `{required_version}` does not match the running version `{__version__}`!"
with pytest.raises(SystemExit, match=error_msg):
main.main(["--required-version", required_version, str(python_file)])


def test_preconvert():
assert main._preconvert(frozenset([1, 1, 2])) == [1, 2]
assert main._preconvert(WrapModes.GRID) == "GRID"
Expand Down