mirror of https://github.com/pypa/hatch.git
420 lines
13 KiB
Python
420 lines
13 KiB
Python
import os
|
|
|
|
import pytest
|
|
|
|
from hatch.config.constants import ConfigEnvVars
|
|
from hatch.project.core import Project
|
|
from hatchling.utils.constants import DEFAULT_CONFIG_FILE
|
|
|
|
pytestmark = [pytest.mark.usefixtures('mock_backend_process_output')]
|
|
|
|
|
|
def read_readme(project_dir):
|
|
return repr((project_dir / 'README.txt').read_text())[1:-1]
|
|
|
|
|
|
def test_other_backend(hatch, temp_dir, helpers):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
(path / 'README.md').replace(path / 'README.txt')
|
|
|
|
project = Project(path)
|
|
config = dict(project.raw_config)
|
|
config['build-system']['requires'] = ['flit-core']
|
|
config['build-system']['build-backend'] = 'flit_core.buildapi'
|
|
config['project']['version'] = '0.0.1'
|
|
config['project']['dynamic'] = []
|
|
config['project']['readme'] = 'README.txt'
|
|
del config['project']['license']
|
|
project.save_config(config)
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
{{
|
|
"name": "my-app",
|
|
"version": "0.0.1",
|
|
"readme": {{
|
|
"content-type": "text/plain",
|
|
"text": "{read_readme(path)}\\n"
|
|
}},
|
|
"keywords": [
|
|
""
|
|
],
|
|
"classifiers": [
|
|
"Development Status :: 4 - Beta",
|
|
"Programming Language :: Python",
|
|
"Programming Language :: Python :: 3.8",
|
|
"Programming Language :: Python :: 3.9",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
"Programming Language :: Python :: Implementation :: PyPy"
|
|
],
|
|
"urls": {{
|
|
"Documentation": "https://github.com/Foo Bar/my-app#readme",
|
|
"Issues": "https://github.com/Foo Bar/my-app/issues",
|
|
"Source": "https://github.com/Foo Bar/my-app"
|
|
}},
|
|
"authors": [
|
|
{{
|
|
"email": "foo@bar.baz",
|
|
"name": "Foo Bar"
|
|
}}
|
|
],
|
|
"requires-python": ">=3.8"
|
|
}}
|
|
"""
|
|
)
|
|
|
|
|
|
def test_default_all(hatch, temp_dir, helpers):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
(path / 'README.md').replace(path / 'README.txt')
|
|
|
|
project = Project(path)
|
|
config = dict(project.raw_config)
|
|
config['project']['readme'] = 'README.txt'
|
|
project.save_config(config)
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
{{
|
|
"name": "my-app",
|
|
"version": "0.0.1",
|
|
"readme": {{
|
|
"content-type": "text/plain",
|
|
"text": "{read_readme(path)}"
|
|
}},
|
|
"requires-python": ">=3.8",
|
|
"license": "MIT",
|
|
"authors": [
|
|
{{
|
|
"name": "Foo Bar",
|
|
"email": "foo@bar.baz"
|
|
}}
|
|
],
|
|
"classifiers": [
|
|
"Development Status :: 4 - Beta",
|
|
"Programming Language :: Python",
|
|
"Programming Language :: Python :: 3.8",
|
|
"Programming Language :: Python :: 3.9",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
"Programming Language :: Python :: Implementation :: PyPy"
|
|
],
|
|
"urls": {{
|
|
"Documentation": "https://github.com/Foo Bar/my-app#readme",
|
|
"Issues": "https://github.com/Foo Bar/my-app/issues",
|
|
"Source": "https://github.com/Foo Bar/my-app"
|
|
}}
|
|
}}
|
|
"""
|
|
)
|
|
|
|
|
|
def test_field_readme(hatch, temp_dir):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
(path / 'README.md').replace(path / 'README.txt')
|
|
|
|
project = Project(path)
|
|
config = dict(project.raw_config)
|
|
config['project']['readme'] = 'README.txt'
|
|
project.save_config(config)
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata', 'readme')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == (
|
|
f"""\
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
{(path / 'README.txt').read_text()}
|
|
"""
|
|
)
|
|
|
|
|
|
def test_field_string(hatch, temp_dir, helpers):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata', 'license')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
MIT
|
|
"""
|
|
)
|
|
|
|
|
|
def test_field_complex(hatch, temp_dir, helpers):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata', 'urls')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
{
|
|
"Documentation": "https://github.com/Foo Bar/my-app#readme",
|
|
"Issues": "https://github.com/Foo Bar/my-app/issues",
|
|
"Source": "https://github.com/Foo Bar/my-app"
|
|
}
|
|
"""
|
|
)
|
|
|
|
|
|
@pytest.mark.allow_backend_process
|
|
def test_incompatible_environment(hatch, temp_dir, helpers, build_env_config):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
project = Project(path)
|
|
helpers.update_project_environment(project, 'hatch-build', {'python': '9000', **build_env_config})
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata')
|
|
|
|
assert result.exit_code == 1, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Environment `hatch-build` is incompatible: cannot locate Python: 9000
|
|
"""
|
|
)
|
|
|
|
|
|
def test_plugin_dependencies_unmet(hatch, temp_dir, helpers, mock_plugin_installation):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
dependency = os.urandom(16).hex()
|
|
(path / DEFAULT_CONFIG_FILE).write_text(
|
|
helpers.dedent(
|
|
f"""
|
|
[env]
|
|
requires = ["{dependency}"]
|
|
"""
|
|
)
|
|
)
|
|
|
|
(path / 'README.md').replace(path / 'README.txt')
|
|
|
|
project = Project(path)
|
|
config = dict(project.raw_config)
|
|
config['project']['readme'] = 'README.txt'
|
|
project.save_config(config)
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
f"""
|
|
Syncing environment plugin requirements
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
{{
|
|
"name": "my-app",
|
|
"version": "0.0.1",
|
|
"readme": {{
|
|
"content-type": "text/plain",
|
|
"text": "{read_readme(path)}"
|
|
}},
|
|
"requires-python": ">=3.8",
|
|
"license": "MIT",
|
|
"authors": [
|
|
{{
|
|
"name": "Foo Bar",
|
|
"email": "foo@bar.baz"
|
|
}}
|
|
],
|
|
"classifiers": [
|
|
"Development Status :: 4 - Beta",
|
|
"Programming Language :: Python",
|
|
"Programming Language :: Python :: 3.8",
|
|
"Programming Language :: Python :: 3.9",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
"Programming Language :: Python :: Implementation :: PyPy"
|
|
],
|
|
"urls": {{
|
|
"Documentation": "https://github.com/Foo Bar/my-app#readme",
|
|
"Issues": "https://github.com/Foo Bar/my-app/issues",
|
|
"Source": "https://github.com/Foo Bar/my-app"
|
|
}}
|
|
}}
|
|
"""
|
|
)
|
|
helpers.assert_plugin_installation(mock_plugin_installation, [dependency])
|
|
|
|
|
|
def test_build_dependencies_unmet(hatch, temp_dir, helpers):
|
|
project_name = 'My.App'
|
|
|
|
with temp_dir.as_cwd():
|
|
result = hatch('new', project_name)
|
|
assert result.exit_code == 0, result.output
|
|
|
|
path = temp_dir / 'my-app'
|
|
data_path = temp_dir / 'data'
|
|
data_path.mkdir()
|
|
|
|
(path / 'README.md').replace(path / 'README.txt')
|
|
|
|
project = Project(path)
|
|
config = dict(project.raw_config)
|
|
config['project']['readme'] = 'README.txt'
|
|
config['tool']['hatch']['build'] = {'dependencies': ['binary']}
|
|
project.save_config(config)
|
|
|
|
with path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata', 'license')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
Syncing dependencies
|
|
MIT
|
|
"""
|
|
)
|
|
|
|
|
|
@pytest.mark.allow_backend_process
|
|
@pytest.mark.requires_internet
|
|
def test_no_compatibility_check_if_exists(hatch, temp_dir, helpers, mocker):
|
|
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['build-system']['requires'].append('binary')
|
|
project.save_config(config)
|
|
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata', 'license')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Creating environment: hatch-build
|
|
Checking dependencies
|
|
Syncing dependencies
|
|
Inspecting build dependencies
|
|
MIT
|
|
"""
|
|
)
|
|
|
|
mocker.patch('hatch.env.virtual.VirtualEnvironment.check_compatibility', side_effect=Exception('incompatible'))
|
|
with project_path.as_cwd(env_vars={ConfigEnvVars.DATA: str(data_path)}):
|
|
result = hatch('project', 'metadata', 'license')
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert result.output == helpers.dedent(
|
|
"""
|
|
Inspecting build dependencies
|
|
MIT
|
|
"""
|
|
)
|