def default(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig(get_env_config(), {}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate() assert build.build_image == 'readthedocs/build:2.0'
def test_config_requires_type(): build = BuildConfig({'output_base': ''}, {'name': 'docs'}, source_file='readthedocs.yml', source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'type' assert excinfo.value.code == TYPE_REQUIRED
def test_build_requires_valid_name(): build = BuildConfig({'output_base': ''}, {'name': 'with/slashes'}, source_file='readthedocs.yml', source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'name' assert excinfo.value.code == NAME_INVALID
def default(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( get_env_config(), {}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate() assert build.build_image == 'readthedocs/build:2.0'
def it_validates_to_abspath(tmpdir): apply_fs(tmpdir, {'configs': minimal_config, 'docs': {}}) with tmpdir.as_cwd(): source_file = str(tmpdir.join('configs', 'readthedocs.yml')) build = BuildConfig(get_env_config(), {'base': '../docs'}, source_file=source_file, source_position=0) build.validate() assert build.base == str(tmpdir.join('docs'))
def it_works(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( get_env_config(), {'build': {'image': 'latest'}}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate() assert build.build_image == 'readthedocs/build:latest'
def it_works(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig(get_env_config(), {'build': { 'image': 'latest' }}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate() assert build.build_image == 'readthedocs/build:latest'
def it_fails_if_base_does_not_exist(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig(get_env_config(), {'base': 'docs'}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'base' assert excinfo.value.code == INVALID_PATH
def test_config_requires_type(): build = BuildConfig( {'output_base': ''}, {'name': 'docs'}, source_file='readthedocs.yml', source_position=0 ) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'type' assert excinfo.value.code == TYPE_REQUIRED
def test_build_requires_valid_name(): build = BuildConfig( {'output_base': ''}, {'name': 'with/slashes'}, source_file='readthedocs.yml', source_position=0 ) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'name' assert excinfo.value.code == NAME_INVALID
def it_validates_to_abspath(tmpdir): apply_fs(tmpdir, {'configs': minimal_config, 'docs': {}}) with tmpdir.as_cwd(): source_file = str(tmpdir.join('configs', 'readthedocs.yml')) build = BuildConfig( get_env_config(), {'base': '../docs'}, source_file=source_file, source_position=0) build.validate() assert build.base == str(tmpdir.join('docs'))
def it_fails_if_build_is_invalid_option(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( get_env_config(), {'build': {'image': 3.0}}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'build' assert excinfo.value.code == INVALID_CHOICE
def it_fails_if_base_does_not_exist(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( get_env_config(), {'base': 'docs'}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'base' assert excinfo.value.code == INVALID_PATH
def test_build_requires_valid_type(): build = BuildConfig({'output_base': ''}, { 'name': 'docs', 'type': 'unknown' }, source_file='readthedocs.yml', source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'type' assert excinfo.value.code == INVALID_CHOICE
def test_build_requires_valid_type(): build = BuildConfig( {'output_base': ''}, {'name': 'docs', 'type': 'unknown'}, source_file='readthedocs.yml', source_position=0 ) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'type' assert excinfo.value.code == INVALID_CHOICE
def it_fails_if_build_is_invalid_option(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig(get_env_config(), {'build': { 'image': 3.0 }}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'build' assert excinfo.value.code == INVALID_CHOICE
def it_fails_if_base_is_not_a_string(tmpdir): apply_fs(tmpdir, minimal_config) with tmpdir.as_cwd(): build = BuildConfig(get_env_config(), {'base': 1}, source_file=str( tmpdir.join('readthedocs.yml')), source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'base' assert excinfo.value.code == INVALID_STRING
def it_fails_if_base_is_not_a_string(tmpdir): apply_fs(tmpdir, minimal_config) with tmpdir.as_cwd(): build = BuildConfig( get_env_config(), {'base': 1}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with raises(InvalidConfig) as excinfo: build.validate() assert excinfo.value.key == 'base' assert excinfo.value.code == INVALID_STRING
def test_valid_build_config(): build = BuildConfig(env_config, minimal_config, source_file='readthedocs.yml', source_position=0) build.validate() assert build.name == 'docs' assert build.type == 'sphinx' assert build.base assert build.python assert 'setup_py_install' in build.python assert 'use_system_site_packages' in build.python assert build.output_base
def it_priorities_image_from_env_config(tmpdir, image): apply_fs(tmpdir, minimal_config) defaults = { 'build_image': image, } build = BuildConfig( get_env_config({'defaults': defaults}), {'build': {'image': 'latest'}}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0 ) build.validate() assert build.build_image == image
def it_priorities_image_from_env_config(tmpdir, image): apply_fs(tmpdir, minimal_config) defaults = { 'build_image': image, } build = BuildConfig(get_env_config({'defaults': defaults}), {'build': { 'image': 'latest' }}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate() assert build.build_image == image
def test_build_validate_calls_all_subvalidators(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig({}, {}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with patch.multiple(BuildConfig, validate_base=DEFAULT, validate_name=DEFAULT, validate_type=DEFAULT, validate_python=DEFAULT, validate_output_base=DEFAULT): build.validate() BuildConfig.validate_base.assert_called_with() BuildConfig.validate_name.assert_called_with() BuildConfig.validate_type.assert_called_with() BuildConfig.validate_python.assert_called_with() BuildConfig.validate_output_base.assert_called_with()
def test_build_validate_calls_all_subvalidators(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( {}, {}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) with patch.multiple(BuildConfig, validate_base=DEFAULT, validate_name=DEFAULT, validate_type=DEFAULT, validate_python=DEFAULT, validate_output_base=DEFAULT): build.validate() BuildConfig.validate_base.assert_called_with() BuildConfig.validate_name.assert_called_with() BuildConfig.validate_type.assert_called_with() BuildConfig.validate_python.assert_called_with() BuildConfig.validate_output_base.assert_called_with()
def load_yaml_config(version): """ Load a configuration from `readthedocs.yml` file. This uses the configuration logic from `readthedocs-build`, which will keep parsing consistent between projects. """ checkout_path = version.project.checkout_path(version.slug) project = version.project # Get build image to set up the python version validation. Pass in the # build image python limitations to the loaded config so that the versions # can be rejected at validation img_name = project.container_image or DOCKER_IMAGE python_version = 3 if project.python_interpreter == 'python3' else 2 env_config = { 'build': { 'image': img_name, }, 'defaults': { 'install_project': project.install_project, 'formats': get_default_formats(project), 'use_system_packages': project.use_system_packages, 'requirements_file': project.requirements_file, 'python_version': python_version, 'build_image': project.container_image, } } img_settings = DOCKER_IMAGE_SETTINGS.get(img_name, None) if img_settings: env_config.update(img_settings) env_config['DOCKER_IMAGE_SETTINGS'] = img_settings try: sphinx_env_config = env_config.copy() sphinx_env_config.update({ 'output_base': '', 'type': 'sphinx', 'name': version.slug, }) config = load_config( path=checkout_path, env_config=sphinx_env_config, )[0] except InvalidConfig: # This is a subclass of ConfigError, so has to come first raise except ConfigError: # TODO: this shouldn't be hardcoded here env_config.update({ 'output_base': '', 'type': 'sphinx', 'name': version.slug, }) config = BuildConfig( env_config=env_config, raw_config={}, source_file=path.join(checkout_path, 'empty'), source_position=0, ) config.validate() return config
def load_yaml_config(version): """ Load a configuration from `readthedocs.yml` file. This uses the configuration logic from `readthedocs-build`, which will keep parsing consistent between projects. """ checkout_path = version.project.checkout_path(version.slug) project = version.project # Get build image to set up the python version validation. Pass in the # build image python limitations to the loaded config so that the versions # can be rejected at validation img_name = project.container_image or DOCKER_IMAGE python_version = 3 if project.python_interpreter == 'python3' else 2 env_config = { 'build': { 'image': img_name, }, 'defaults': { 'install_project': project.install_project, 'formats': get_default_formats(project), 'use_system_packages': project.use_system_packages, 'requirements_file': project.requirements_file, 'python_version': python_version, 'build_image': project.container_image, } } img_settings = DOCKER_IMAGE_SETTINGS.get(img_name, None) if img_settings: env_config.update(img_settings) env_config['DOCKER_IMAGE_SETTINGS'] = img_settings try: sphinx_env_config = env_config.copy() sphinx_env_config.update({ 'output_base': '', 'type': 'sphinx', 'name': version.slug, }) config = load_config( path=checkout_path, env_config=sphinx_env_config, )[0] except InvalidConfig: # This is a subclass of ConfigError, so has to come first raise except ConfigError: # TODO: this shouldn't be hardcoded here env_config.update({ 'output_base': '', 'type': 'sphinx', 'name': version.slug, }) config = BuildConfig( env_config=env_config, raw_config={}, source_file='empty', source_position=0, ) config.validate() return config