Skip to content

Commit

Permalink
Temp fix decade-long Sphinx bug breaking our CSS during partial rebui…
Browse files Browse the repository at this point in the history
…lds (#2496)

* Add temp fix for Sphinx failing to copy static files

* Gate the temp fix feature behind a dev-machine specific file

* Move the temp fix into a contained script file + update .gitignore comment

* Remove extraneous commits + add annotations and docstrings

* Fix broken URL link in docstring

* Extra safety for when we notice we shouldn't run

* Fix some pathing stuff + test with ./make.py serve

* Fix paths

* Update top-of-file docstring

* Fix dirs
  • Loading branch information
pushfoo authored Jan 20, 2025
1 parent 7be16ce commit 049ec48
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ temp/
.python-version

.flake8

# pending: Sphinx 8.1.4 + deps are verified as working with Arcade
# see util/sphinx_static_file_temp_fix.py
.ENABLE_DEVMACHINE_SPHINX_STATIC_FIX
6 changes: 5 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

HERE = Path(__file__).resolve()
REPO_LOCAL_ROOT = HERE.parent.parent

ARCADE_MODULE = REPO_LOCAL_ROOT / "arcade"
UTIL_DIR = REPO_LOCAL_ROOT / "util"

Expand Down Expand Up @@ -88,14 +89,17 @@ def run_util(filename, run_name="__main__", init_globals=None):

runpy.run_path(full_str, **kwargs)

# Temp fix for Sphinx not copying static files # pending: post-3.0 refactor
# Enable by creating a .ENABLE_DEVMACHINE_SPHINX_STATIC_FIX
run_util("sphinx_static_file_temp_fix.py")

# Make thumbnails for the example code screenshots
run_util("generate_example_thumbnails.py")
# Create a tabular representation of the resources with embeds
run_util("create_resources_listing.py", init_globals=RESOURCE_GLOBALS)
# Run the generate quick API index script
run_util('../util/update_quick_index.py')


autodoc_inherit_docstrings = False
autodoc_default_options = {
'members': True,
Expand Down
119 changes: 119 additions & 0 deletions util/sphinx_static_file_temp_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/usr/bin/env python3
"""
Gets 3.0 out the door by temp fixing Sphinx rebuild not copying CSS.
IMPORTANT: ONLY LOCAL DEVELOPER MACHINES NEED THIS!
## Who should use this?
If `./make.py clean` seems like the only way to get `./make.py html` or
`./make.py serve` to serve your modified CSS, then yes, it's for you.
## How do I use this?
1. `cd` to the repo root
2. `touch .ENABLE_DEVMACHINE_SPHINX_STATIC_FIX`
3. `./make.py html` with working CSS change updates copying
## When should I be careful?
Keep the following in mind:
1. It is a temp fix which *seems* to work with both:
* `./make.py html`
* `./make.py serve`
3. No real config options other on/off via file presence
## What's Broken in Sphinx?
1. Sphinx has a long-standing bug which fails to copy static files
https://github.com/sphinx-doc/sphinx/issues/1810
2. The fix is slated for 8.2.0 and the fix PR merged on Jan 13, 2025:
https://github.com/sphinx-doc/sphinx/pull/13236
3. No, Arcade 3.0 **will not wait** for the following:
1. Sphinx 3.2.0 to ship the fix for the problem
2. Themes to become compatible
3. Plugins to become compatible
4. Our customizations to be tested with all of the above
"""

import sys
import logging
from pathlib import Path
from sphinx import __version__ as sphinx_version

UTIL_DIR = Path(__file__).parent.resolve()
REPO_ROOT = UTIL_DIR.parent.resolve()

# Ensure we get utility & Arcade imports first
sys.path.insert(0, str(REPO_ROOT))

log = logging.getLogger(__name__)

DOC_DIR = REPO_ROOT / "doc"
STATIC_SOURCE_DIR = DOC_DIR / "_static"

ENABLE_DEVMACHINE_SPHINX_STATIC_FIX = REPO_ROOT / ".ENABLE_DEVMACHINE_SPHINX_STATIC_FIX"

BUILD_DIR = REPO_ROOT / "build"
BUILD_HTML_DIR = BUILD_DIR / "html"
BUILD_STATIC_DIR = BUILD_HTML_DIR / "_static"
BUILD_CSS_DIR = BUILD_STATIC_DIR / "css"

STATIC_CSS_DIR = STATIC_SOURCE_DIR / "css"
force_copy_on_change = { # pending: sphinx >= 8.1.4
source_file: BUILD_CSS_DIR / source_file.name
for source_file in STATIC_CSS_DIR.glob("*.css")
}


def force_sync(src: Path, dest: Path, dry: bool = False) -> None:
"""Sync a single file from ``src`` to ``dest``.
Caveats:
1. Assumes both are `pathlib.Path` instances
2. Assumes both are small
3. Fails hard when a file isn't found
"""
if sphinx_version >= '8.1.4':
log.warning(
'Sphinx >= 8.1.4 may patch broken _static copy\n'
' (see https://github.com/sphinx-doc/sphinx/issues/1810)')
try:
if src.read_text() != dest.read_text():
if dry:
log.info(f" DRY : {src} was out of date, but dry run left it as-is!")
# shutil.copyfile(src, dest)
else:
log.info(f" SYNC: {src} was out of date!")

else:
log.info(f" SKIP: {src} is current!")
except Exception as e:
log.error(f" FAIL: {src} failed: {e}")
raise e


def main():
if not ENABLE_DEVMACHINE_SPHINX_STATIC_FIX.exists():
log.info(f"SKIP: Force-sync found no {ENABLE_DEVMACHINE_SPHINX_STATIC_FIX} file!")
return
elif not BUILD_HTML_DIR.exists():
log.info(f"SKIP: {BUILD_HTML_DIR} does not exist yet.")
return

log.info(f"SYNC: Force-sync enable file found")
for src, dest in force_copy_on_change.items():
force_sync(src, dest)


if __name__ == "__main__":
main()

0 comments on commit 049ec48

Please sign in to comment.