mirror of https://github.com/pypa/hatch.git
970 lines
33 KiB
Python
970 lines
33 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from hatch.config.constants import ConfigEnvVars
|
|
from hatch.project.core import Project
|
|
|
|
|
|
def construct_ruff_defaults_file(rules: tuple[str, ...]) -> str:
|
|
from hatch.cli.fmt.core import PER_FILE_IGNORED_RULES
|
|
|
|
lines = [
|
|
'line-length = 120',
|
|
'',
|
|
'[format]',
|
|
'docstring-code-format = true',
|
|
'docstring-code-line-length = 80',
|
|
'',
|
|
'[lint]',
|
|
]
|
|
|
|
# Selected rules
|
|
lines.append('select = [')
|
|
lines.extend(f' "{rule}",' for rule in sorted(rules))
|
|
lines.extend((']', ''))
|
|
|
|
# Ignored rules
|
|
lines.append('[lint.per-file-ignores]')
|
|
for glob, ignored_rules in PER_FILE_IGNORED_RULES.items():
|
|
lines.append(f'"{glob}" = [')
|
|
lines.extend(f' "{ignored_rule}",' for ignored_rule in ignored_rules)
|
|
lines.append(']')
|
|
|
|
# Default config
|
|
lines.extend((
|
|
'',
|
|
'[lint.flake8-tidy-imports]',
|
|
'ban-relative-imports = "all"',
|
|
'',
|
|
'[lint.isort]',
|
|
'known-first-party = ["my_app"]',
|
|
'',
|
|
'[lint.flake8-pytest-style]',
|
|
'fixture-parentheses = false',
|
|
'mark-parentheses = false',
|
|
))
|
|
|
|
# Ensure the file ends with a newline to satisfy other linters
|
|
lines.append('')
|
|
|
|
return '\n'.join(lines)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def defaults_file_stable() -> str:
|
|
from hatch.cli.fmt.core import STABLE_RULES
|
|
|
|
return construct_ruff_defaults_file(STABLE_RULES)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def defaults_file_preview() -> str:
|
|
from hatch.cli.fmt.core import PREVIEW_RULES, STABLE_RULES
|
|
|
|
return construct_ruff_defaults_file(STABLE_RULES + PREVIEW_RULES)
|
|
|
|
|
|
class TestDefaults:
|
|
def test_fix(self, hatch, helpers, temp_dir, config_file, env_run, mocker, platform, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
config_dir = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config' / project_path.id
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
cmd [1] | ruff check --config {user_config_path} --fix .
|
|
cmd [2] | ruff format --config {user_config_path} .
|
|
"""
|
|
)
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} --fix .', shell=True),
|
|
mocker.call(f'ruff format --config {user_config_path} .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_stable
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
def test_check(self, hatch, helpers, temp_dir, config_file, env_run, mocker, platform, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
config_dir = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config' / project_path.id
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--check')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
cmd [1] | ruff check --config {user_config_path} .
|
|
cmd [2] | ruff format --config {user_config_path} --check --diff .
|
|
"""
|
|
)
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} .', shell=True),
|
|
mocker.call(f'ruff format --config {user_config_path} --check --diff .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_stable
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
def test_existing_config(
|
|
self, hatch, helpers, temp_dir, config_file, env_run, mocker, platform, defaults_file_stable
|
|
):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
config_dir = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config' / project_path.id
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
project_file = project_path / 'pyproject.toml'
|
|
old_contents = project_file.read_text()
|
|
project_file.write_text(f'[tool.ruff]\n{old_contents}')
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--check')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
cmd [1] | ruff check --config {user_config_path} .
|
|
cmd [2] | ruff format --config {user_config_path} --check --diff .
|
|
"""
|
|
)
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} .', shell=True),
|
|
mocker.call(f'ruff format --config {user_config_path} --check --diff .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_stable
|
|
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
[tool.ruff]
|
|
extend = "{config_path}\"
|
|
{old_contents.rstrip()}"""
|
|
)
|
|
|
|
|
|
class TestPreview:
|
|
def test_fix_flag(self, hatch, helpers, temp_dir, config_file, env_run, mocker, platform, defaults_file_preview):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
config_dir = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config' / project_path.id
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--preview')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
cmd [1] | ruff check --config {user_config_path} --preview --fix .
|
|
cmd [2] | ruff format --config {user_config_path} --preview .
|
|
"""
|
|
)
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} --preview --fix .', shell=True),
|
|
mocker.call(f'ruff format --config {user_config_path} --preview .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_preview
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
def test_check_flag(self, hatch, helpers, temp_dir, config_file, env_run, mocker, platform, defaults_file_preview):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
config_dir = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config' / project_path.id
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--check', '--preview')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
cmd [1] | ruff check --config {user_config_path} --preview .
|
|
cmd [2] | ruff format --config {user_config_path} --preview --check --diff .
|
|
"""
|
|
)
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} --preview .', shell=True),
|
|
mocker.call(f'ruff format --config {user_config_path} --preview --check --diff .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_preview
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
|
|
class TestComponents:
|
|
def test_only_linter(self, hatch, temp_dir, config_file, env_run, mocker, platform, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--linter')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert not result.output
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
config_dir = next(root_data_path.iterdir())
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} --fix .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_stable
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
def test_only_formatter(self, hatch, temp_dir, config_file, env_run, mocker, platform, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--formatter')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert not result.output
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
config_dir = next(root_data_path.iterdir())
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff format --config {user_config_path} .', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_stable
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
@pytest.mark.usefixtures('env_run')
|
|
def test_select_multiple(self, hatch, helpers, temp_dir, config_file):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--linter', '--formatter')
|
|
|
|
assert result.exit_code == 1, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Cannot specify both --linter and --formatter
|
|
"""
|
|
)
|
|
|
|
|
|
class TestArguments:
|
|
def test_forwarding(self, hatch, helpers, temp_dir, config_file, env_run, mocker, platform, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
config_dir = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config' / project_path.id
|
|
default_config = config_dir / 'ruff_defaults.toml'
|
|
user_config = config_dir / 'pyproject.toml'
|
|
user_config_path = platform.join_command_args([str(user_config)])
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--', '--foo', 'bar')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
cmd [1] | ruff check --config {user_config_path} --fix --foo bar
|
|
cmd [2] | ruff format --config {user_config_path} --foo bar
|
|
"""
|
|
)
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call(f'ruff check --config {user_config_path} --fix --foo bar', shell=True),
|
|
mocker.call(f'ruff format --config {user_config_path} --foo bar', shell=True),
|
|
]
|
|
|
|
assert default_config.read_text() == defaults_file_stable
|
|
|
|
old_contents = (project_path / 'pyproject.toml').read_text()
|
|
config_path = str(default_config).replace('\\', '\\\\')
|
|
assert (
|
|
user_config.read_text()
|
|
== f"""\
|
|
{old_contents}
|
|
[tool.ruff]
|
|
extend = "{config_path}\""""
|
|
)
|
|
|
|
|
|
class TestConfigPath:
|
|
@pytest.mark.usefixtures('env_run')
|
|
def test_sync_without_config(self, hatch, helpers, temp_dir, config_file):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--sync')
|
|
|
|
assert result.exit_code == 1, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
The --sync flag can only be used when the `tool.hatch.format.config-path` option is defined
|
|
"""
|
|
)
|
|
|
|
def test_sync(self, hatch, helpers, temp_dir, config_file, env_run, mocker, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
default_config_file = project_path / 'ruff_defaults.toml'
|
|
assert not default_config_file.is_file()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {'hatch-static-analysis': {'config-path': 'ruff_defaults.toml'}}
|
|
config['tool']['ruff'] = {'extend': 'ruff_defaults.toml'}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--sync')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
cmd [1] | ruff check --fix .
|
|
cmd [2] | ruff format .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('ruff check --fix .', shell=True),
|
|
mocker.call('ruff format .', shell=True),
|
|
]
|
|
|
|
assert default_config_file.read_text() == defaults_file_stable
|
|
|
|
def test_no_sync(self, hatch, helpers, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
default_config_file = project_path / 'ruff_defaults.toml'
|
|
default_config_file.touch()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {'hatch-static-analysis': {'config-path': 'ruff_defaults.toml'}}
|
|
config['tool']['ruff'] = {'extend': 'ruff_defaults.toml'}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
cmd [1] | ruff check --fix .
|
|
cmd [2] | ruff format .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('ruff check --fix .', shell=True),
|
|
mocker.call('ruff format .', shell=True),
|
|
]
|
|
|
|
assert not default_config_file.read_text()
|
|
|
|
def test_sync_legacy_config(self, hatch, helpers, temp_dir, config_file, env_run, mocker, defaults_file_stable):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
default_config_file = project_path / 'ruff_defaults.toml'
|
|
assert not default_config_file.is_file()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['format'] = {'config-path': 'ruff_defaults.toml'}
|
|
config['tool']['ruff'] = {'extend': 'ruff_defaults.toml'}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--sync')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
The `tool.hatch.format.config-path` option is deprecated and will be removed in a future release. Use `tool.hatch.envs.hatch-static-analysis.config-path` instead.
|
|
cmd [1] | ruff check --fix .
|
|
cmd [2] | ruff format .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('ruff check --fix .', shell=True),
|
|
mocker.call('ruff format .', shell=True),
|
|
]
|
|
|
|
assert default_config_file.read_text() == defaults_file_stable
|
|
|
|
|
|
class TestCustomScripts:
|
|
def test_only_linter_fix(self, hatch, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {
|
|
'hatch-static-analysis': {
|
|
'config-path': 'none',
|
|
'dependencies': ['black', 'flake8', 'isort'],
|
|
'scripts': {
|
|
'format-check': [
|
|
'black --check --diff {args:.}',
|
|
'isort --check-only --diff {args:.}',
|
|
],
|
|
'format-fix': [
|
|
'isort {args:.}',
|
|
'black {args:.}',
|
|
],
|
|
'lint-check': 'flake8 {args:.}',
|
|
'lint-fix': 'lint-check',
|
|
},
|
|
}
|
|
}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--linter')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert not result.output
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('flake8 .', shell=True),
|
|
]
|
|
|
|
def test_only_linter_check(self, hatch, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {
|
|
'hatch-static-analysis': {
|
|
'config-path': 'none',
|
|
'dependencies': ['black', 'flake8', 'isort'],
|
|
'scripts': {
|
|
'format-check': [
|
|
'black --check --diff {args:.}',
|
|
'isort --check-only --diff {args:.}',
|
|
],
|
|
'format-fix': [
|
|
'isort {args:.}',
|
|
'black {args:.}',
|
|
],
|
|
'lint-check': 'flake8 {args:.}',
|
|
'lint-fix': 'lint-check',
|
|
},
|
|
}
|
|
}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--check', '--linter')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert not result.output
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('flake8 .', shell=True),
|
|
]
|
|
|
|
def test_only_formatter_fix(self, hatch, helpers, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {
|
|
'hatch-static-analysis': {
|
|
'config-path': 'none',
|
|
'dependencies': ['black', 'flake8', 'isort'],
|
|
'scripts': {
|
|
'format-check': [
|
|
'black --check --diff {args:.}',
|
|
'isort --check-only --diff {args:.}',
|
|
],
|
|
'format-fix': [
|
|
'isort {args:.}',
|
|
'black {args:.}',
|
|
],
|
|
'lint-check': 'flake8 {args:.}',
|
|
'lint-fix': 'lint-check',
|
|
},
|
|
}
|
|
}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--formatter')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
cmd [1] | isort .
|
|
cmd [2] | black .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('isort .', shell=True),
|
|
mocker.call('black .', shell=True),
|
|
]
|
|
|
|
def test_only_formatter_check(self, hatch, helpers, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {
|
|
'hatch-static-analysis': {
|
|
'config-path': 'none',
|
|
'dependencies': ['black', 'flake8', 'isort'],
|
|
'scripts': {
|
|
'format-check': [
|
|
'black --check --diff {args:.}',
|
|
'isort --check-only --diff {args:.}',
|
|
],
|
|
'format-fix': [
|
|
'isort {args:.}',
|
|
'black {args:.}',
|
|
],
|
|
'lint-check': 'flake8 {args:.}',
|
|
'lint-fix': 'lint-check',
|
|
},
|
|
}
|
|
}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--check', '--formatter')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
cmd [1] | black --check --diff .
|
|
cmd [2] | isort --check-only --diff .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('black --check --diff .', shell=True),
|
|
mocker.call('isort --check-only --diff .', shell=True),
|
|
]
|
|
|
|
def test_fix(self, hatch, helpers, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {
|
|
'hatch-static-analysis': {
|
|
'config-path': 'none',
|
|
'dependencies': ['black', 'flake8', 'isort'],
|
|
'scripts': {
|
|
'format-check': [
|
|
'black --check --diff {args:.}',
|
|
'isort --check-only --diff {args:.}',
|
|
],
|
|
'format-fix': [
|
|
'isort {args:.}',
|
|
'black {args:.}',
|
|
],
|
|
'lint-check': 'flake8 {args:.}',
|
|
'lint-fix': 'lint-check',
|
|
},
|
|
}
|
|
}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
cmd [1] | flake8 .
|
|
cmd [2] | isort .
|
|
cmd [3] | black .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('flake8 .', shell=True),
|
|
mocker.call('isort .', shell=True),
|
|
mocker.call('black .', shell=True),
|
|
]
|
|
|
|
def test_check(self, hatch, helpers, temp_dir, config_file, env_run, mocker):
|
|
config_file.model.template.plugins['default']['tests'] = False
|
|
config_file.save()
|
|
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
|
|
assert result.exit_code == 0, result.output
|
|
|
|
project_path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(project_path)
|
|
config = dict(project.raw_config)
|
|
config['tool']['hatch']['envs'] = {
|
|
'hatch-static-analysis': {
|
|
'config-path': 'none',
|
|
'dependencies': ['black', 'flake8', 'isort'],
|
|
'scripts': {
|
|
'format-check': [
|
|
'black --check --diff {args:.}',
|
|
'isort --check-only --diff {args:.}',
|
|
],
|
|
'format-fix': [
|
|
'isort {args:.}',
|
|
'black {args:.}',
|
|
],
|
|
'lint-check': 'flake8 {args:.}',
|
|
'lint-fix': 'lint-check',
|
|
},
|
|
}
|
|
}
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('fmt', '--check')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
cmd [1] | flake8 .
|
|
cmd [2] | black --check --diff .
|
|
cmd [3] | isort --check-only --diff .
|
|
"""
|
|
)
|
|
|
|
root_data_path = data_path / 'env' / '.internal' / 'hatch-static-analysis' / '.config'
|
|
assert not root_data_path.is_dir()
|
|
|
|
assert env_run.call_args_list == [
|
|
mocker.call('flake8 .', shell=True),
|
|
mocker.call('black --check --diff .', shell=True),
|
|
mocker.call('isort --check-only --diff .', shell=True),
|
|
]
|