Skip to content

Commit

Permalink
fix: redirect file wasn't getting created
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Sep 6, 2024
2 parents 7696487 + 5ac45a4 commit 19809f3
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 34 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Quick Start

`sphinx-ape` is a documenation plugin for the Sphinx framework.
`sphinx-ape` is a documentation plugin for the Sphinx framework.
The purpose of this plugin to share code for generating documentation across all ApeWorX repositories.

## Dependencies
Expand Down
4 changes: 4 additions & 0 deletions sphinx_ape/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def methoddocs_path(self) -> Path:
def conf_file(self) -> Path:
return self.docs_path / "conf.py"

@property
def index_file(self) -> Path:
return self.build_path / "index.html"

def init(self):
if not self.docs_path.is_dir():
self.docs_path.mkdir()
Expand Down
40 changes: 21 additions & 19 deletions sphinx_ape/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ class BuildMode(Enum):
LATEST = 0
"""Build and then push to 'latest/'"""

RELEASE = 1
MERGE_TO_MAIN = 1
"""Build and then push to 'stable/'"""

RELEASE = 2
"""Build and then push to 'stable/', 'latest/', and the version's release tag folder"""

@classmethod
Expand All @@ -40,8 +43,13 @@ def init(cls, identifier: Optional[Union[str, "BuildMode"]] = None) -> "BuildMod
# Click being weird, value like "buildmode.release".
identifier = identifier.split(".")[-1].upper()

# GitHub event name.
return BuildMode.RELEASE if identifier.lower() == "release" else BuildMode.LATEST
identifier = identifier.lower()
if identifier == "release":
return BuildMode.RELEASE
elif identifier in ("push", "merge_to_main"):
return BuildMode.MERGE_TO_MAIN
else:
return BuildMode.LATEST

# Unexpected.
raise TypeError(identifier)
Expand Down Expand Up @@ -83,8 +91,9 @@ def build(self):
building fails.
"""

if self.mode is BuildMode.LATEST:
if self.mode in (BuildMode.LATEST, BuildMode.MERGE_TO_MAIN):
# TRIGGER: Push to 'main' branch. Only builds latest.
# And on PRs / local.
self._sphinx_build(self.latest_path)

elif self.mode is BuildMode.RELEASE:
Expand Down Expand Up @@ -122,7 +131,7 @@ def _publish(self, repository: Optional[str] = None, push: bool = True):
else:
repo_url = extract_source_url()

gh_pages_path = Path.cwd() / "gh-pages"
gh_pages_path = self._base_path / "gh-pages"
git(
"clone",
repo_url,
Expand All @@ -135,14 +144,11 @@ def _publish(self, repository: Optional[str] = None, push: bool = True):
# Any built docs get added; the docs that got built are based on
# the mode parameter.
for path in self.build_path.iterdir():
if not path.is_dir() or path.name.startswith(".") or path.name == "doctest":
continue

elif path.name == "index.html":
(gh_pages_path / "index.html").write_text(path.read_text())

else:
if path.is_dir() and not path.name.startswith(".") and path.name != "doctest":
shutil.copytree(path, gh_pages_path / path.name, dirs_exist_ok=True)
elif (path.name == "index.html") and path.is_file():
gh_pages_path.mkdir(exist_ok=True)
(gh_pages_path / "index.html").write_text(path.read_text())

no_jykell_file = gh_pages_path / ".nojekyll"
no_jykell_file.touch(exist_ok=True)
Expand Down Expand Up @@ -195,14 +201,10 @@ def _build_release(self):

def _setup_redirect(self):
self.build_path.mkdir(exist_ok=True, parents=True)

# In the case for local dev (or a new docs-site), the 'stable/'
# path will not exist yet, so use 'latest/' instead.
redirect = "stable" if self.stable_path.is_dir() else "latest"

index_file = self.build_path / "index.html"
index_file.unlink(missing_ok=True)
index_file.write_text(REDIRECT_HTML.format(redirect))
# We replace it to handle the case when stable has joined the chat.
self.index_file.unlink(missing_ok=True)
self.index_file.write_text(REDIRECT_HTML.format(redirect))

def _sphinx_build(self, dst_path):
sphinx_build(dst_path, self.docs_path)
84 changes: 70 additions & 14 deletions tests/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@

import pytest

from sphinx_ape.build import BuildMode, DocumentationBuilder
from sphinx_ape.build import REDIRECT_HTML, BuildMode, DocumentationBuilder


class TestBuildMode:
@pytest.mark.parametrize("val", ("latest", 0, "pull_request", "buildmode.latest"))
def test_init_latest(self, val):
mode = BuildMode.init("val")
mode = BuildMode.init(val)
assert mode is BuildMode.LATEST

@pytest.mark.parametrize("val", ("release", 1, "buildmode.release"))
@pytest.mark.parametrize("val", ("merge_to_main", 1, "push", "buildmode.merge_to_main"))
def test_init_merge_to_main(self, val):
mode = BuildMode.init(val)
assert mode is BuildMode.MERGE_TO_MAIN, val

@pytest.mark.parametrize("val", ("release", 2, "buildmode.release"))
def test_init_release(self, val):
mode = BuildMode.init(val)
assert mode is BuildMode.RELEASE


def assert_build_path(path: Path, expected: str):
assert path.name == expected # Tag, latest, or stable
assert path.parent.name == "sphinx-ape" # Project name, happens to be this lib
assert path.parent.parent.name == "_build" # Sphinx-ism
assert path.parent.parent.parent.name == "docs" # Sphinx-ism


class TestDocumentationBuilder:
@pytest.fixture(autouse=True)
def mock_sphinx(self, mocker):
Expand All @@ -37,18 +49,26 @@ def test_build_latest(self, mock_sphinx, temp_path):
builder = DocumentationBuilder(mode=BuildMode.LATEST, base_path=temp_path)
builder.build()
call_path = mock_sphinx.call_args[0][0]
self.assert_build_path(call_path, "latest")
assert_build_path(call_path, "latest")
# Ensure re-direct exists and points to latest/.
assert builder.index_file.is_file()
expected_content = REDIRECT_HTML.format("latest")
assert builder.index_file.read_text() == expected_content

def test_build_release(self, mock_sphinx, mock_git, temp_path):
tag = "v1.0.0"
mock_git.return_value = tag
builder = DocumentationBuilder(mode=BuildMode.RELEASE, base_path=temp_path)
builder.build()
call_path = mock_sphinx.call_args[0][0]
self.assert_build_path(call_path, tag)
assert_build_path(call_path, tag)
# Latest and Stable should also have been created!
self.assert_build_path(call_path.parent / "latest", "latest")
self.assert_build_path(call_path.parent / "stable", "stable")
assert_build_path(call_path.parent / "latest", "latest")
assert_build_path(call_path.parent / "stable", "stable")
# Ensure re-direct exists and points to stable/.
assert builder.index_file.is_file()
expected_content = REDIRECT_HTML.format("stable")
assert builder.index_file.read_text() == expected_content

@pytest.mark.parametrize("sub_tag", ("alpha", "beta"))
def test_build_alpha_release(self, sub_tag, mock_sphinx, mock_git, temp_path):
Expand All @@ -61,12 +81,48 @@ def test_build_alpha_release(self, sub_tag, mock_sphinx, mock_git, temp_path):
builder = DocumentationBuilder(mode=BuildMode.RELEASE, base_path=temp_path)
builder.build()
call_path = mock_sphinx.call_args[0][0]
self.assert_build_path(call_path, "stable")
assert_build_path(call_path, "stable")
# Latest should also have been created!
self.assert_build_path(call_path.parent / "latest", "latest")
assert_build_path(call_path.parent / "latest", "latest")

def assert_build_path(self, path: Path, expected: str):
assert path.name == expected # Tag, latest, or stable
assert path.parent.name == "sphinx-ape" # Project name, happens to be this lib
assert path.parent.parent.name == "_build" # Sphinx-ism
assert path.parent.parent.parent.name == "docs" # Sphinx-ism
def test_publish_merge_to_main(self, temp_path, mock_git):
tag = "v1.0.0"
mock_git.return_value = tag
builder = DocumentationBuilder(mode=BuildMode.MERGE_TO_MAIN, base_path=temp_path)
# Ensure built first.
builder.build()
builder.publish(push=False)
gh_pages_path = temp_path / "gh-pages"
nojekyll_file = gh_pages_path / ".nojekyll"
stable_dir = gh_pages_path / "stable"
latest_dir = gh_pages_path / "latest"
tag_dir = gh_pages_path / tag
index_file = gh_pages_path / builder.index_file.name
assert gh_pages_path.is_dir()
assert nojekyll_file.is_file()
assert latest_dir.is_dir()
assert index_file.is_file()
# Not tag-release should have gotten created on merge-to-main.
assert not tag_dir.is_dir()
# Stable only gets built on releases.
assert not stable_dir.is_dir()

def test_publish_release(self, temp_path, mock_git):
tag = "v1.0.0"
mock_git.return_value = tag
builder = DocumentationBuilder(mode=BuildMode.RELEASE, base_path=temp_path)
# Ensure built first.
builder.build()
builder.publish(push=False)
gh_pages_path = temp_path / "gh-pages"
nojekyll_file = gh_pages_path / ".nojekyll"
stable_dir = gh_pages_path / "stable"
latest_dir = gh_pages_path / "latest"
tag_dir = gh_pages_path / tag
index_file = gh_pages_path / builder.index_file.name
assert gh_pages_path.is_dir()
assert nojekyll_file.is_file()
assert stable_dir.is_dir()
assert latest_dir.is_dir()
assert tag_dir.is_dir()
assert index_file.is_file()

0 comments on commit 19809f3

Please sign in to comment.