summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/docs/frontend.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/web-platform/tests/docs/frontend.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/testing/web-platform/tests/docs/frontend.py b/testing/web-platform/tests/docs/frontend.py
new file mode 100644
index 0000000000..c8d114b39f
--- /dev/null
+++ b/testing/web-platform/tests/docs/frontend.py
@@ -0,0 +1,127 @@
+import argparse
+import logging
+import os
+import subprocess
+import sys
+
+here = os.path.dirname(__file__)
+wpt_root = os.path.abspath(os.path.join(here, ".."))
+
+# Directories relative to the wpt root that we want to include in the docs
+# Sphinx doesn't support including files outside of docs/ so we temporarily symlink
+# these directories under docs/ whilst running the build.
+link_dirs = [
+ "tools/wptserve",
+ "tools/certs",
+ "tools/wptrunner",
+ "tools/webtransport",
+ "tools/third_party/pywebsocket3",
+]
+
+logger = logging.getLogger()
+
+
+def link_source_dirs():
+ created = set()
+ failed = []
+ for rel_path in link_dirs:
+ rel_path = rel_path.replace("/", os.path.sep)
+ src = os.path.join(wpt_root, rel_path)
+ dest = os.path.join(here, rel_path)
+ try:
+ dest_dir = os.path.dirname(dest)
+ if not os.path.exists(dest_dir):
+ os.makedirs(dest_dir)
+ created.add(dest_dir)
+ if not os.path.exists(dest):
+ os.symlink(src, dest, target_is_directory=True)
+ else:
+ if (not os.path.islink(dest) or
+ os.path.join(os.path.dirname(dest), os.readlink(dest)) != src):
+ # The file exists but it isn't a link or points at the wrong target
+ raise OSError("File exists")
+ except Exception as e:
+ failed.append((dest, e))
+ else:
+ created.add(dest)
+ return created, failed
+
+
+def unlink_source_dirs(created):
+ # Sort backwards in length to remove all files before getting to directory
+ for path in sorted(created, key=lambda x: -len(x)):
+ # This will also remove empty parent directories
+ if not os.path.islink(path) and os.path.isdir(path):
+ os.removedirs(path)
+ else:
+ os.unlink(path)
+
+
+def get_parser():
+ p = argparse.ArgumentParser()
+ p.add_argument("--type", default="html", help="Output type (default: html)")
+ p.add_argument("--docker", action="store_true", help="Run inside the docs docker image")
+ p.add_argument("--serve", default=None, nargs="?", const=8000,
+ type=int, help="Run a server on the specified port (default: 8000)")
+ return p
+
+
+def docker_build(tag="wpt:docs"):
+ subprocess.check_call(["docker",
+ "build",
+ "--pull",
+ "--tag", tag,
+ here])
+
+def docker_run(**kwargs):
+ cmd = ["docker", "run"]
+ cmd.extend(["--mount",
+ "type=bind,source=%s,target=/app/web-platform-tests" % wpt_root])
+ if kwargs["serve"] is not None:
+ serve = str(kwargs["serve"])
+ cmd.extend(["--expose", serve, "--publish", f"{serve}:{serve}"])
+ cmd.extend(["-w", "/app/web-platform-tests"])
+ if os.isatty(os.isatty(sys.stdout.fileno())):
+ cmd.append("-it")
+ cmd.extend(["wpt:docs", "./wpt"])
+ # /app/venv is created during docker build and is always active inside the
+ # container.
+ cmd.extend(["--venv", "/app/venv", "--skip-venv-setup"])
+ cmd.extend(["build-docs", "--type", kwargs["type"]])
+ if kwargs["serve"] is not None:
+ cmd.extend(["--serve", str(kwargs["serve"])])
+ logger.debug(" ".join(cmd))
+ return subprocess.call(cmd)
+
+
+def build(_venv, **kwargs):
+ if kwargs["docker"]:
+ docker_build()
+ return docker_run(**kwargs)
+
+ out_dir = os.path.join(here, "_build")
+ try:
+ created, failed = link_source_dirs()
+ if failed:
+ failure_msg = "\n".join(f"{dest}: {err}" for (dest, err) in failed)
+ logger.error(f"Failed to create source symlinks:\n{failure_msg}")
+ sys.exit(1)
+ if kwargs["serve"] is not None:
+ executable = "sphinx-autobuild"
+ extras = ["--port", str(kwargs["serve"]),
+ "--host", "0.0.0.0",
+ "--watch", os.path.abspath(os.path.join(here, os.pardir, "resources")),
+ # Ignore changes to files specified with glob pattern
+ "--ignore", "**/flycheck_*",
+ "--ignore", "**/.*",
+ "--ignore", "**/#*",
+ "--ignore", "docs/frontend.py",
+ "--ignore", "docs/Dockerfile"]
+ else:
+ executable = "sphinx-build"
+ extras = []
+ cmd = [executable, "-n", "-v", "-b", kwargs["type"], "-j", "auto"] + extras + [here, out_dir]
+ logger.debug(" ".join(cmd))
+ subprocess.check_call(cmd)
+ finally:
+ unlink_source_dirs(created)