Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ help:
@echo " build to build the documentation in all formats (PDF, HTML and ePUB)"
@echo " build_html to build the documentation in HTML format only"
@echo " release_notes to generate the release notes for a specific version (default: 25.10). Use 'make changelog VERSION=XX' to specify."
@echo ""
@echo "Build arguments:"
@echo " SKIP_FETCH=1 skip GitHub fetch/clone operations (for quick iteration)"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
Expand Down Expand Up @@ -71,10 +74,10 @@ build:
mv _build/versions_map.json versions_map.json &> /dev/null || true

@echo "Building version map"
./build.py --formats version_map $(if $(VERSION),--version $(VERSION)) $(if $(MODULES),--modules $(MODULES))
./build.py --formats version_map $(if $(VERSION),--version $(VERSION)) $(if $(MODULES),--modules $(MODULES)) $(if $(SKIP_FETCH),--skip-fetch)

@echo "Building documentation"
./build.py $(if $(FORMATS),--formats $(FORMATS)) $(if $(VERSION),--version $(VERSION)) $(if $(MODULES),--modules $(MODULES))
./build.py $(if $(FORMATS),--formats $(FORMATS)) $(if $(VERSION),--version $(VERSION)) $(if $(MODULES),--modules $(MODULES)) $(if $(SKIP_FETCH),--skip-fetch)

# Store the version map in the _build/ directory
mv versions_map.json _build/
Expand Down
35 changes: 26 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,18 @@ Requirements: Python >= 3.9.

# This command will generate the documentation in all formats - HTML, PDF and ePUB
make build

# The ``formats`` argument is a comma separated list of formats to build,
# e.g. ``formats=html,pdf,epub``. The default is to build all available
# formats, which currently are ``html``, ``pdf`` and ``epub``.
make build formats=pdf,html

# This command is a shortcut for generating only HTML documentation during
# development, since building PDF and ePUB takes time. It also supports
# the VERSION argument.
make build_html

# Build only the dev version in HTML format
make build VERSION=dev FORMATS=html

..
note:

Please refer the "`build options" <#build-options>`_section of this
configuration for a complete reference of the available options.
# Quickly rebuild, useful during iteration
make build VERSION=dev FORMATS=html SKIP_FETCH=1

5. Open the generated HTML files in your browser.

Expand Down Expand Up @@ -170,6 +163,30 @@ instead of HTTPS. For example:

SSH=1 make build

Skipping repository fetch for quick iteration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When actively editing documentation, you may want to skip the
fetch/clone/update operations to speed up the build process. This is
especially useful when you have already cloned the repositories and want
to quickly rebuild the documentation after making local changes.

To skip all repository operations, use the ``SKIP_FETCH`` argument:

.. code-block:: shell

make build SKIP_FETCH=1

Or for HTML-only builds:

.. code-block:: shell

make build_html SKIP_FETCH=1

**Note**: Using ``SKIP_FETCH`` requires that the repositories have already been
cloned in a previous build. If the repositories don't exist, the build
will fail.

Spell check
~~~~~~~~~~~

Expand Down
31 changes: 20 additions & 11 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,14 @@ def git_is_on_branch(repo_path):


def clone_or_update_repo(
name, branch, dir_name, owner="openwisp", dest=None, version_name=None
name, branch, dir_name, skip_fetch=False, owner="openwisp", dest=None, version_name=None
):
"""
Clone or update a repository based on the module name and branch provided.
If the repository already exists, update it. Otherwise, clone the repository.
The resulting directory is then symlinked internally.
If skip_fetch=True is passed, git fetching/cloning
is skipped and only symlink is performed.
"""
repository = f"{owner}/{name}"
# Support for building with local changes
Expand Down Expand Up @@ -327,9 +330,9 @@ def clone_or_update_repo(
repo_url = f"git@github.com:{repository}.git"
else:
repo_url = f"https://github.com/{repository}.git"
# update if dir exists, otherwise clone
clone_path = os.path.abspath(os.path.join("modules", dir_name))

if os.path.exists(clone_path):
if os.path.exists(clone_path) and not skip_fetch:
print(f"Repository '{name}' already exists. Updating...")
subprocess.run(
# Update remote-tracking ref (avoid fetching into checked-out branch)
Expand Down Expand Up @@ -366,7 +369,7 @@ def clone_or_update_repo(
subprocess.run(
["git", "pull", "origin", branch], cwd=clone_path, check=True
)
else:
elif not skip_fetch:
print(f"Cloning repository '{name}'...")
subprocess.run(
[
Expand All @@ -382,6 +385,10 @@ def clone_or_update_repo(
],
check=True,
)
elif skip_fetch and not os.path.exists(clone_path):
raise FileNotFoundError(
f"Repository \"{name}\" not found at {clone_path}; run without SKIP_FETCH=1 first."
)
# Create a symlink to either the 'docs' directory inside the cloned repository
# or to the entire repository if no 'docs' directory exists.
# This makes the documentation sources available to the Sphinx build process.
Expand Down Expand Up @@ -414,11 +421,15 @@ def main():
help="comma separated modules to build"
"in the format of <version:module-name>:<branch>:<dir-name>:<repository-owner>",
)
parser.add_argument(
"--skip-fetch",
action="store_true",
default=False,
help="skip fetching/cloning repositories (useful for quick iteration while editing docs)",
)
args = parser.parse_args()

with open("config.yml") as f:
config = yaml.safe_load(f)

build_versions = get_build_versions(config["versions"], args.version)
stable_version = get_stable_version(build_versions)
docs_root = ""
Expand All @@ -428,11 +439,10 @@ def main():
docs_root = "/docs"
html_base_url = "https://openwisp.io"
build_dir = f"{build_dir}{docs_root}"

# loop over versions and build each one by one
for version in build_versions:
version_name = version["name"]
module_dirs = []

# Modules which are configured to be included in all the builds
default_modules = (
config["modules"] if not version.get("overwrite_modules") else []
Expand All @@ -446,20 +456,21 @@ def main():
version_modules=version_modules,
overridden_modules=overridden_modules,
)

# If a module does not define a branch,
# it will fallback to the version_branch.
version_branch = version.get("module_branch", version["name"])
docs_branch = version.get("docs_branch", "master")
clone_or_update_repo(
name="openwisp-docs",
branch=docs_branch,
skip_fetch=args.skip_fetch,
dir_name="openwisp-docs",
version_name=version_name,
)
for module in modules:
clone_or_update_repo(
branch=module.pop("branch", version_branch),
skip_fetch=args.skip_fetch,
**module,
)
module_dirs.append(module["dir_name"])
Expand All @@ -484,13 +495,11 @@ def main():
# Remove all temporary directories
for dir in module_dirs:
remove_symlink(dir)

# Generate the index.html file which redirects to the stable version.
env = Environment(loader=FileSystemLoader("_static"))
template = env.get_template("index.jinja2")
with open(f"{build_dir}/index.html", "w") as f:
f.write(template.render(stable_version=stable_version, docs_root=docs_root))

# Create a symbolic link for the stable version
subprocess.run(
[
Expand Down