diff --git a/.gitignore b/.gitignore index 440756a7e4..2cc71b43c1 100644 --- a/.gitignore +++ b/.gitignore @@ -143,3 +143,10 @@ dist # Locally generated PII reports pii_report + +# Local documentation builds +docs/_build +docs/cms +docs/common +docs/lms +docs/openedx diff --git a/Makefile b/Makefile index 434ded978f..6577f677ba 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # Do things in edx-platform -.PHONY: clean extract_translations help pull pull_translations push_translations requirements shell upgrade +.PHONY: clean docs extract_translations help pull pull_translations push_translations requirements shell upgrade # Careful with mktemp syntax: it has to work on Mac and Ubuntu, which have differences. PRIVATE_FILES := $(shell mktemp -u /tmp/private_files.XXXXXX) @@ -18,6 +18,10 @@ clean: ## archive and delete most git-ignored files tar xf $(PRIVATE_FILES) rm $(PRIVATE_FILES) +docs: ## build the developer documentation for this repository + rm -rf docs/_build docs/cms docs/common docs/lms docs/openedx + cd docs; make html + extract_translations: ## extract localizable strings from sources i18n_tool extract -v diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..298ea9e213 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/cms_index.rst b/docs/cms_index.rst new file mode 100644 index 0000000000..f04caad7f1 --- /dev/null +++ b/docs/cms_index.rst @@ -0,0 +1,14 @@ +cms +*** + +The ``cms`` (course management system) directory in edx-platform is home to +the code needed for the Course Authoring Studio which is not also needed for +the LMS. + +.. toctree:: + :maxdepth: 2 + + cms/modules + cms/djangoapps/contentstore/modules + cms/djangoapps/course_creators/modules + cms/djangoapps/xblock_config/modules diff --git a/docs/common_djangoapps.rst b/docs/common_djangoapps.rst new file mode 100644 index 0000000000..071833e169 --- /dev/null +++ b/docs/common_djangoapps.rst @@ -0,0 +1,25 @@ +common/djangoapps +***************** + +This directory contains Django applications intended to be used in both the +LMS and Studio. + +.. toctree:: + :maxdepth: 2 + + common/djangoapps/course_action_state/modules + common/djangoapps/course_modes/modules + common/djangoapps/database_fixups/modules + common/djangoapps/django_comment_common/modules + common/djangoapps/edxmako/modules + common/djangoapps/enrollment/modules + common/djangoapps/entitlements/modules + common/djangoapps/microsite_configuration/modules + common/djangoapps/pipeline_mako/modules + common/djangoapps/static_replace/modules + common/djangoapps/status/modules + common/djangoapps/student/modules + common/djangoapps/third_party_auth/modules + common/djangoapps/track/modules + common/djangoapps/util/modules + common/djangoapps/xblock_django/modules diff --git a/docs/common_index.rst b/docs/common_index.rst new file mode 100644 index 0000000000..f2c6d9a7a9 --- /dev/null +++ b/docs/common_index.rst @@ -0,0 +1,14 @@ +common +****** + +The ``common`` directory in edx-platform is home to an assortment of packages +used by the LMS and Studio. This is a legacy code organization decision, and +it is currently intended that most of the code here will eventually either be +moved into the ``openedx`` package or broken out into a separately installed +package. + +.. toctree:: + :maxdepth: 2 + + common_djangoapps + common_lib diff --git a/docs/common_lib.rst b/docs/common_lib.rst new file mode 100644 index 0000000000..e761153f14 --- /dev/null +++ b/docs/common_lib.rst @@ -0,0 +1,16 @@ +common/lib +********** + +This directory contains libraries which are installed locally so they can be +imported by name with no package hierarchy. They will most likely be split +out from edx-platform into separate packages at some point. + +.. toctree:: + :maxdepth: 2 + + common/lib/calc/modules + common/lib/capa/modules + common/lib/chem/modules + common/lib/safe_lxml/modules + common/lib/symmath/modules + common/lib/xmodule/modules diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000..f20186059c --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,334 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +from __future__ import absolute_import, unicode_literals + +import datetime +import os +import sys +from subprocess import check_call + +import django +import edx_theme +import six +from path import Path + +root = Path('..').abspath() + +# Hack the PYTHONPATH to match what LMS and Studio use so all the code +# can be successfully imported +sys.path.insert(0, root) +sys.path.append(root / "docs") +sys.path.append(root / "cms/djangoapps") +sys.path.append(root / "common/djangoapps") +sys.path.append(root / "common/lib/calc") +sys.path.append(root / "common/lib/capa") +sys.path.append(root / "common/lib/chem") +sys.path.append(root / "common/lib/safe_lxml") +sys.path.append(root / "common/lib/symmath") +sys.path.append(root / "common/lib/xmodule") +sys.path.append(root / "lms/djangoapps") +sys.path.append(root / "lms/envs") +sys.path.append(root / "openedx/core/djangoapps") +sys.path.append(root / "openedx/features") + +# Use a settings module that allows all LMS and Studio code to be imported +# without errors. If running sphinx-apidoc, we already set a different +# settings module to use in the on_init() hook of the parent process +if 'DJANGO_SETTINGS_MODULE' not in os.environ: + os.environ['DJANGO_SETTINGS_MODULE'] = 'docs_settings' + +django.setup() + +# -- Project information ----------------------------------------------------- + +project = u'edx-platform' +copyright = edx_theme.COPYRIGHT +author = edx_theme.AUTHOR + +# The short X.Y version +version = u'' +# The full version, including alpha/beta/rc tags +release = u'' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.coverage', + 'sphinx.ext.doctest', + 'sphinx.ext.ifconfig', + 'sphinx.ext.intersphinx', + 'sphinx.ext.mathjax', + 'sphinx.ext.napoleon', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'edx_theme' + +html_theme_path = [edx_theme.get_html_theme_path()] + +html_theme_options = {'navigation_depth': 3} + +html_favicon = os.path.join(edx_theme.get_html_theme_path(), 'edx_theme', 'static', 'css', 'favicon.ico') + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'edx-platformdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'edx-platform.tex', u'edx-platform Documentation', + author, 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'edx-platform', u'edx-platform Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'edx-platform', u'edx-platform Documentation', + author, 'edx-platform', 'The Open edX platform, the software that powers edX!', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + 'https://docs.python.org/2.7': None, + 'django': ('https://docs.djangoproject.com/en/1.11/', 'https://docs.djangoproject.com/en/1.11/_objects/'), +} + +# Mock out these external modules during code import to avoid errors +autodoc_mock_imports = [ + 'MySQLdb', + 'contracts', + 'django_mysql', + 'lettuce', + 'pymongo', +] + +# Start building a map of the directories relative to the repository root to +# run sphinx-apidoc against and the directories under "docs" in which to store +# the generated *.rst files +modules = { + 'cms': 'cms', + 'common/lib/calc/calc': 'common/lib/calc', + 'common/lib/capa/capa': 'common/lib/capa', + 'common/lib/chem/chem': 'common/lib/chem', + 'common/lib/safe_lxml/safe_lxml': 'common/lib/safe_lxml', + 'common/lib/symmath/symmath': 'common/lib/symmath', + 'common/lib/xmodule/xmodule': 'common/lib/xmodule', + 'lms': 'lms', + 'openedx': 'openedx', +} + +# These Django apps under cms don't import correctly with the "cms.djangapps" prefix +# Others don't import correctly without it...INSTALLED_APPS entries are inconsistent +cms_djangoapps = ['contentstore', 'course_creators', 'xblock_config'] +for app in cms_djangoapps: + path = os.path.join('cms', 'djangoapps', app) + modules[path] = path + +# The Django apps under common must be imported directly, not under their path +for app in os.listdir(six.text_type(root / 'common' / 'djangoapps')): + path = os.path.join('common', 'djangoapps', app) + if os.path.isdir(six.text_type(root / path)) and app != 'terrain': + modules[path] = path + +# These Django apps under lms don't import correctly with the "lms.djangapps" prefix +# Others don't import correctly without it...INSTALLED_APPS entries are inconsistent +lms_djangoapps = ['badges', 'branding', 'bulk_email', 'courseware', + 'coursewarehistoryextended', 'email_marketing', 'experiments', 'lti_provider', + 'mobile_api', 'notes', 'rss_proxy', 'shoppingcart', 'survey'] +for app in lms_djangoapps: + path = os.path.join('lms', 'djangoapps', app) + modules[path] = path + + +def update_settings_module(service='lms'): + """ + Set the "DJANGO_SETTINGS_MODULE" environment variable appropriately + for the module sphinx-apidoc is about to be run on. + """ + if os.environ['EDX_PLATFORM_SETTINGS'] == 'devstack_docker': + settings_module = '{}.envs.devstack_docker'.format(service) + else: + settings_module = '{}.envs.devstack'.format(service) + os.environ['DJANGO_SETTINGS_MODULE'] = settings_module + + +def on_init(app): # pylint: disable=unused-argument + """ + Run sphinx-apidoc after Sphinx initialization. + + Read the Docs won't run tox or custom shell commands, so we need this to + avoid checking in the generated reStructuredText files. + """ + docs_path = root / 'docs' + apidoc_path = 'sphinx-apidoc' + if hasattr(sys, 'real_prefix'): # Check to see if we are in a virtualenv + # If we are, assemble the path manually + bin_path = os.path.abspath(os.path.join(sys.prefix, 'bin')) + apidoc_path = os.path.join(bin_path, apidoc_path) + exclude_dirs = ['envs', 'migrations', 'test', 'tests'] + exclude_dirs.extend(cms_djangoapps) + exclude_dirs.extend(lms_djangoapps) + exclude_files = ['admin.py', 'test.py', 'testing.py', 'tests.py', 'testutils.py', 'wsgi.py'] + for module in modules: + module_path = six.text_type(root / module) + output_path = six.text_type(docs_path / modules[module]) + args = [apidoc_path, '--ext-intersphinx', '-o', + output_path, module_path] + exclude = [] + if module == 'cms': + update_settings_module('cms') + else: + update_settings_module('lms') + for dirpath, dirnames, filenames in os.walk(module_path): + to_remove = [] + for name in dirnames: + if name in exclude_dirs: + to_remove.append(name) + exclude.append(os.path.join(dirpath, name)) + if 'features' in dirnames and 'openedx' not in dirpath: + to_remove.append('features') + exclude.append(os.path.join(dirpath, 'features')) + for name in to_remove: + dirnames.remove(name) + for name in filenames: + if name in exclude_files: + exclude.append(os.path.join(dirpath, name)) + if exclude: + args.extend(exclude) + check_call(args) + + +def setup(app): + """Sphinx extension: run sphinx-apidoc.""" + event = b'builder-inited' if six.PY2 else 'builder-inited' + app.connect(event, on_init) diff --git a/docs/docs_settings.py b/docs/docs_settings.py new file mode 100644 index 0000000000..9dfdec2cf0 --- /dev/null +++ b/docs/docs_settings.py @@ -0,0 +1,35 @@ +""" +Django settings for use when generating API documentation. +Basically the LMS devstack settings plus a few items needed to successfully +import all the Studio code. +""" +from __future__ import absolute_import, unicode_literals + +import os + +if os.environ['EDX_PLATFORM_SETTINGS'] == 'devstack_docker': + from lms.envs.devstack_docker import * + from cms.envs.devstack_docker import ( + ADVANCED_PROBLEM_TYPES, + COURSE_IMPORT_EXPORT_STORAGE, + SCRAPE_YOUTUBE_THUMBNAILS_JOB_QUEUE, + VIDEO_TRANSCRIPT_MIGRATIONS_JOB_QUEUE, + ) +else: + from lms.envs.devstack import * + from cms.envs.devstack import ( + ADVANCED_PROBLEM_TYPES, + COURSE_IMPORT_EXPORT_STORAGE, + SCRAPE_YOUTUBE_THUMBNAILS_JOB_QUEUE, + VIDEO_TRANSCRIPT_MIGRATIONS_JOB_QUEUE, + ) + +FEATURES['ENABLE_LTI_PROVIDER'] = True + +INSTALLED_APPS.extend([ + 'contentstore.apps.ContentstoreConfig', + 'course_creators', + 'xblock_config.apps.XBlockConfig', + 'user_tasks', + 'lti_provider' +]) diff --git a/docs/docstrings.rst b/docs/docstrings.rst new file mode 100644 index 0000000000..bbd0418112 --- /dev/null +++ b/docs/docstrings.rst @@ -0,0 +1,10 @@ +Python Docstrings +***************** + +.. toctree:: + :maxdepth: 2 + + cms_index + common_index + lms_index + openedx/modules diff --git a/docs/guides.rst b/docs/guides.rst new file mode 100644 index 0000000000..9cbf535fa7 --- /dev/null +++ b/docs/guides.rst @@ -0,0 +1,12 @@ +Guides +****** + +.. toctree:: + :maxdepth: 2 + + best_practices + testing + javascript + styling + bootstrap + static_assets diff --git a/docs/index.rst b/docs/index.rst index 2350453d41..3c71ceccff 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,12 +22,17 @@ locations. .. _Open edX ReadTheDocs: http://docs.edx.org/ .. toctree:: - :maxdepth: 2 + :maxdepth: 2 + + guides + docstrings Change History ************** +* April, 2019: API and repository-specific documentation builds resumed. + * May, 2017: The local docs directory was cleared out to start fresh. * January 13, 2015: The "edX Developer's Guide" was moved to diff --git a/docs/lms_index.rst b/docs/lms_index.rst new file mode 100644 index 0000000000..f771e3dc50 --- /dev/null +++ b/docs/lms_index.rst @@ -0,0 +1,24 @@ +lms +*** + +The ``lms`` directory in edx-platform is home to the code needed for the LMS +(Learning Management System) which is not also needed for the Course Authoring +Studio. + +.. toctree:: + :maxdepth: 2 + + lms/modules + lms/djangoapps/badges/modules + lms/djangoapps/branding/modules + lms/djangoapps/bulk_email/modules + lms/djangoapps/courseware/modules + lms/djangoapps/coursewarehistoryextended/modules + lms/djangoapps/email_marketing/modules + lms/djangoapps/experiments/modules + lms/djangoapps/lti_provider/modules + lms/djangoapps/mobile_api/modules + lms/djangoapps/notes/modules + lms/djangoapps/rss_proxy/modules + lms/djangoapps/shoppingcart/modules + lms/djangoapps/survey/modules diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000000..27f573b87a --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/testing.rst b/docs/testing.rst index 8848e7e8e6..149a3e1e0d 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -1,5 +1,6 @@ +####### Testing -======= +####### Overview --------