diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 457f22dba7c..bfd4916206d 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -117,7 +117,13 @@ def install_core_requirements(self): """Install basic Read the Docs requirements into the virtualenv.""" requirements = [ 'Pygments==2.2.0', - 'setuptools==28.8.0', + # Assume semver for setuptools version, support up to next backwards + # incompatible release + self.project.get_feature_value( + Feature.USE_SETUPTOOLS_LATEST, + positive='setuptools<37', + negative='setuptools==28.8.0', + ), 'docutils==0.13.1', 'mock==1.0.1', 'pillow==2.6.1', @@ -129,13 +135,14 @@ def install_core_requirements(self): if self.project.documentation_type == 'mkdocs': requirements.append('mkdocs==0.15.0') else: - if self.project.has_feature(Feature.USE_SPHINX_LATEST): - # We will assume semver here and only automate up to the next - # backward incompatible release: 2.x - requirements.append('sphinx<2') - else: - requirements.append('sphinx==1.5.6') + # We will assume semver here and only automate up to the next + # backward incompatible release: 2.x requirements.extend([ + self.project.get_feature_value( + Feature.USE_SPHINX_LATEST, + positive='sphinx<2', + negative='sphinx==1.5.6', + ), 'sphinx-rtd-theme<0.3', 'readthedocs-sphinx-ext<0.6' ]) diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index 86a63937d22..068c3622675 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -835,6 +835,14 @@ def has_feature(self, feature_id): """ return self.features.filter(feature_id=feature_id).exists() + def get_feature_value(self, feature, positive, negative): + """Look up project feature, return corresponding value + + If a project has a feature, return ``positive``, otherwise return + ``negative`` + """ + return positive if self.has_feature(feature) else negative + class APIProject(Project): @@ -994,9 +1002,11 @@ def add_features(sender, **kwargs): # Feature constants - this is not a exhaustive list of features, features # may be added by other packages USE_SPHINX_LATEST = 'use_sphinx_latest' + USE_SETUPTOOLS_LATEST = 'use_setuptools_latest' FEATURES = ( (USE_SPHINX_LATEST, _('Use latest version of Sphinx')), + (USE_SETUPTOOLS_LATEST, _('Use latest version of setuptools')), ) projects = models.ManyToManyField(