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 default(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig({}, {}, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate_build() assert build['build']['image'] == 'readthedocs/build:2.0'
def test_build_requires_valid_type(): build = BuildConfig({}, {'type': 'unknown'}, source_file=None, source_position=None) with raises(InvalidConfig) as excinfo: build.validate_type() assert excinfo.value.key == 'type' assert excinfo.value.code == INVALID_CHOICE
def test_config_requires_type(): build = BuildConfig({}, {'name': 'docs'}, source_file=None, source_position=None) with raises(InvalidConfig) as excinfo: build.validate_type() 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 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({}, {'name': 'with/slashes'}, source_file=None, source_position=None) with raises(InvalidConfig) as excinfo: build.validate_name() assert excinfo.value.key == 'name' assert excinfo.value.code == NAME_INVALID
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 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_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_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 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 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 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_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_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 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_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_works_on_python_validation(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( {}, { 'build': {'image': 'latest'}, 'python': {'version': '3.3'}, }, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate_build() build.validate_python()
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_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 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_fails_on_python_validation(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig( {}, { 'build': {'image': 1.0}, 'python': {'version': '3.3'}, }, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate_build() with raises(InvalidConfig) as excinfo: build.validate_python() assert excinfo.value.key == 'python.version' assert excinfo.value.code == INVALID_CHOICE
def test_project_set_output_base(): project = ProjectConfig([ BuildConfig(env_config, minimal_config, source_file='readthedocs.yml', source_position=0), BuildConfig(env_config, minimal_config, source_file='readthedocs.yml', source_position=1), ]) project.set_output_base('random') for build_config in project: assert (build_config['output_base'] == os.path.join( os.getcwd(), 'random'))
def get_build_config(config, env_config=None, source_file='readthedocs.yml', source_position=0): return BuildConfig(env_config or {}, config, source_file=source_file, source_position=source_position)
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_validate_project_config(): with patch.object(BuildConfig, 'validate') as build_validate: project = ProjectConfig([ BuildConfig(env_config, minimal_config, source_file='readthedocs.yml', source_position=0) ]) project.validate() assert build_validate.call_count == 1
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 inner(path=None, env_config=None): env_config_defaults = { 'output_base': '', 'name': '1', 'type': 'sphinx', } if env_config is not None: env_config_defaults.update(env_config) yaml_config = ProjectConfig([ BuildConfig(env_config_defaults, config, source_file='readthedocs.yml', source_position=0) ]) yaml_config.validate() return yaml_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) # 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 = version.project.container_image or DOCKER_IMAGE env_config = { 'build': { 'image': img_name, } } 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: config = BuildConfig( env_config=env_config, raw_config={}, source_file='empty', source_position=0, ) return ConfigWrapper(version=version, yaml_config=config)
def it_works_on_python_validation(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig({}, { 'build': { 'image': 'latest' }, 'python': { 'version': '3.3' }, }, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate_build() build.validate_python()
def it_fails_on_python_validation(tmpdir): apply_fs(tmpdir, minimal_config) build = BuildConfig({}, { 'build': { 'image': 1.0 }, 'python': { 'version': '3.3' }, }, source_file=str(tmpdir.join('readthedocs.yml')), source_position=0) build.validate_build() with raises(InvalidConfig) as excinfo: build.validate_python() assert excinfo.value.key == 'python.version' assert excinfo.value.code == INVALID_CHOICE
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