-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement mkdocs key from v2 config #4486
Conversation
I will wait until the base PR gets merged to review this. |
Base PR is merged, care to rebase this? |
I'm rebasing this now |
8ad9594
to
fe5de39
Compare
1cb4d95
to
7892ec3
Compare
I had to use an empty commit, travis wasn't being executed, even forcing the push :/ |
I'll be testing this with a couple of mkdocs projects and see how it goes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I realize that we use the doctype
from the api and resolver, we don't have a config object there. We need to figure out how to pass the doctype there.
- We can save the config as metadata in each version
- We can save only the doctype in each version
- We can write some values to a file as we do to detect an old environment.
@@ -470,10 +470,6 @@ def run_build(self, docker, record): | |||
|
|||
# Environment used for building code, usually with Docker | |||
with self.build_env: | |||
|
|||
if self.project.documentation_type == 'auto': | |||
self.update_documentation_type() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I move this logic to the save method of the project model
readthedocs/projects/tasks.py
Outdated
|
||
# Web tasks | ||
@app.task(queue='web') | ||
def sync_files(project_pk, version_pk, hostname=None, html=False, | ||
def sync_files(project_pk, version_pk, config, hostname=None, html=False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need the current doctype, so I'm passing it to all tasks
Search tests are failing, but before fixing them, I'd like to resolve #4486 (review) |
@@ -198,6 +199,8 @@ def build(self): | |||
'--site-dir', self.build_dir, | |||
'--config-file', self.yaml_file, | |||
] | |||
if self.config.mkdocs.fail_on_warning: | |||
build_command.append('--strict') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I'd let users configure this in their mkdocs.yml
rather than adding an extra Read the Docs option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm +1 for this, I didn't know about that, Sphinx doesn't have something like that (I mean, using the conf.py file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could define setup()
function in conf.py
and override config.warningiserror = True
and I think it should work.
We can use https://docs.djangoproject.com/en/1.9/ref/contrib/postgres/fields/#jsonfield to store metadata on the build/version object. |
We can't use the |
So, what I think:
I prefer 1), as we can save all the metadata used to build the docs, and query that data (like show the exact configuration used to build the docs). One downside is that we need to figure out how to make it work on development with sqlite. Edit: We can use https://pypi.org/project/jsonfield/ or https://pypi.org/project/django-jsonfield/ if we want to keep the code database agnostic. Or maybe recommend using docker to new contributors (time to setup a docker-compose environment for dev?). |
a8db61a
to
463f879
Compare
9ddbb78
to
ff1a8df
Compare
@@ -236,7 +236,7 @@ def install_core_requirements(self): | |||
'recommonmark==0.4.0', | |||
] | |||
|
|||
if self.project.documentation_type == 'mkdocs': | |||
if self.config.doctype == 'mkdocs': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm leaving the doctype access in some places where we always use the config object, it doesn't break anything anyway. Just keeping the same pattern.
80e3904
to
b0d23a6
Compare
@@ -138,7 +138,7 @@ def __init__(self, env_config, raw_config, source_file, source_position): | |||
def error(self, key, message, code): | |||
"""Raise an error related to ``key``.""" | |||
source = '{file} [{pos}]'.format( | |||
file=self.source_file, | |||
file=os.path.relpath(self.source_file, self.base_path), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were showing the full path here (/rtd/builds/...)
@@ -566,6 +573,8 @@ def validate(self): | |||
self.validate_doc_types() | |||
self._config['mkdocs'] = self.validate_mkdocs() | |||
self._config['sphinx'] = self.validate_sphinx() | |||
# TODO: remove later | |||
self.validate_final_doc_type() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to remove this later #4638 (there is a note with the commit there)
def is_type_mkdocs(self): | ||
"""Is project type Mkdocs.""" | ||
return 'mkdocs' in self.documentation_type | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing these is a first step to deprecate Project.doctype
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted a couple small changes, but i think this looks good otherwise!
readthedocs/config/config.py
Outdated
self.error( | ||
key, | ||
'Your documentation type should match ' | ||
'the one from the admin panel of your project.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: "project admin dashboard" instead of "admin panel of your panel"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, perhaps instead mention the expected value here?
"Your project is configured as '{ project.documentation_type }' in your project admin dashboard, but there was no "sphinx" key specified in the configuration."
Something like that
@@ -1333,6 +1336,7 @@ def test_sphinx_builder_default(self): | |||
build.validate() | |||
build.sphinx.builder == 'sphinx' | |||
|
|||
@pytest.mark.skip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this skipped?
Perhaps we should get in the habit of code commenting why a test is xfail, skip, etc. Or i think you can do:
@pytest.mark.skip("Skipped because ...")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tests are incompatible with the new behavior of checking the same doctype, all those changes are part of #4638 (comment)
self.project.save() | ||
|
||
update_docs = self.get_update_docs_task() | ||
update_docs.build_docs_html() | ||
|
||
get_builder_class.assert_called_with(result) | ||
|
||
@pytest.mark.skip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another spot to note why we're skipping
@agjohnson done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last update on the error copy and I think we're good to merge.
readthedocs/config/config.py
Outdated
'Your documentation type should match ' | ||
'the one from the admin panel of your project.', | ||
'Your project is configured as "{doctype}" in your admin ' | ||
'dashboard, but there was a "{key}" key specified.'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last nitpick. The error is sort of inverted i feel -- we don't actually tell the user the they need a "sphinx" key, just that they can't have a "mkdocs" key. I feel we need to be clearer here, ie:
Your project is configured as "Sphinx" in your project admin dashboard, but there is no "sphinx" key specified.
Also, for some of the odd documentation types, it looks like we're putting the slug in there, so:
Your project is configured as "sphinx_htmldir" ...
I feel like we want the verbose name instead. This shouldn't be a huge change, just using the model field to resolve the verbose name, but if it is a large change, it's not horribly important. This piece is temporary and it's probably close enough for most users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm, I'm not sure about accessing the db from the config module (we don't do that there). I'm changing the error message.
@agjohnson done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the last fix wasn't correct.
readthedocs/config/config.py
Outdated
) | ||
self.error( | ||
key, | ||
'Your project is configured as "{doctype}" in your admin ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doctype
here is the interpolation that could be displayed as sphinx_htmldir
. key
in this string can only be sphinx
or mkdocs
.
readthedocs/config/config.py
Outdated
'Your project is configured as "{doctype}" in your admin ' | ||
'dashboard, but there is no "{key}" key specified.'.format( | ||
doctype=dashboard_doctype, | ||
key=needed_doctype, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you meant was:
doctype=needed_doctype,
key=key,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was on purpose, as we say that the project is configured as sphinx_htmldir
in the admin dashboard, and the user is missing a sphinx
key in their config file.
key
represents the current doctype from the config file.
Dashboard -> sphinx
Config -> mkdocs
Error: Your project is configured as "sphinx" in your admin dashboard, but there is no "sphinx" key specified.
The key is used to indicate where is the error something like File, key: error message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, in the previous example, key would be mkdocs
We can put the key as .
if that's looks confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we need the dashboard_doctype, otherwise we will have some weird errors like:
Dashboard -> sphinx_htmldir
Config -> sphinx.html
Your project is configured as "sphinx" in your admin dashboard, but there is no "sphinx" key specified
The current message for this case looks like:
Your project is configured as "sphinx_htmldir" in your admin dashboard, but there is no "sphinx" key specified
Isn't perfect neither... but better than the above p:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about Your project is configured as "sphinx_htmldir" in your admin dashboard, it doesn't match the documentation type from the configuration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't perfect neither... but better than the above p:
Exposing our internal slug to users isn't great UX, so i actually prefer the first. I wanted to originally use the verbose option name, but this is maybe annoying to get from the choice list -- for example, if i was using the model, i'd use the get_documentation_type_display()
automatic function.
The _get_FIELD_display
method is very small, we can likely replicate it very easily:
https://github.com/django/django/blob/cc79c7ee637e65c8da27e56d746c87903d5ec901/django/db/models/base.py#L902-L904
That way, we give the user an error that matches what the user sees in our admin, not what we see in our database. So, ideally:
Your project is configured as Sphinx HTMLdir in your admin dashboard,
but there is no "sphinx" key specified
readthedocs/config/config.py
Outdated
'sphinx': 'Sphinx Html', | ||
'sphinx_htmldir': 'Sphinx HtmlDir', | ||
'sphinx_singlehtml': 'Sphinx Single Page HTML', | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to bring these from the db, as the config module is isolated from the other rtd code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably -1 on maintaining this in the config module separately. Was this to ensure we could move the config module out of rtd core?
I'd say either rely on the model field choices to report messages like ".. your project is configured as Sphinx HTMLdir", or skip all mentions of the Sphinx builder. I think what I was trying to describe in an earlier review was that we should skip mentioning the exact builder entirely if this complicates things too much (which seems like it is).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that was the reason. I think we can pair haha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry! More review on the error reporting. I think I might have suggested changes that complicate this PR further. If it helps to pair on this really quick, let me know!
readthedocs/config/config.py
Outdated
'sphinx': 'Sphinx Html', | ||
'sphinx_htmldir': 'Sphinx HtmlDir', | ||
'sphinx_singlehtml': 'Sphinx Single Page HTML', | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably -1 on maintaining this in the config module separately. Was this to ensure we could move the config module out of rtd core?
I'd say either rely on the model field choices to report messages like ".. your project is configured as Sphinx HTMLdir", or skip all mentions of the Sphinx builder. I think what I was trying to describe in an earlier review was that we should skip mentioning the exact builder entirely if this complicates things too much (which seems like it is).
readthedocs/config/config.py
Outdated
code=INVALID_KEYS_COMBINATION, | ||
) | ||
error_msg = ( | ||
'Your project is configured as "{}" in your admin dashboard.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message shouldn't end with a period, it results in two sentence fragments:
Your project is configured as "Mkdocs" in your admin dashboard. But there is no "mkdocs" key specified.
It would be better as:
... in your admin, but there is no ..
readthedocs/config/config.py
Outdated
'mkdocs' if dashboard_doctype == 'mkdocs' else 'sphinx' | ||
) | ||
else: | ||
error_msg += ' But your "sphinx.builder" key does not match.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're no longer catching the case where the user has no sphinx key at all. I still think this needs to be a separate check on top of checking if there is a sphinx
key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check for no sphinx key is above
Thanks for repeatedly taking my nitpick abuse! 🙂 Looks good! |
No worries, I'm a nitpick person too haha |
I miss something here. I understood that you said that we were returning |
This is on top of #4482, it should be merged after.
New changes are from 3f311ef
Ref #4219