From 7dd4b654c13a2c0dcd3cee1239f161132391d1f7 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Tue, 2 Oct 2018 12:47:50 -0500 Subject: [PATCH 1/3] Test --- readthedocs/config/tests/test_config.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readthedocs/config/tests/test_config.py b/readthedocs/config/tests/test_config.py index e2bfc37bf46..3c12223bcc8 100644 --- a/readthedocs/config/tests/test_config.py +++ b/readthedocs/config/tests/test_config.py @@ -834,6 +834,14 @@ def test_version(self): build = self.get_build_config({}) assert build.version == '2' + def test_correct_error_when_source_is_dir(self, tmpdir): + build = self.get_build_config({}, source_file=str(tmpdir)) + with raises(InvalidConfig) as excinfo: + build.error(key='key', message='Message', code='code') + # We don't have any extra information about + # the source_file. + assert str(excinfo.value) == 'Invalid "key": Message' + def test_formats_check_valid(self): build = self.get_build_config({'formats': ['htmlzip', 'pdf', 'epub']}) build.validate() From eb35dc4352fa0826c0248c6788e7a81402507e7b Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Tue, 2 Oct 2018 12:51:10 -0500 Subject: [PATCH 2/3] Allow source_file to be a dict --- readthedocs/config/config.py | 47 +++++++++++++++++++------------ readthedocs/doc_builder/config.py | 2 +- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/readthedocs/config/config.py b/readthedocs/config/config.py index eb718df1b4e..b7f807519c5 100644 --- a/readthedocs/config/config.py +++ b/readthedocs/config/config.py @@ -135,25 +135,40 @@ class BuildConfigBase(object): version = None def __init__(self, env_config, raw_config, source_file, source_position): + """ + :param env_config: A dict that cointains additional information + about the environment. + :param raw_config: A dict with all configuration without validation. + :param source_file: The file that contains the configuration. + All paths are relative to this file. + If a dir is given, the configuration was loaded + from another source (like the web admin). + """ self.env_config = env_config self.raw_config = raw_config self.source_file = source_file self.source_position = source_position - self.base_path = os.path.dirname(self.source_file) + if os.path.isdir(self.source_file): + self.base_path = self.source_file + else: + self.base_path = os.path.dirname(self.source_file) self.defaults = self.env_config.get('defaults', {}) self._config = {} def error(self, key, message, code): """Raise an error related to ``key``.""" - source = '{file} [{pos}]'.format( - file=os.path.relpath(self.source_file, self.base_path), - pos=self.source_position, - ) - error_message = '{source}: {message}'.format( - source=source, - message=message, - ) + if not os.path.isdir(self.source_file): + source = '{file} [{pos}]'.format( + file=os.path.relpath(self.source_file, self.base_path), + pos=self.source_position, + ) + error_message = '{source}: {message}'.format( + source=source, + message=message, + ) + else: + error_message = message raise InvalidConfig( key=key, code=code, @@ -271,10 +286,9 @@ def validate_output_base(self): """Validates that ``output_base`` exists and set its absolute path.""" assert 'output_base' in self.env_config, ( '"output_base" required in "env_config"') - base_path = os.path.dirname(self.source_file) output_base = os.path.abspath( os.path.join( - self.env_config.get('output_base', base_path), + self.env_config.get('output_base', self.base_path), ) ) return output_base @@ -302,10 +316,9 @@ def validate_base(self): if 'base' in self.raw_config: base = self.raw_config['base'] else: - base = os.path.dirname(self.source_file) + base = self.base_path with self.catch_validation_error('base'): - base_path = os.path.dirname(self.source_file) - base = validate_directory(base, base_path) + base = validate_directory(base, self.base_path) return base def validate_build(self): @@ -452,9 +465,8 @@ def validate_conda(self): conda_environment = None if 'file' in raw_conda: with self.catch_validation_error('conda.file'): - base_path = os.path.dirname(self.source_file) conda_environment = validate_file( - raw_conda['file'], base_path + raw_conda['file'], self.base_path ) conda['environment'] = conda_environment @@ -469,9 +481,8 @@ def validate_requirements_file(self): requirements_file = self.raw_config['requirements_file'] if not requirements_file: return None - base_path = os.path.dirname(self.source_file) with self.catch_validation_error('requirements_file'): - validate_file(requirements_file, base_path) + validate_file(requirements_file, self.base_path) return requirements_file def validate_formats(self): diff --git a/readthedocs/doc_builder/config.py b/readthedocs/doc_builder/config.py index 9d714af604f..8620082ad3e 100644 --- a/readthedocs/doc_builder/config.py +++ b/readthedocs/doc_builder/config.py @@ -73,7 +73,7 @@ def load_yaml_config(version): config = BuildConfigV1( env_config=env_config, raw_config={}, - source_file=path.join(checkout_path, 'empty'), + source_file=checkout_path, source_position=0, ) config.validate() From 5f2c8b119e4496404bf34fb846789ec97ef8ea61 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Tue, 2 Oct 2018 13:51:13 -0500 Subject: [PATCH 3/3] Move docstrings --- readthedocs/config/config.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/readthedocs/config/config.py b/readthedocs/config/config.py index b7f807519c5..dfcb30ce0cd 100644 --- a/readthedocs/config/config.py +++ b/readthedocs/config/config.py @@ -128,22 +128,22 @@ class BuildConfigBase(object): """ Config that handles the build of one particular documentation. - You need to call ``validate`` before the config is ready to use. Also - setting the ``output_base`` is required before using it for a build. + .. note:: + + You need to call ``validate`` before the config is ready to use. + + :param env_config: A dict that cointains additional information + about the environment. + :param raw_config: A dict with all configuration without validation. + :param source_file: The file that contains the configuration. + All paths are relative to this file. + If a dir is given, the configuration was loaded + from another source (like the web admin). """ version = None def __init__(self, env_config, raw_config, source_file, source_position): - """ - :param env_config: A dict that cointains additional information - about the environment. - :param raw_config: A dict with all configuration without validation. - :param source_file: The file that contains the configuration. - All paths are relative to this file. - If a dir is given, the configuration was loaded - from another source (like the web admin). - """ self.env_config = env_config self.raw_config = raw_config self.source_file = source_file