-
-
Notifications
You must be signed in to change notification settings - Fork 284
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Nox setup & setup-remotes commands + other improvements (#384)
- Loading branch information
Showing
2 changed files
with
152 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,11 +21,12 @@ | |
nox.options.sessions = ["build"] | ||
nox.options.default_venv_backend = "none" | ||
|
||
|
||
CI = "CI" in os.environ | ||
ORG_NAME = "spyder-ide" | ||
REPO_NAME = "spyder-docs" | ||
REPO_URL_HTTPS = "https://github.com/{user}/{repo}.git" | ||
REPO_URL_SSH = "[email protected]:{user}/{repo}.git" | ||
|
||
CANARY_COMMAND = ("sphinx-build", "--version") | ||
|
||
BUILD_INVOCATION = ("python", "-m", "sphinx") | ||
SOURCE_DIR = Path("doc").resolve() | ||
BUILD_DIR = Path("doc/_build").resolve() | ||
|
@@ -51,6 +52,8 @@ | |
CONF_PY = SOURCE_DIR / "conf.py" | ||
SCRIPT_DIR = Path("scripts").resolve() | ||
|
||
CI = "CI" in os.environ | ||
|
||
|
||
# ---- Helpers ---- # | ||
|
||
|
@@ -89,6 +92,8 @@ def extract_option_values(options, option_names, *, split_csv=False): | |
"""Extract particular option values from a sequence of options.""" | ||
option_values = [] | ||
remaining_options = [] | ||
if isinstance(option_names, str): | ||
option_names = [option_names] | ||
|
||
save_next_option = False | ||
for option in options: | ||
|
@@ -196,8 +201,11 @@ def build_help(session): | |
|
||
|
||
def _run(session): | ||
"""Run an arbitrary command in the project's venv.""" | ||
session.run(*session.posargs[1:]) | ||
"""Run an arbitrary command invocation in the project's venv.""" | ||
posargs = session.posargs[1:] | ||
if not posargs: | ||
session.error("Must pass a command invocation to run") | ||
session.run(*posargs) | ||
|
||
|
||
@nox.session() | ||
|
@@ -209,14 +217,15 @@ def run(session): | |
def _clean(session): | ||
"""Remove the build directory.""" | ||
print(f"Removing build directory {BUILD_DIR.as_posix()!r}") | ||
ignore = session.posargs and session.posargs[0] in {"-i", "--ignore"} | ||
ignore_flag = "--ignore" | ||
should_ignore = ignore_flag in session.posargs | ||
|
||
try: | ||
shutil.rmtree(BUILD_DIR, ignore_errors=ignore) | ||
shutil.rmtree(BUILD_DIR, ignore_errors=should_ignore) | ||
except FileNotFoundError: | ||
pass | ||
except Exception: | ||
print("\nError removing files; pass '-i'/'--ignore' flag to ignore\n") | ||
print(f"\nError removing files; pass {ignore_flag!r} flag to ignore\n") | ||
raise | ||
|
||
|
||
|
@@ -226,13 +235,77 @@ def clean(session): | |
_clean(session) | ||
|
||
|
||
# --- Set up --- # | ||
|
||
def _setup_remotes(session): | ||
"""Set up the origin and upstream remote repositories.""" | ||
remote_cmd = ["git", "remote"] | ||
posargs = list(session.posargs[1:]) | ||
https = "--https" in posargs | ||
ssh = "--ssh" in posargs | ||
username_args = extract_option_values(posargs, "--username")[0] | ||
if https == ssh: | ||
session.error("Exactly one of '--https' or '--ssh' must be passed") | ||
|
||
# Get current origin details | ||
origin_url_cmd = (*remote_cmd, "get-url", "origin") | ||
origin_url = session.run( | ||
*origin_url_cmd, external=True, silent=True, log=False).strip() | ||
if "https://" not in origin_url: | ||
origin_url = origin_url.split(":")[-1] | ||
origin_user, origin_repo = origin_url.split("/")[-2:] | ||
if origin_repo.endswith(".git"): | ||
origin_repo = origin_repo[:-4] | ||
|
||
# Check username | ||
if username_args: | ||
origin_user = username_args[0].strip().lstrip("@") | ||
elif origin_user.lower() == ORG_NAME.lower(): | ||
code_host = REPO_URL_HTTPS.split(":")[1].lstrip("/").split("/")[0] | ||
session.warn( | ||
"Origin remote currently set to upstream; should be your fork.\n" | ||
f"To fix, fork it and pass --username <Your {code_host} username>" | ||
) | ||
|
||
# Set up remotes | ||
existing_remotes = session.run( | ||
*remote_cmd, external=True, silent=True, log=False).strip().split("\n") | ||
for remote, user_name, repo_name in ( | ||
("origin", origin_user, origin_repo), | ||
("upstream", ORG_NAME, REPO_NAME), | ||
): | ||
action = "set-url" if remote in existing_remotes else "add" | ||
fetch_url = REPO_URL_HTTPS.format(user=user_name, repo=repo_name) | ||
session.run(*remote_cmd, action, remote, fetch_url, external=True) | ||
|
||
ssh_url = REPO_URL_SSH.format(user=user_name, repo=repo_name) | ||
push_url = ssh_url if ssh else fetch_url | ||
session.run( | ||
*remote_cmd, "set-url", "--push", remote, push_url, external=True) | ||
|
||
session.run("git", "fetch", "--all", external=True) | ||
|
||
|
||
@nox.session(name="setup-remotes") | ||
def setup_remotes(session): | ||
"""Set up the Git remotes; pass --https or --ssh to specify URL type.""" | ||
session.notify("_execute", posargs=([_setup_remotes], *session.posargs)) | ||
|
||
|
||
@nox.session() | ||
def setup(session): | ||
"""Set up the project; pass --https or --ssh to specify Git URL type.""" | ||
session.notify( | ||
"_execute", | ||
posargs=([_setup_remotes, _install_hooks, _clean], *session.posargs), | ||
) | ||
|
||
|
||
# ---- Build ---- # | ||
|
||
def _build(session): | ||
"""Execute the docs build.""" | ||
sphinx_invocation = construct_sphinx_invocation( | ||
posargs=session.posargs[1:]) | ||
session.run(*sphinx_invocation) | ||
_docs(session) | ||
|
||
|
||
@nox.session | ||
|
@@ -242,6 +315,32 @@ def build(session): | |
|
||
|
||
def _autobuild(session): | ||
"""Use Sphinx-Autobuild to rebuild the project and open in browser.""" | ||
_autodocs(session) | ||
|
||
|
||
@nox.session | ||
def autobuild(session): | ||
"""Rebuild the project continuously as source files are changed.""" | ||
session.notify("_execute", posargs=([_autobuild], *session.posargs)) | ||
|
||
|
||
# --- Docs --- # | ||
|
||
def _docs(session): | ||
"""Execute the docs build.""" | ||
sphinx_invocation = construct_sphinx_invocation( | ||
posargs=session.posargs[1:]) | ||
session.run(*sphinx_invocation) | ||
|
||
|
||
@nox.session | ||
def docs(session): | ||
"""Build the documentation.""" | ||
session.notify("_execute", posargs=([_docs], *session.posargs)) | ||
|
||
|
||
def _autodocs(session): | ||
"""Use Sphinx-Autobuild to rebuild the project and open in browser.""" | ||
session.install("sphinx-autobuild") | ||
|
||
|
@@ -261,9 +360,9 @@ def _autobuild(session): | |
|
||
|
||
@nox.session | ||
def autobuild(session): | ||
"""Rebuild the project continuously as source files are changed.""" | ||
session.notify("_execute", posargs=([_autobuild], *session.posargs)) | ||
def autodocs(session): | ||
"""Rebuild the docs continuously as source files are changed.""" | ||
session.notify("_execute", posargs=([_autodocs], *session.posargs)) | ||
|
||
|
||
def _build_languages(session): | ||
|
@@ -298,20 +397,32 @@ def build_multilanguage(session): | |
|
||
# ---- Deploy ---- # | ||
|
||
def _serve(_session=None): | ||
def _serve(session=None): | ||
"""Open the docs in a web browser.""" | ||
_serve_docs(session) | ||
|
||
|
||
def _serve_docs(_session=None): | ||
"""Open the docs in a web browser.""" | ||
webbrowser.open(HTML_INDEX_PATH.as_uri()) | ||
|
||
|
||
@nox.session | ||
def serve(_session): | ||
"""Display the project.""" | ||
"""Display the built project.""" | ||
_serve() | ||
|
||
|
||
@nox.session(name="serve-docs") | ||
def serve_docs(_session): | ||
"""Display the rendered documentation.""" | ||
_serve_docs() | ||
|
||
|
||
def _prepare_multiversion(_session=None): | ||
"""Execute the pre-deployment steps for multi-version support.""" | ||
# pylint: disable=import-outside-toplevel | ||
# pylint: disable=import-error | ||
|
||
sys.path.append(str(SCRIPT_DIR)) | ||
import generateredirects | ||
|