mirror of https://github.com/pypa/hatch.git
2948 lines
120 KiB
Python
2948 lines
120 KiB
Python
from itertools import product
|
|
|
|
import pytest
|
|
|
|
from hatch.plugin.constants import DEFAULT_CUSTOM_SCRIPT
|
|
from hatch.plugin.manager import PluginManager
|
|
from hatch.project.config import ProjectConfig
|
|
from hatch.project.constants import DEFAULT_BUILD_DIRECTORY, BuildEnvVars
|
|
from hatch.project.env import RESERVED_OPTIONS
|
|
from hatch.utils.structures import EnvVars
|
|
|
|
ARRAY_OPTIONS = [o for o, t in RESERVED_OPTIONS.items() if t is list]
|
|
BOOLEAN_OPTIONS = [o for o, t in RESERVED_OPTIONS.items() if t is bool]
|
|
MAPPING_OPTIONS = [o for o, t in RESERVED_OPTIONS.items() if t is dict]
|
|
STRING_OPTIONS = [o for o, t in RESERVED_OPTIONS.items() if t is str and o != 'matrix-name-format']
|
|
|
|
|
|
def construct_matrix_data(env_name, config, overrides=None):
|
|
config = dict(config[env_name])
|
|
config.pop('overrides', None)
|
|
matrices = config.pop('matrix')
|
|
final_matrix_name_format = config.pop('matrix-name-format', '{value}')
|
|
|
|
# [{'version': ['9000']}, {'feature': ['bar']}]
|
|
envs = {}
|
|
for matrix_data in matrices:
|
|
matrix = dict(matrix_data)
|
|
variables = {}
|
|
python_selected = False
|
|
for variable in ('py', 'python'):
|
|
if variable in matrix:
|
|
python_selected = True
|
|
variables[variable] = matrix.pop(variable)
|
|
break
|
|
variables.update(matrix)
|
|
|
|
for result in product(*variables.values()):
|
|
variable_values = dict(zip(variables, result))
|
|
env_name_parts = []
|
|
for j, (variable, value) in enumerate(variable_values.items()):
|
|
if j == 0 and python_selected:
|
|
env_name_parts.append(value if value.startswith('py') else f'py{value}')
|
|
else:
|
|
env_name_parts.append(final_matrix_name_format.format(variable=variable, value=value))
|
|
|
|
new_env_name = '-'.join(env_name_parts)
|
|
if env_name != 'default':
|
|
new_env_name = f'{env_name}.{new_env_name}'
|
|
|
|
envs[new_env_name] = variable_values
|
|
if 'py' in variable_values:
|
|
envs[new_env_name] = {'python': variable_values.pop('py'), **variable_values}
|
|
|
|
config.update(overrides or {})
|
|
config.setdefault('type', 'virtual')
|
|
return {'config': config, 'envs': envs}
|
|
|
|
|
|
class TestEnv:
|
|
def test_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.env` must be a table'):
|
|
_ = ProjectConfig(isolation, {'env': 9000}).env
|
|
|
|
def test_default(self, isolation):
|
|
project_config = ProjectConfig(isolation, {})
|
|
|
|
assert project_config.env == project_config.env == {}
|
|
|
|
|
|
class TestEnvRequires:
|
|
def test_not_array(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.env.requires` must be an array'):
|
|
_ = ProjectConfig(isolation, {'env': {'requires': 9000}}).env_requires
|
|
|
|
def test_requirement_not_string(self, isolation):
|
|
with pytest.raises(TypeError, match='Requirement #1 in `tool.hatch.env.requires` must be a string'):
|
|
_ = ProjectConfig(isolation, {'env': {'requires': [9000]}}).env_requires
|
|
|
|
def test_requirement_invalid(self, isolation):
|
|
with pytest.raises(ValueError, match='Requirement #1 in `tool.hatch.env.requires` is invalid: .+'):
|
|
_ = ProjectConfig(isolation, {'env': {'requires': ['foo^1']}}).env_requires
|
|
|
|
def test_default(self, isolation):
|
|
project_config = ProjectConfig(isolation, {})
|
|
|
|
assert project_config.env_requires_complex == project_config.env_requires_complex == []
|
|
assert project_config.env_requires == project_config.env_requires == []
|
|
|
|
def test_defined(self, isolation):
|
|
project_config = ProjectConfig(isolation, {'env': {'requires': ['foo', 'bar', 'baz']}})
|
|
|
|
assert project_config.env_requires == ['foo', 'bar', 'baz']
|
|
|
|
|
|
class TestEnvCollectors:
|
|
def test_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.env.collectors` must be a table'):
|
|
_ = ProjectConfig(isolation, {'env': {'collectors': 9000}}).env_collectors
|
|
|
|
def test_collector_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.env.collectors.foo` must be a table'):
|
|
_ = ProjectConfig(isolation, {'env': {'collectors': {'foo': 9000}}}).env_collectors
|
|
|
|
def test_default(self, isolation):
|
|
project_config = ProjectConfig(isolation, {})
|
|
|
|
assert project_config.env_collectors == project_config.env_collectors == {'default': {}}
|
|
|
|
def test_defined(self, isolation):
|
|
project_config = ProjectConfig(isolation, {'env': {'collectors': {'foo': {'bar': {'baz': 9000}}}}})
|
|
|
|
assert project_config.env_collectors == {'default': {}, 'foo': {'bar': {'baz': 9000}}}
|
|
assert list(project_config.env_collectors) == ['default', 'foo']
|
|
|
|
|
|
class TestEnvs:
|
|
def test_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': 9000}, PluginManager()).envs
|
|
|
|
def test_config_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': 9000}}, PluginManager()).envs
|
|
|
|
def test_unknown_collector(self, isolation):
|
|
with pytest.raises(ValueError, match='Unknown environment collector: foo'):
|
|
_ = ProjectConfig(isolation, {'env': {'collectors': {'foo': {}}}}, PluginManager()).envs
|
|
|
|
def test_unknown_template(self, isolation):
|
|
with pytest.raises(
|
|
ValueError, match='Field `tool.hatch.envs.foo.template` refers to an unknown environment `bar`'
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'template': 'bar'}}}, PluginManager()).envs
|
|
|
|
def test_default_undefined(self, isolation):
|
|
project_config = ProjectConfig(isolation, {}, PluginManager())
|
|
|
|
assert project_config.envs == project_config.envs == {'default': {'type': 'virtual'}}
|
|
assert project_config.matrices == project_config.matrices == {}
|
|
|
|
def test_default_partially_defined(self, isolation):
|
|
env_config = {'default': {'option': True}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {'default': {'option': True, 'type': 'virtual'}}
|
|
|
|
def test_default_defined(self, isolation):
|
|
env_config = {'default': {'type': 'foo'}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {'default': {'type': 'foo'}}
|
|
|
|
def test_basic(self, isolation):
|
|
env_config = {'foo': {'option': True}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {'default': {'type': 'virtual'}, 'foo': {'option': True, 'type': 'virtual'}}
|
|
|
|
def test_basic_override(self, isolation):
|
|
env_config = {'foo': {'type': 'baz'}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {'default': {'type': 'virtual'}, 'foo': {'type': 'baz'}}
|
|
|
|
def test_multiple_inheritance(self, isolation):
|
|
env_config = {
|
|
'foo': {'option1': 'foo'},
|
|
'bar': {'template': 'foo', 'option2': 'bar'},
|
|
'baz': {'template': 'bar', 'option3': 'baz'},
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'option1': 'foo'},
|
|
'bar': {'type': 'virtual', 'option1': 'foo', 'option2': 'bar'},
|
|
'baz': {'type': 'virtual', 'option1': 'foo', 'option2': 'bar', 'option3': 'baz'},
|
|
}
|
|
|
|
def test_circular_inheritance(self, isolation):
|
|
with pytest.raises(
|
|
ValueError, match='Circular inheritance detected for field `tool.hatch.envs.*.template`: foo -> bar -> foo'
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation, {'envs': {'foo': {'template': 'bar'}, 'bar': {'template': 'foo'}}}, PluginManager()
|
|
).envs
|
|
|
|
def test_scripts_inheritance(self, isolation):
|
|
env_config = {
|
|
'default': {'scripts': {'cmd1': 'bar', 'cmd2': 'baz'}},
|
|
'foo': {'scripts': {'cmd1': 'foo'}},
|
|
'bar': {'template': 'foo', 'scripts': {'cmd3': 'bar'}},
|
|
'baz': {},
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {
|
|
'default': {'type': 'virtual', 'scripts': {'cmd1': 'bar', 'cmd2': 'baz'}},
|
|
'foo': {'type': 'virtual', 'scripts': {'cmd1': 'foo', 'cmd2': 'baz'}},
|
|
'bar': {'type': 'virtual', 'scripts': {'cmd1': 'foo', 'cmd2': 'baz', 'cmd3': 'bar'}},
|
|
'baz': {'type': 'virtual', 'scripts': {'cmd1': 'bar', 'cmd2': 'baz'}},
|
|
}
|
|
|
|
def test_self_referential(self, isolation):
|
|
env_config = {'default': {'option1': 'foo'}, 'bar': {'template': 'bar'}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {
|
|
'default': {'type': 'virtual', 'option1': 'foo'},
|
|
'bar': {'type': 'virtual'},
|
|
}
|
|
|
|
def test_detached(self, isolation):
|
|
env_config = {'default': {'option1': 'foo'}, 'bar': {'detached': True}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
assert project_config.envs == {
|
|
'default': {'type': 'virtual', 'option1': 'foo'},
|
|
'bar': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
def test_matrices_not_array(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.matrix` must be an array'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': 9000}}}, PluginManager()).envs
|
|
|
|
def test_matrix_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Entry #1 in field `tool.hatch.envs.foo.matrix` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [9000]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_empty(self, isolation):
|
|
with pytest.raises(ValueError, match='Matrix #1 in field `tool.hatch.envs.foo.matrix` cannot be empty'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_variable_empty_string(self, isolation):
|
|
with pytest.raises(
|
|
ValueError, match='Variable #1 in matrix #1 in field `tool.hatch.envs.foo.matrix` cannot be an empty string'
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{'': []}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_variable_not_array(self, isolation):
|
|
with pytest.raises(
|
|
TypeError, match='Variable `bar` in matrix #1 in field `tool.hatch.envs.foo.matrix` must be an array'
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{'bar': 9000}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_variable_array_empty(self, isolation):
|
|
with pytest.raises(
|
|
ValueError, match='Variable `bar` in matrix #1 in field `tool.hatch.envs.foo.matrix` cannot be empty'
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{'bar': []}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_variable_entry_not_string(self, isolation):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match='Value #1 of variable `bar` in matrix #1 in field `tool.hatch.envs.foo.matrix` must be a string',
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{'bar': [9000]}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_variable_entry_empty_string(self, isolation):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
'Value #1 of variable `bar` in matrix #1 in field `tool.hatch.envs.foo.matrix` '
|
|
'cannot be an empty string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{'bar': ['']}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_variable_entry_duplicate(self, isolation):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match='Value #2 of variable `bar` in matrix #1 in field `tool.hatch.envs.foo.matrix` is a duplicate',
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix': [{'bar': ['1', '1']}]}}}, PluginManager()).envs
|
|
|
|
def test_matrix_multiple_python_variables(self, isolation):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match='Matrix #1 in field `tool.hatch.envs.foo.matrix` cannot contain both `py` and `python` variables',
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{'envs': {'foo': {'matrix': [{'py': ['39', '310'], 'python': ['39', '311']}]}}},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
def test_matrix_name_format_not_string(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.matrix-name-format` must be a string'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix-name-format': 9000}}}, PluginManager()).envs
|
|
|
|
def test_matrix_name_format_invalid(self, isolation):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match='Field `tool.hatch.envs.foo.matrix-name-format` must contain at least the `{value}` placeholder',
|
|
):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'matrix-name-format': 'bar'}}}, PluginManager()).envs
|
|
|
|
def test_overrides_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'overrides': 9000}}}, PluginManager()).envs
|
|
|
|
def test_overrides_platform_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.platform` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'overrides': {'platform': 9000}}}}, PluginManager()).envs
|
|
|
|
def test_overrides_env_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.env` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'overrides': {'env': 9000}}}}, PluginManager()).envs
|
|
|
|
def test_overrides_matrix_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.matrix` must be a table'):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{'envs': {'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': 9000}}}},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
def test_overrides_name_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.name` must be a table'):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{'envs': {'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'name': 9000}}}},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
def test_overrides_platform_entry_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.platform.bar` must be a table'):
|
|
_ = ProjectConfig(
|
|
isolation, {'envs': {'foo': {'overrides': {'platform': {'bar': 9000}}}}}, PluginManager()
|
|
).envs
|
|
|
|
def test_overrides_env_entry_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.env.bar` must be a table'):
|
|
_ = ProjectConfig(isolation, {'envs': {'foo': {'overrides': {'env': {'bar': 9000}}}}}, PluginManager()).envs
|
|
|
|
def test_overrides_matrix_entry_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.matrix.bar` must be a table'):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{'envs': {'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'bar': 9000}}}}},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
def test_overrides_name_entry_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.envs.foo.overrides.name.bar` must be a table'):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{'envs': {'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'name': {'bar': 9000}}}}},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
def test_matrix_simple_no_python(self, isolation):
|
|
env_config = {'foo': {'option': True, 'matrix': [{'version': ['9000', '3.14']}]}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'option': True},
|
|
'foo.3.14': {'type': 'virtual', 'option': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_matrix_simple_no_python_custom_name_format(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'option': True,
|
|
'matrix-name-format': '{variable}_{value}',
|
|
'matrix': [{'version': ['9000', '3.14']}],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.version_9000': {'type': 'virtual', 'option': True},
|
|
'foo.version_3.14': {'type': 'virtual', 'option': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('indicator', ['py', 'python'])
|
|
def test_matrix_simple_only_python(self, isolation, indicator):
|
|
env_config = {'foo': {'option': True, 'matrix': [{indicator: ['39', '310']}]}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.py39': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py310': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('indicator', ['py', 'python'])
|
|
def test_matrix_simple(self, isolation, indicator):
|
|
env_config = {'foo': {'option': True, 'matrix': [{'version': ['9000', '3.14'], indicator: ['39', '310']}]}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.py39-9000': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-3.14': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py310-9000': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-3.14': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('indicator', ['py', 'python'])
|
|
def test_matrix_simple_custom_name_format(self, isolation, indicator):
|
|
env_config = {
|
|
'foo': {
|
|
'option': True,
|
|
'matrix-name-format': '{variable}_{value}',
|
|
'matrix': [{'version': ['9000', '3.14'], indicator: ['39', '310']}],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.py39-version_9000': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-version_3.14': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py310-version_9000': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-version_3.14': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_matrix_multiple_non_python(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'option': True,
|
|
'matrix': [{'version': ['9000', '3.14'], 'py': ['39', '310'], 'foo': ['baz', 'bar']}],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.py39-9000-baz': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-9000-bar': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-3.14-baz': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-3.14-bar': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py310-9000-baz': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-9000-bar': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-3.14-baz': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-3.14-bar': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_matrix_series(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'option': True,
|
|
'matrix': [
|
|
{'version': ['9000', '3.14'], 'py': ['39', '310'], 'foo': ['baz', 'bar']},
|
|
{'version': ['9000'], 'py': ['310'], 'baz': ['foo', 'test'], 'bar': ['foobar']},
|
|
],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.py39-9000-baz': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-9000-bar': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-3.14-baz': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py39-3.14-bar': {'type': 'virtual', 'option': True, 'python': '39'},
|
|
'foo.py310-9000-baz': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-9000-bar': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-3.14-baz': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-3.14-bar': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-9000-foo-foobar': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
'foo.py310-9000-test-foobar': {'type': 'virtual', 'option': True, 'python': '310'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_matrices_not_inherited(self, isolation):
|
|
env_config = {
|
|
'foo': {'option1': True, 'matrix': [{'py': ['39']}]},
|
|
'bar': {'template': 'foo', 'option2': False},
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.py39': {'type': 'virtual', 'option1': True, 'python': '39'},
|
|
'bar': {'type': 'virtual', 'option1': True, 'option2': False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_matrix_default_naming(self, isolation):
|
|
env_config = {'default': {'option': True, 'matrix': [{'version': ['9000', '3.14']}]}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'9000': {'type': 'virtual', 'option': True},
|
|
'3.14': {'type': 'virtual', 'option': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['default'] == construct_matrix_data('default', env_config)
|
|
|
|
def test_matrix_pypy_naming(self, isolation):
|
|
env_config = {'foo': {'option': True, 'matrix': [{'py': ['python3.9', 'pypy3']}]}}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.python3.9': {'type': 'virtual', 'option': True, 'python': 'python3.9'},
|
|
'foo.pypy3': {'type': 'virtual', 'option': True, 'python': 'pypy3'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=f'Field `tool.hatch.envs.foo.overrides.matrix.version.{option}` must be a string or an array',
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: 9000}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_entry_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string or an inline table'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [9000]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_table_entry_no_key(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must have an option named `key`'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: [{}]}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_table_entry_key_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `key` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_table_entry_key_empty_string(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
f'Option `key` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'cannot be an empty string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': ''}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_table_entry_value_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `value` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': 'foo', 'value': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_table_entry_if_not_array(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `if` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {
|
|
'matrix': {'version': {option: [{'key': 'foo', 'value': 'bar', 'if': 9000}]}}
|
|
},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError, match=f'Field `tool.hatch.envs.foo.overrides.matrix.version.{option}` must be an array'
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: 9000}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_entry_no_value(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must have an option named `value`'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: [{}]}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_entry_value_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `value` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_entry_value_empty_string(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
f'Option `value` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'cannot be an empty string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': ''}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_entry_if_not_array(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `if` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'foo', 'if': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_entry_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string or an inline table'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [9000]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string, inline table, or an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: 9000}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_table_no_value(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=f'Field `tool.hatch.envs.foo.overrides.matrix.version.{option}` must have an option named `value`',
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: {}}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_table_value_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=f'Option `value` in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` must be a string',
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': 9000}}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_entry_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string or an inline table'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [9000]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_no_value(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must have an option named `value`'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: [{}]}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_value_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `value` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_if_not_array(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `if` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'foo', 'if': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a boolean, inline table, or an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: 9000}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_table_no_value(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=f'Field `tool.hatch.envs.foo.overrides.matrix.version.{option}` must have an option named `value`',
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: {}}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_table_value_not_boolean(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=f'Option `value` in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` must be a boolean',
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': 9000}}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_entry_invalid_type(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a boolean or an inline table'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [9000]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_no_value(self, isolation, option):
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
f'Entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must have an option named `value`'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {'matrix': [{'version': ['9000']}], 'overrides': {'matrix': {'version': {option: [{}]}}}}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_value_not_boolean(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `value` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be a boolean'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_if_not_array(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `if` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'if': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_platform_not_array(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `platform` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'platform': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_platform_item_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Item #1 in option `platform` in entry #1 in field '
|
|
f'`tool.hatch.envs.foo.overrides.matrix.version.{option}` must be a string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'platform': [9000]}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_env_not_array(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Option `env` in entry #1 in field `tool.hatch.envs.foo.overrides.matrix.version.{option}` '
|
|
f'must be an array'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'env': 9000}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_env_item_not_string(self, isolation, option):
|
|
with pytest.raises(
|
|
TypeError,
|
|
match=(
|
|
f'Item #1 in option `env` in entry #1 in field '
|
|
f'`tool.hatch.envs.foo.overrides.matrix.version.{option}` must be a string'
|
|
),
|
|
):
|
|
_ = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'env': [9000]}]}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
).envs
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_string_with_value(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: 'FOO=ok'}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': 'ok'}},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_string_without_value(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: 'FOO'}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': '9000'}},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_string_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: {'TEST': 'baz'},
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: 'TEST'}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'TEST': '9000'}},
|
|
'foo.bar': {'type': 'virtual', option: {'TEST': 'baz'}},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_string_with_value(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: ['FOO=ok']}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': 'ok'}},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_string_without_value(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: ['FOO']}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': '9000'}},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_string_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: {'TEST': 'baz'},
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: ['TEST']}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'TEST': '9000'}},
|
|
'foo.bar': {'type': 'virtual', option: {'TEST': 'baz'}},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_table_key_with_value(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': 'FOO', 'value': 'ok'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': 'ok'}},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_table_key_without_value(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': 'FOO'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': '9000'}},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_table_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: {'TEST': 'baz'},
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': 'TEST'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'TEST': '9000'}},
|
|
'foo.bar': {'type': 'virtual', option: {'TEST': 'baz'}},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_array_table_conditional(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: {'TEST': 'baz'},
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'key': 'TEST', 'if': ['42']}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'TEST': 'baz'}},
|
|
'foo.42': {'type': 'virtual', option: {'TEST': '42'}},
|
|
'foo.bar': {'type': 'virtual', option: {'TEST': 'baz'}},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', MAPPING_OPTIONS)
|
|
def test_overrides_matrix_mapping_overwrite(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: {'TEST': 'baz'},
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {f'set-{option}': ['FOO=bar', {'key': 'BAZ'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: {'FOO': 'bar', 'BAZ': '9000'}},
|
|
'foo.bar': {'type': 'virtual', option: {'TEST': 'baz'}},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_string(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: ['run foo']}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run foo']},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_string_existing_append(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: ['run foo']}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'run foo'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run foo']},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_existing_append(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'run foo'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42']}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_platform(self, isolation, option, current_platform):
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {
|
|
'version': {option: [{'value': 'run foo', 'if': ['42'], 'platform': [current_platform]}]}
|
|
},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_wrong_platform(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42'], 'platform': ['bar']}]}},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_env_var_match(self, isolation, option):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42'], 'env': [f'{env_var}=bar']}]}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
with EnvVars({env_var: 'bar'}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_env_var_match_empty_string(self, isolation, option):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42'], 'env': [f'{env_var}=']}]}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
with EnvVars({env_var: ''}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_env_var_present(self, isolation, option):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42'], 'env': [env_var]}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz', 'run foo']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
with EnvVars({env_var: 'any'}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_env_var_no_match(self, isolation, option):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42'], 'env': [f'{env_var}=bar']}]}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
with EnvVars({env_var: 'baz'}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_table_conditional_with_env_var_missing(self, isolation, option):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {'version': {option: [{'value': 'run foo', 'if': ['42'], 'env': [f'{env_var}=bar']}]}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run baz']},
|
|
'foo.42': {'type': 'virtual', option: ['run baz']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_overrides_matrix_set_with_no_type_information(self, isolation):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'matrix': {'version': {'bar': {'value': ['baz'], 'if': ['42'], 'env': [f'{env_var}=bar']}}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual'},
|
|
'foo.42': {'type': 'virtual', 'bar': ['baz']},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
with EnvVars({env_var: 'bar'}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
def test_overrides_matrix_set_with_no_type_information_not_table(self, isolation):
|
|
project_config = ProjectConfig(
|
|
isolation,
|
|
{
|
|
'envs': {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {'bar': 9000}}},
|
|
}
|
|
}
|
|
},
|
|
PluginManager(),
|
|
)
|
|
_ = project_config.envs
|
|
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=(
|
|
'Untyped option `tool.hatch.envs.foo.9000.overrides.matrix.version.bar` '
|
|
'must be defined as a table with a `value` key'
|
|
),
|
|
):
|
|
project_config.finalize_env_overrides({})
|
|
|
|
@pytest.mark.parametrize('option', ARRAY_OPTIONS)
|
|
def test_overrides_matrix_array_overwrite(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: ['run baz'],
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {f'set-{option}': ['run foo', {'value': 'run bar'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: ['run foo', 'run bar']},
|
|
'foo.bar': {'type': 'virtual', option: ['run baz']},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_string_create(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: 'baz'}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_string_overwrite(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: 'baz'}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_table_create(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': 'baz'}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_table_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': 'baz'}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_table_conditional(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': 'baz', 'if': ['42']}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'test'},
|
|
'foo.42': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_create(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'baz'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'baz'}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_conditional(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'baz', 'if': ['42']}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'test'},
|
|
'foo.42': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_conditional_eager_string(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: ['baz', {'value': 'foo', 'if': ['42']}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'baz'},
|
|
'foo.42': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', STRING_OPTIONS)
|
|
def test_overrides_matrix_string_array_table_conditional_eager_table(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: 'test',
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': 'baz', 'if': ['42']}, 'foo']}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: 'foo'},
|
|
'foo.42': {'type': 'virtual', option: 'baz'},
|
|
'foo.bar': {'type': 'virtual', option: 'test'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_boolean_create(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: True}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_boolean_overwrite(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: True}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_table_create(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': True}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_table_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': True}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_table_conditional(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: {'value': True, 'if': ['42']}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: False},
|
|
'foo.42': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_create(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_override(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_conditional(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'if': ['42']}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: False},
|
|
'foo.42': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_conditional_eager_boolean(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [True, {'value': False, 'if': ['42']}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: True},
|
|
'foo.42': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
@pytest.mark.parametrize('option', BOOLEAN_OPTIONS)
|
|
def test_overrides_matrix_boolean_array_table_conditional_eager_table(self, isolation, option):
|
|
env_config = {
|
|
'foo': {
|
|
option: False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {option: [{'value': True, 'if': ['42']}, False]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', option: False},
|
|
'foo.42': {'type': 'virtual', option: True},
|
|
'foo.bar': {'type': 'virtual', option: False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
# We assert type coverage using matrix variable overrides, for the others just test one type
|
|
def test_overrides_platform_boolean_boolean_create(self, isolation, current_platform):
|
|
env_config = {
|
|
'foo': {
|
|
'overrides': {'platform': {'bar': {'dependencies': ['baz']}, current_platform: {'skip-install': True}}}
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_platform_boolean_boolean_overwrite(self, isolation, current_platform):
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': True,
|
|
'overrides': {
|
|
'platform': {'bar': {'dependencies': ['baz']}, current_platform: {'skip-install': False}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_platform_boolean_table_create(self, isolation, current_platform):
|
|
env_config = {
|
|
'foo': {
|
|
'overrides': {
|
|
'platform': {
|
|
'bar': {'dependencies': ['baz']},
|
|
current_platform: {'skip-install': [{'value': True}]},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_platform_boolean_table_overwrite(self, isolation, current_platform):
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': True,
|
|
'overrides': {
|
|
'platform': {
|
|
'bar': {'dependencies': ['baz']},
|
|
current_platform: {'skip-install': [{'value': False}]},
|
|
}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_env_boolean_boolean_create(self, isolation):
|
|
env_var_exists = 'OVERRIDES_ENV_FOO'
|
|
env_var_missing = 'OVERRIDES_ENV_BAR'
|
|
env_config = {
|
|
'foo': {
|
|
'overrides': {
|
|
'env': {env_var_missing: {'dependencies': ['baz']}, env_var_exists: {'skip-install': True}}
|
|
}
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
with EnvVars({env_var_exists: 'any'}):
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_env_boolean_boolean_overwrite(self, isolation):
|
|
env_var_exists = 'OVERRIDES_ENV_FOO'
|
|
env_var_missing = 'OVERRIDES_ENV_BAR'
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': True,
|
|
'overrides': {
|
|
'env': {env_var_missing: {'dependencies': ['baz']}, env_var_exists: {'skip-install': False}}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
with EnvVars({env_var_exists: 'any'}):
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_env_boolean_table_create(self, isolation):
|
|
env_var_exists = 'OVERRIDES_ENV_FOO'
|
|
env_var_missing = 'OVERRIDES_ENV_BAR'
|
|
env_config = {
|
|
'foo': {
|
|
'overrides': {
|
|
'env': {
|
|
env_var_missing: {'dependencies': ['baz']},
|
|
env_var_exists: {'skip-install': [{'value': True}]},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
with EnvVars({env_var_exists: 'any'}):
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_env_boolean_table_overwrite(self, isolation):
|
|
env_var_exists = 'OVERRIDES_ENV_FOO'
|
|
env_var_missing = 'OVERRIDES_ENV_BAR'
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': True,
|
|
'overrides': {
|
|
'env': {
|
|
env_var_missing: {'dependencies': ['baz']},
|
|
env_var_exists: {'skip-install': [{'value': False}]},
|
|
}
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
with EnvVars({env_var_exists: 'any'}):
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_env_boolean_conditional(self, isolation):
|
|
env_var_exists = 'OVERRIDES_ENV_FOO'
|
|
env_var_missing = 'OVERRIDES_ENV_BAR'
|
|
env_config = {
|
|
'foo': {
|
|
'overrides': {
|
|
'env': {
|
|
env_var_missing: {'dependencies': ['baz']},
|
|
env_var_exists: {'skip-install': [{'value': True, 'if': ['foo']}]},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
with EnvVars({env_var_exists: 'foo'}):
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_name_boolean_boolean_create(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'name': {'bar$': {'skip-install': True}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual'},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_name_boolean_boolean_overwrite(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': True,
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'name': {'bar$': {'skip-install': False}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'skip-install': True},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_name_boolean_table_create(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'name': {'bar$': {'skip-install': [{'value': True}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual'},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
def test_overrides_name_boolean_table_overwrite(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': True,
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {'name': {'bar$': {'skip-install': [{'value': False}]}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'skip-install': True},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
|
|
# Tests for source precedence
|
|
def test_overrides_name_precedence_over_matrix(self, isolation):
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'name': {'42$': {'skip-install': False}},
|
|
'matrix': {'version': {'skip-install': [{'value': True, 'if': ['42']}]}},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'skip-install': False},
|
|
'foo.42': {'type': 'virtual', 'skip-install': False},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config, {'skip-install': False})
|
|
|
|
def test_overrides_matrix_precedence_over_platform(self, isolation, current_platform):
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'platform': {current_platform: {'skip-install': True}},
|
|
'matrix': {'version': {'skip-install': [{'value': False, 'if': ['42']}]}},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'skip-install': True},
|
|
'foo.42': {'type': 'virtual', 'skip-install': False},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config, {'skip-install': True})
|
|
|
|
def test_overrides_matrix_precedence_over_env(self, isolation):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
'skip-install': False,
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'env': {env_var: {'skip-install': True}},
|
|
'matrix': {'version': {'skip-install': [{'value': False, 'if': ['42']}]}},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'skip-install': True},
|
|
'foo.42': {'type': 'virtual', 'skip-install': False},
|
|
'foo.bar': {'type': 'virtual', 'skip-install': True},
|
|
}
|
|
|
|
with EnvVars({env_var: 'any'}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config, {'skip-install': True})
|
|
|
|
def test_overrides_env_precedence_over_platform(self, isolation, current_platform):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
'overrides': {
|
|
'platform': {current_platform: {'skip-install': True}},
|
|
'env': {env_var: {'skip-install': [{'value': False, 'if': ['foo']}]}},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo': {'type': 'virtual', 'skip-install': False},
|
|
}
|
|
|
|
with EnvVars({env_var: 'foo'}):
|
|
assert project_config.envs == expected_envs
|
|
|
|
# Test for options defined by environment plugins
|
|
def test_overrides_for_environment_plugins(self, isolation, current_platform):
|
|
env_var = 'OVERRIDES_ENV_FOO'
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000']}, {'feature': ['bar']}],
|
|
'overrides': {
|
|
'platform': {current_platform: {'foo': True}},
|
|
'env': {env_var: {'bar': [{'value': 'foobar', 'if': ['foo']}]}},
|
|
'matrix': {'version': {'baz': 'BAR=ok'}},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, {'envs': env_config}, PluginManager())
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual'},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
with EnvVars({env_var: 'foo'}):
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
project_config.finalize_env_overrides({'foo': bool, 'bar': str, 'baz': dict})
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual', 'foo': True, 'bar': 'foobar', 'baz': {'BAR': 'ok'}},
|
|
'foo.bar': {'type': 'virtual', 'foo': True, 'bar': 'foobar'},
|
|
}
|
|
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
# Test environment collectors
|
|
def test_environment_collector_finalize_config(self, helpers, temp_dir):
|
|
file_path = temp_dir / DEFAULT_CUSTOM_SCRIPT
|
|
file_path.write_text(
|
|
helpers.dedent(
|
|
"""
|
|
from hatch.env.collectors.plugin.interface import EnvironmentCollectorInterface
|
|
|
|
class CustomHook(EnvironmentCollectorInterface):
|
|
def finalize_config(self, config):
|
|
config['default']['type'] = 'foo'
|
|
"""
|
|
)
|
|
)
|
|
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {'type': {'value': 'baz', 'if': ['42']}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(
|
|
temp_dir, {'envs': env_config, 'env': {'collectors': {'custom': {}}}}, PluginManager()
|
|
)
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'foo'},
|
|
'foo.9000': {'type': 'foo'},
|
|
'foo.42': {'type': 'baz'},
|
|
'foo.bar': {'type': 'foo'},
|
|
}
|
|
|
|
with temp_dir.as_cwd():
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config, {'type': 'foo'})
|
|
|
|
def test_environment_collector_finalize_environments(self, helpers, temp_dir):
|
|
file_path = temp_dir / DEFAULT_CUSTOM_SCRIPT
|
|
file_path.write_text(
|
|
helpers.dedent(
|
|
"""
|
|
from hatch.env.collectors.plugin.interface import EnvironmentCollectorInterface
|
|
|
|
class CustomHook(EnvironmentCollectorInterface):
|
|
def finalize_environments(self, config):
|
|
config['foo.42']['type'] = 'foo'
|
|
"""
|
|
)
|
|
)
|
|
|
|
env_config = {
|
|
'foo': {
|
|
'matrix': [{'version': ['9000', '42']}, {'feature': ['bar']}],
|
|
'overrides': {'matrix': {'version': {'type': {'value': 'baz', 'if': ['42']}}}},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(
|
|
temp_dir, {'envs': env_config, 'env': {'collectors': {'custom': {}}}}, PluginManager()
|
|
)
|
|
|
|
expected_envs = {
|
|
'default': {'type': 'virtual'},
|
|
'foo.9000': {'type': 'virtual'},
|
|
'foo.42': {'type': 'foo'},
|
|
'foo.bar': {'type': 'virtual'},
|
|
}
|
|
|
|
with temp_dir.as_cwd():
|
|
assert project_config.envs == expected_envs
|
|
assert project_config.matrices['foo'] == construct_matrix_data('foo', env_config)
|
|
|
|
|
|
class TestPublish:
|
|
def test_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.publish` must be a table'):
|
|
_ = ProjectConfig(isolation, {'publish': 9000}).publish
|
|
|
|
def test_config_not_table(self, isolation):
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.publish.foo` must be a table'):
|
|
_ = ProjectConfig(isolation, {'publish': {'foo': 9000}}).publish
|
|
|
|
def test_default(self, isolation):
|
|
project_config = ProjectConfig(isolation, {})
|
|
|
|
assert project_config.publish == project_config.publish == {}
|
|
|
|
def test_defined(self, isolation):
|
|
project_config = ProjectConfig(isolation, {'publish': {'foo': {'bar': 'baz'}}})
|
|
|
|
assert project_config.publish == {'foo': {'bar': 'baz'}}
|
|
|
|
|
|
class TestScripts:
|
|
def test_not_table(self, isolation):
|
|
config = {'scripts': 9000}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.scripts` must be a table'):
|
|
_ = project_config.scripts
|
|
|
|
def test_name_contains_spaces(self, isolation):
|
|
config = {'scripts': {'foo bar': []}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(
|
|
ValueError, match='Script name `foo bar` in field `tool.hatch.scripts` must not contain spaces'
|
|
):
|
|
_ = project_config.scripts
|
|
|
|
def test_default(self, isolation):
|
|
project_config = ProjectConfig(isolation, {})
|
|
|
|
assert project_config.scripts == project_config.scripts == {}
|
|
|
|
def test_single_commands(self, isolation):
|
|
config = {'scripts': {'foo': 'command1', 'bar': 'command2'}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.scripts == {'foo': ['command1'], 'bar': ['command2']}
|
|
|
|
def test_multiple_commands(self, isolation):
|
|
config = {'scripts': {'foo': 'command1', 'bar': ['command3', 'command2']}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.scripts == {'foo': ['command1'], 'bar': ['command3', 'command2']}
|
|
|
|
def test_multiple_commands_not_string(self, isolation):
|
|
config = {'scripts': {'foo': [9000]}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Command #1 in field `tool.hatch.scripts.foo` must be a string'):
|
|
_ = project_config.scripts
|
|
|
|
def test_config_invalid_type(self, isolation):
|
|
config = {'scripts': {'foo': 9000}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.scripts.foo` must be a string or an array of strings'):
|
|
_ = project_config.scripts
|
|
|
|
def test_command_expansion_basic(self, isolation):
|
|
config = {'scripts': {'foo': 'command1', 'bar': ['command3', 'foo']}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.scripts == {'foo': ['command1'], 'bar': ['command3', 'command1']}
|
|
|
|
def test_command_expansion_multiple_nested(self, isolation):
|
|
config = {
|
|
'scripts': {
|
|
'foo': 'command3',
|
|
'baz': ['command5', 'bar', 'foo', 'command1'],
|
|
'bar': ['command4', 'foo', 'command2'],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.scripts == {
|
|
'foo': ['command3'],
|
|
'baz': ['command5', 'command4', 'command3', 'command2', 'command3', 'command1'],
|
|
'bar': ['command4', 'command3', 'command2'],
|
|
}
|
|
|
|
def test_command_expansion_multiple_nested_ignore_exit_code(self, isolation):
|
|
config = {
|
|
'scripts': {
|
|
'foo': 'command3',
|
|
'baz': ['command5', '- bar', 'foo', 'command1'],
|
|
'bar': ['command4', '- foo', 'command2'],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.scripts == {
|
|
'foo': ['command3'],
|
|
'baz': ['command5', '- command4', '- command3', '- command2', 'command3', 'command1'],
|
|
'bar': ['command4', '- command3', 'command2'],
|
|
}
|
|
|
|
def test_command_expansion_modification(self, isolation):
|
|
config = {
|
|
'scripts': {
|
|
'foo': 'command3',
|
|
'baz': ['command5', 'bar world', 'foo', 'command1'],
|
|
'bar': ['command4', 'foo hello', 'command2'],
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.scripts == {
|
|
'foo': ['command3'],
|
|
'baz': ['command5', 'command4 world', 'command3 hello world', 'command2 world', 'command3', 'command1'],
|
|
'bar': ['command4', 'command3 hello', 'command2'],
|
|
}
|
|
|
|
def test_command_expansion_circular_inheritance(self, isolation):
|
|
config = {'scripts': {'foo': 'bar', 'bar': 'foo'}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(
|
|
ValueError, match='Circular expansion detected for field `tool.hatch.scripts`: foo -> bar -> foo'
|
|
):
|
|
_ = project_config.scripts
|
|
|
|
|
|
class TestBuild:
|
|
def test_not_table(self, isolation):
|
|
config = {'build': 9000}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build` must be a table'):
|
|
_ = project_config.build
|
|
|
|
def test_targets_not_table(self, isolation):
|
|
config = {'build': {'targets': 9000}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.targets` must be a table'):
|
|
_ = project_config.build.target('foo')
|
|
|
|
def test_target_not_table(self, isolation):
|
|
config = {'build': {'targets': {'foo': 9000}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.targets.foo` must be a table'):
|
|
_ = project_config.build.target('foo')
|
|
|
|
def test_directory_global_not_table(self, isolation):
|
|
config = {'build': {'directory': 9000}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.directory` must be a string'):
|
|
_ = project_config.build.target('foo').directory
|
|
|
|
def test_directory_not_table(self, isolation):
|
|
config = {'build': {'targets': {'foo': {'directory': 9000}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.targets.foo.directory` must be a string'):
|
|
_ = project_config.build.target('foo').directory
|
|
|
|
def test_directory_default(self, isolation):
|
|
project_config = ProjectConfig(isolation, {})
|
|
|
|
assert project_config.build.target('foo').directory == DEFAULT_BUILD_DIRECTORY
|
|
|
|
def test_directory_global_correct(self, isolation):
|
|
config = {'build': {'directory': 'bar'}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.build.target('foo').directory == 'bar'
|
|
|
|
def test_directory_target_override(self, isolation):
|
|
config = {'build': {'directory': 'bar', 'targets': {'foo': {'directory': 'baz'}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.build.target('foo').directory == 'baz'
|
|
|
|
def test_dependencies_global_not_array(self, isolation):
|
|
config = {'build': {'dependencies': 9000}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.dependencies` must be an array'):
|
|
_ = project_config.build.target('foo').dependencies
|
|
|
|
def test_dependencies_global_entry_not_string(self, isolation):
|
|
config = {'build': {'dependencies': [9000]}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Dependency #1 in field `tool.hatch.build.dependencies` must be a string'):
|
|
_ = project_config.build.target('foo').dependencies
|
|
|
|
def test_dependencies_not_array(self, isolation):
|
|
config = {'build': {'targets': {'foo': {'dependencies': 9000}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.targets.foo.dependencies` must be an array'):
|
|
_ = project_config.build.target('foo').dependencies
|
|
|
|
def test_dependencies_entry_not_string(self, isolation):
|
|
config = {'build': {'targets': {'foo': {'dependencies': [9000]}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(
|
|
TypeError, match='Dependency #1 in field `tool.hatch.build.targets.foo.dependencies` must be a string'
|
|
):
|
|
_ = project_config.build.target('foo').dependencies
|
|
|
|
def test_dependencies_target_merge(self, isolation):
|
|
config = {'build': {'dependencies': ['baz'], 'targets': {'foo': {'dependencies': ['bar']}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
assert project_config.build.target('foo').dependencies == ['baz', 'bar']
|
|
|
|
def test_hooks_global_not_table(self, isolation):
|
|
config = {'build': {'hooks': 9000}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.hooks` must be a table'):
|
|
_ = project_config.build.target('foo').hook_config
|
|
|
|
def test_hook_config_global_not_table(self, isolation):
|
|
config = {'build': {'hooks': {'hook1': 9000}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.hooks.hook1` must be a table'):
|
|
_ = project_config.build.target('foo').hook_config
|
|
|
|
def test_hooks_not_table(self, isolation):
|
|
config = {'build': {'targets': {'foo': {'hooks': 9000}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.targets.foo.hooks` must be a table'):
|
|
_ = project_config.build.target('foo').hook_config
|
|
|
|
def test_hook_config_not_table(self, isolation):
|
|
config = {'build': {'targets': {'foo': {'hooks': {'hook1': 9000}}}}}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with pytest.raises(TypeError, match='Field `tool.hatch.build.targets.foo.hooks.hook1` must be a table'):
|
|
_ = project_config.build.target('foo').hook_config
|
|
|
|
def test_hook_config_target_override(self, isolation):
|
|
config = {
|
|
'build': {
|
|
'hooks': {
|
|
'hook1': {'foo': 'bar', 'enable-by-default': False},
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'foo': 'bar'},
|
|
'hook4': {'foo': 'bar'},
|
|
},
|
|
'targets': {
|
|
'foo': {
|
|
'hooks': {
|
|
'hook3': {'bar': 'foo'},
|
|
'hook4': {'bar': 'foo', 'enable-by-default': False},
|
|
'hook5': {'bar': 'foo'},
|
|
'hook6': {'bar': 'foo', 'enable-by-default': False},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
hook_config = project_config.build.target('foo').hook_config
|
|
assert hook_config == {
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'bar': 'foo'},
|
|
'hook5': {'bar': 'foo'},
|
|
}
|
|
|
|
def test_hook_config_all_enabled(self, isolation):
|
|
config = {
|
|
'build': {
|
|
'hooks': {
|
|
'hook1': {'foo': 'bar', 'enable-by-default': False},
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'foo': 'bar'},
|
|
'hook4': {'foo': 'bar'},
|
|
},
|
|
'targets': {
|
|
'foo': {
|
|
'hooks': {
|
|
'hook3': {'bar': 'foo'},
|
|
'hook4': {'bar': 'foo', 'enable-by-default': False},
|
|
'hook5': {'bar': 'foo'},
|
|
'hook6': {'bar': 'foo', 'enable-by-default': False},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with EnvVars({BuildEnvVars.HOOKS_ENABLE: 'true'}):
|
|
hook_config = project_config.build.target('foo').hook_config
|
|
|
|
assert hook_config == {
|
|
'hook1': {'foo': 'bar', 'enable-by-default': False},
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'bar': 'foo'},
|
|
'hook4': {'bar': 'foo', 'enable-by-default': False},
|
|
'hook5': {'bar': 'foo'},
|
|
'hook6': {'bar': 'foo', 'enable-by-default': False},
|
|
}
|
|
|
|
def test_hook_config_all_disabled(self, isolation):
|
|
config = {
|
|
'build': {
|
|
'hooks': {
|
|
'hook1': {'foo': 'bar', 'enable-by-default': False},
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'foo': 'bar'},
|
|
'hook4': {'foo': 'bar'},
|
|
},
|
|
'targets': {
|
|
'foo': {
|
|
'hooks': {
|
|
'hook3': {'bar': 'foo'},
|
|
'hook4': {'bar': 'foo', 'enable-by-default': False},
|
|
'hook5': {'bar': 'foo'},
|
|
'hook6': {'bar': 'foo', 'enable-by-default': False},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with EnvVars({BuildEnvVars.NO_HOOKS: 'true'}):
|
|
hook_config = project_config.build.target('foo').hook_config
|
|
|
|
assert not hook_config
|
|
|
|
def test_hook_config_specific_enabled(self, isolation):
|
|
config = {
|
|
'build': {
|
|
'hooks': {
|
|
'hook1': {'foo': 'bar', 'enable-by-default': False},
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'foo': 'bar'},
|
|
'hook4': {'foo': 'bar'},
|
|
},
|
|
'targets': {
|
|
'foo': {
|
|
'hooks': {
|
|
'hook3': {'bar': 'foo'},
|
|
'hook4': {'bar': 'foo', 'enable-by-default': False},
|
|
'hook5': {'bar': 'foo'},
|
|
'hook6': {'bar': 'foo', 'enable-by-default': False},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
project_config = ProjectConfig(isolation, config)
|
|
|
|
with EnvVars({f'{BuildEnvVars.HOOK_ENABLE_PREFIX}HOOK6': 'true'}):
|
|
hook_config = project_config.build.target('foo').hook_config
|
|
|
|
assert hook_config == {
|
|
'hook2': {'foo': 'bar'},
|
|
'hook3': {'bar': 'foo'},
|
|
'hook5': {'bar': 'foo'},
|
|
'hook6': {'bar': 'foo', 'enable-by-default': False},
|
|
}
|