Skip to content

Commit 9ce860a

Browse files
authored
Improve and refactor noxfile to prepare for translation commands (#379)
2 parents 76c446a + 22b3088 commit 9ce860a

File tree

3 files changed

+114
-39
lines changed

3 files changed

+114
-39
lines changed

CONTRIBUTING.md

+32-15
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ First off, thanks for your interest in helping out with the documentation for Sp
66
For more information about Spyder, please see the [website](https://www.spyder-ide.org/), and for the core Spyder codebase, visit the [main repo](https://github.com/spyder-ide/spyder).
77
You can view the live documentation for current and past Spyder versions at [docs.Spyder-IDE.org](https://docs.spyder-ide.org).
88

9-
Spyder-Docs is part of the Spyder IDE Github org, and is developed with standard Github flow.
9+
Spyder-Docs is part of the Spyder IDE GitHub org, and is developed with standard GitHub flow.
1010
If you're not comfortable with at least the basics of ``git`` and GitHub, we recommend reading beginner tutorials such as [GitHub's Git Guide](https://github.com/git-guides/), its [introduction to basic Git commands](https://docs.github.com/en/get-started/using-git/about-git#basic-git) and its [guide to the fork workflow](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project).
1111
However, this contributing guide should fill you in on most of the basics you need to know.
1212

@@ -20,13 +20,15 @@ Let us know if you have any further questions, and we look forward to your contr
2020
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
2121

2222
- [Reporting Issues](#reporting-issues)
23-
- [Cloning the repository](#cloning-the-repository)
23+
- [Cloning the Repository](#cloning-the-repository)
2424
- [Setting Up a Development Environment with Nox (Recommended)](#setting-up-a-development-environment-with-nox-recommended)
2525
- [Setting Up a Development Environment Manually](#setting-up-a-development-environment-manually)
2626
- [Create and activate a fresh environment](#create-and-activate-a-fresh-environment)
2727
- [Install dependencies](#install-dependencies)
2828
- [Installing the Pre-Commit Hooks](#installing-the-pre-commit-hooks)
29-
- [Building the docs](#building-the-docs)
29+
- [Building the Docs](#building-the-docs)
30+
- [Build with Nox](#build-with-nox)
31+
- [Build manually](#build-manually)
3032
- [Deciding Which Branch to Use](#deciding-which-branch-to-use)
3133
- [Making Your Changes](#making-your-changes)
3234
- [Pushing your Branch](#pushing-your-branch)
@@ -49,9 +51,9 @@ If referring to a particular word, line or section, please be sure to provide a
4951

5052

5153

52-
## Cloning the repository
54+
## Cloning the Repository
5355

54-
First, navigate to the [project repository](https://github.com/spyder-ide/spyder-docs) in your web browser and press the ``Fork`` button to make a personal copy of the repository on your own Github account.
56+
First, navigate to the [project repository](https://github.com/spyder-ide/spyder-docs) in your web browser and press the ``Fork`` button to make a personal copy of the repository on your own GitHub account.
5557
Then, click the ``Clone or Download`` button on your repository, copy the link and run the following on the command line to clone the repo:
5658

5759
```shell
@@ -208,39 +210,54 @@ Once you're satisfied, ``git add .`` and commit again.
208210

209211

210212

211-
## Building the docs
213+
## Building the Docs
212214

213-
To build the docs locally with Sphinx, if you've installed Nox you can just run
215+
The documentation is built with [Sphinx](https://www.sphinx-doc.org/), which you can invoke either using [Nox](https://nox.thea.codes/) or manually.
216+
217+
218+
### Build with Nox
219+
220+
To build the docs using Nox, just run
214221

215222
```shell
216223
nox -s build
217224
```
218225

219-
For manual installations, you can invoke Sphinx yourself with the appropriate options:
226+
and can then open the rendered documentation in your default web browser with
220227

221228
```shell
222-
python -m sphinx -n -W --keep-going doc doc/_build/html
229+
nox -s serve
223230
```
224231

225-
If using Nox, you can open the rendered documentation in your default web browser with
232+
Alternatively, to automatically rebuild the docs when changes occur, you can invoke
226233

227234
```shell
228-
nox -s serve
235+
nox -s autobuild
229236
```
230237

231-
and to additionally automatically keep rebuilding the docs when changes occur, you can invoke
238+
You can also pass your own custom [Sphinx build options](https://www.sphinx-doc.org/en/master/man/sphinx-build.html) after a ``--`` separator which are added to the default set.
239+
For example, to rebuild just the install guide and FAQ in verbose mode with the ``dirhtml`` builder (our noxfile automatically prepends the source directory for you, so typing the full relative path is optional):
232240

233241
```shell
234-
nox -s autobuild
242+
nox -s build -- --verbose --builder dirhtml -- installation.rst faq.rst
243+
```
244+
245+
246+
### Build manually
247+
248+
For manual installations, you can invoke Sphinx yourself with the appropriate options:
249+
250+
```shell
251+
python -m sphinx -n -W --keep-going doc doc/_build/html
235252
```
236253

237-
Otherwise, navigate to the ``_build/html`` directory inside the ``spyder-docs`` repository and open ``index.html`` (the main page of the docs) in your preferred browser.
254+
Then, navigate to the ``_build/html`` directory inside the ``spyder-docs`` repository and open ``index.html`` (the main page of the docs) in your preferred browser.
238255

239256

240257

241258
## Deciding Which Branch to Use
242259

243-
When you start to work on a new pull request (PR), you need to be sure that your work is done on top of the correct branch, and that you base your PR on Github against it.
260+
When you start to work on a new pull request (PR), you need to be sure that your work is done on top of the correct branch, and that you base your PR on GitHub against it.
244261

245262
To guide you, issues on GitHub are marked with a milestone that indicates the correct branch to use.
246263
If not, follow these guidelines:

noxfile.py

+80-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Common tasks to build, check and publish Spyder-Docs."""
22

33
# Standard library imports
4+
import contextlib
5+
import logging
46
import os
57
import tempfile
68
import shutil
@@ -10,17 +12,20 @@
1012

1113
# Third party imports
1214
import nox # pylint: disable=import-error
15+
import nox.logger # pylint: disable=import-error
1316

1417

1518
# --- Global constants --- #
1619

20+
nox.options.error_on_external_run = True
1721
nox.options.sessions = ["build"]
1822
nox.options.default_venv_backend = "none"
1923

20-
LATEST_VERSION = 5
21-
BASE_URL = "https://docs.spyder-ide.org"
2224

23-
BUILD_INVOCATION = ("python", "-m", "sphinx", "--color")
25+
CI = "CI" in os.environ
26+
CANARY_COMMAND = ("sphinx-build", "--version")
27+
28+
BUILD_INVOCATION = ("python", "-m", "sphinx")
2429
SOURCE_DIR = Path("doc").resolve()
2530
BUILD_DIR = Path("doc/_build").resolve()
2631
BUILD_OPTIONS = ("-n", "-W", "--keep-going")
@@ -31,11 +36,23 @@
3136

3237
SCRIPT_DIR = Path("scripts").resolve()
3338

34-
CI = "CI" in os.environ
39+
LATEST_VERSION = 5
40+
BASE_URL = "https://docs.spyder-ide.org"
3541

3642

3743
# ---- Helpers ---- #
3844

45+
@contextlib.contextmanager
46+
def set_log_level(logger=nox.logger.logger, level=logging.CRITICAL):
47+
"""Context manager to set a logger log level and reset it after."""
48+
prev_level = logger.level
49+
logger.setLevel(level)
50+
try:
51+
yield
52+
finally:
53+
logger.setLevel(prev_level)
54+
55+
3956
def split_sequence(seq, sep="--"):
4057
"""Split a sequence by a single separator."""
4158
if sep not in seq:
@@ -56,6 +73,21 @@ def process_filenames(filenames, source_dir=SOURCE_DIR):
5673
return filenames
5774

5875

76+
def extract_builder_name(options):
77+
"""Extract the Sphinx builder name from a sequence of options."""
78+
try:
79+
builder_index = options.index("--builder")
80+
except ValueError:
81+
try:
82+
builder_index = options.index("-b")
83+
except ValueError:
84+
return None
85+
86+
options.pop(builder_index)
87+
builder = options.pop(builder_index)
88+
return builder
89+
90+
5991
def construct_sphinx_invocation(
6092
posargs=(),
6193
builder=HTML_BUILDER,
@@ -65,16 +97,22 @@ def construct_sphinx_invocation(
6597
build_invocation=BUILD_INVOCATION,
6698
):
6799
"""Reusably build a Sphinx invocation string from the given arguments."""
68-
extra_options, filenames = split_sequence(posargs)
100+
extra_options, filenames = split_sequence(list(posargs))
69101
filenames = process_filenames(filenames, source_dir=source_dir)
102+
builder = extract_builder_name(extra_options) or builder
103+
104+
if CI:
105+
build_options = list(build_options) + ["--color"]
106+
70107
sphinx_invocation = [
71108
*build_invocation,
72109
"-b",
73110
builder,
74111
*build_options,
75112
*extra_options,
113+
"--",
76114
str(source_dir),
77-
str(Path(build_dir) / builder),
115+
str(build_dir / builder),
78116
*filenames,
79117
]
80118
return sphinx_invocation
@@ -86,37 +124,51 @@ def construct_sphinx_invocation(
86124
# See: https://github.com/wntrblm/nox/issues/167
87125
@nox.session(venv_backend="virtualenv", reuse_venv=True)
88126
def _execute(session):
89-
"""Dispatch tasks to run in a common environment. Don not run directly."""
90-
_install(session)
127+
"""Dispatch tasks to run in a common environment. Do not run directly."""
128+
if not session.posargs or isinstance(session.posargs[0], str):
129+
raise ValueError(
130+
"Must pass a list of functions to execute as first posarg")
131+
132+
if not session.posargs or session.posargs[0] is not _install:
133+
# pylint: disable=too-many-try-statements
134+
try:
135+
with set_log_level():
136+
session.run(
137+
*CANARY_COMMAND, include_outer_env=False, silent=True)
138+
except nox.command.CommandFailed:
139+
print("Installing dependencies in isolated environment...")
140+
_install(session, use_posargs=False)
141+
91142
if session.posargs:
92143
for task in session.posargs[0]:
93144
task(session)
94145

95146

96147
# ---- Install ---- #
97148

98-
def _install(session):
149+
def _install(session, use_posargs=True):
99150
"""Execute the dependency installation."""
100-
session.install("-r", "requirements.txt")
151+
posargs = session.posargs[1:] if use_posargs else ()
152+
session.install("-r", "requirements.txt", *posargs)
101153

102154

103155
@nox.session
104156
def install(session):
105-
"""Install the project's dependencies in a virtual environment."""
106-
session.notify("_execute", posargs=())
157+
"""Install the project's dependencies (passes through args to pip)."""
158+
session.notify("_execute", posargs=([_install], *session.posargs))
107159

108160

109161
# ---- Utility ---- #
110162

111-
def _sphinx_help(session):
163+
def _build_help(session):
112164
"""Print Sphinx --help."""
113165
session.run(*BUILD_INVOCATION, "--help")
114166

115167

116168
@nox.session(name="help")
117-
def sphinx_help(session):
118-
"""Get help with Sphinx."""
119-
session.notify("_execute", posargs=([_sphinx_help],))
169+
def build_help(session):
170+
"""Get help with the project build."""
171+
session.notify("_execute", posargs=([_build_help],))
120172

121173

122174
def _run(session):
@@ -130,18 +182,24 @@ def run(session):
130182
session.notify("_execute", posargs=([_run], *session.posargs))
131183

132184

133-
def _clean():
134-
"""Remove the Sphinx build directory."""
185+
def _clean(session):
186+
"""Remove the build directory."""
187+
print(f"Removing build directory {BUILD_DIR.as_posix()!r}")
188+
ignore = session.posargs and session.posargs[0] in {"-i", "--ignore"}
189+
135190
try:
136-
BUILD_DIR.unlink()
191+
shutil.rmtree(BUILD_DIR, ignore_errors=ignore)
137192
except FileNotFoundError:
138193
pass
194+
except Exception:
195+
print("\nError removing files; pass '-i'/'--ignore' flag to ignore\n")
196+
raise
139197

140198

141199
@nox.session
142-
def clean(_session):
143-
"""Clean build artifacts."""
144-
_clean()
200+
def clean(session):
201+
"""Clean build artifacts (pass -i/--ignore to ignore errors)."""
202+
_clean(session)
145203

146204

147205
# ---- Build ---- #

requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pre-commit>=2.10.0,<4 # For pre-commit hooks; Lowercap to config syntax
22
pydata-sphinx-theme>=0.14.1,<0.16 # Theme; Lowercap to add version warning
3-
sphinx>=5,<8 # Docs generator; Cap to range confirmed supported by deps
4-
sphinx-design>=0.5.0,<0.6 # For dropdowns and panels; lowercap to sphinx>=5,<8
3+
sphinx>=5,<9 # Docs generator; Cap to range confirmed supported by deps
4+
sphinx-design>=0.5.0,<0.7 # For dropdowns and panels; lowercap to sphinx>=5,<8

0 commit comments

Comments
 (0)