Skip to content

Commit ac58266

Browse files
authored
Poetry+Hatch Monorepo (#1002)
* re-organize dirs + start using hatch * setup root pyproject.toml + basic invoke tasks * add publish task * more ruff fixes * get workflows to run * split up script runs * rename to check * change matrix order * make ruff happy * get tests to pass * check semver * more fixes * ignore missing coverage * fix cov * fix import sort * try build in env-js * try latest hatch-build-scripts * misc fixes * try to fix npm in gh action * do not set registry url by default * allow re-runs * no need for extra build * fix doc build and tests * remove scripts * fix tests * update contributor guide
1 parent cf7950d commit ac58266

File tree

198 files changed

+3859
-1916
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

198 files changed

+3859
-1916
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
name: Nox Session
1+
name: hatch-run
22

33
on:
44
workflow_call:
55
inputs:
66
job-name:
77
required: true
88
type: string
9-
nox-args:
9+
hatch-run:
1010
required: true
1111
type: string
12-
nox-session-args:
13-
required: false
14-
type: string
1512
runs-on-array:
1613
required: false
1714
type: string
@@ -20,6 +17,10 @@ on:
2017
required: false
2118
type: string
2219
default: '["3.x"]'
20+
node-registry-url:
21+
required: false
22+
type: string
23+
default: ""
2324
secrets:
2425
node-auth-token:
2526
required: false
@@ -29,30 +30,30 @@ on:
2930
required: false
3031

3132
jobs:
32-
nox-session:
33+
hatch:
3334
name: ${{ format(inputs.job-name, matrix.python-version, matrix.runs-on) }}
3435
strategy:
3536
matrix:
36-
runs-on: ${{ fromJson(inputs.runs-on-array) }}
3737
python-version: ${{ fromJson(inputs.python-version-array) }}
38+
runs-on: ${{ fromJson(inputs.runs-on-array) }}
3839
runs-on: ${{ matrix.runs-on }}
3940
steps:
4041
- uses: actions/checkout@v2
4142
- uses: actions/setup-node@v2
4243
with:
4344
node-version: "14.x"
44-
registry-url: "https://registry.npmjs.org"
45+
registry-url: ${{ inputs.node-registry-url }}
4546
- name: Pin NPM Version
4647
run: npm install -g [email protected]
4748
- name: Use Python ${{ matrix.python-version }}
4849
uses: actions/setup-python@v2
4950
with:
5051
python-version: ${{ matrix.python-version }}
5152
- name: Install Python Dependencies
52-
run: pip install -r requirements/nox-deps.txt
53-
- name: Run Sessions
53+
run: pip install hatch poetry
54+
- name: Run Scripts
5455
env:
5556
NODE_AUTH_TOKEN: ${{ secrets.node-auth-token }}
5657
PYPI_USERNAME: ${{ secrets.pypi-username }}
5758
PYPI_PASSWORD: ${{ secrets.pypi-password }}
58-
run: nox ${{ inputs.nox-args }} --stop-on-first-error -- ${{ inputs.nox-session-args }}
59+
run: hatch run ${{ inputs.hatch-run }}

Diff for: .github/workflows/check.yml

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: check
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
schedule:
11+
- cron: "0 0 * * 0"
12+
13+
jobs:
14+
test-py-cov:
15+
uses: ./.github/workflows/.hatch-run.yml
16+
with:
17+
job-name: "python-{0}"
18+
hatch-run: "test-py"
19+
lint-py:
20+
uses: ./.github/workflows/.hatch-run.yml
21+
with:
22+
job-name: "python-{0}"
23+
hatch-run: "lint-py"
24+
test-py-matrix:
25+
uses: ./.github/workflows/.hatch-run.yml
26+
with:
27+
job-name: "python-{0} {1}"
28+
hatch-run: "test-py --no-cov"
29+
runs-on-array: '["ubuntu-latest", "macos-latest", "windows-latest"]'
30+
python-version-array: '["3.9", "3.10", "3.11"]'
31+
test-docs:
32+
uses: ./.github/workflows/.hatch-run.yml
33+
with:
34+
job-name: "python-{0}"
35+
hatch-run: "test-docs"
36+
test-js:
37+
uses: ./.github/workflows/.hatch-run.yml
38+
with:
39+
job-name: "{1}"
40+
hatch-run: "test-js"
41+
lint-js:
42+
uses: ./.github/workflows/.hatch-run.yml
43+
with:
44+
job-name: "{1}"
45+
hatch-run: "lint-js"

Diff for: .github/workflows/publish.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ on:
99

1010
jobs:
1111
publish:
12-
uses: ./.github/workflows/.nox-session.yml
12+
uses: ./.github/workflows/.hatch-run.yml
1313
with:
1414
job-name: "publish"
15-
nox-args: "-s publish"
15+
hatch-run: "publish"
16+
node-registry-url: "https://registry.npmjs.org"
1617
secrets:
1718
node-auth-token: ${{ secrets.NODE_AUTH_TOKEN }}
1819
pypi-username: ${{ secrets.PYPI_USERNAME }}

Diff for: .github/workflows/test.yml

-37
This file was deleted.

Diff for: .gitignore

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# --- Build Artifacts ---
2-
src/reactpy/_client
3-
41
# --- Jupyter ---
52
*.ipynb_checkpoints
63
*Untitled*.ipynb

Diff for: .pre-commit-config.yaml

-14
This file was deleted.

Diff for: docs/Dockerfile

+13-29
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,26 @@ RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
88
RUN apt-get install -yq nodejs build-essential
99
RUN npm install -g [email protected]
1010

11-
# Create Python Venv
12-
# ------------------
13-
ENV VIRTUAL_ENV=/opt/venv
14-
RUN python3 -m venv $VIRTUAL_ENV
15-
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
16-
RUN pip install --upgrade pip
17-
18-
# Install ReactPy
11+
# Install Pipx
1912
# ------------
20-
COPY requirements ./requirements
21-
RUN pip install -r requirements/build-docs.txt
13+
RUN pip install pipx
2214

15+
# Copy Files
16+
# ----------
17+
COPY LICENSE ./
2318
COPY src ./src
24-
COPY scripts ./scripts
25-
COPY setup.py ./
26-
COPY pyproject.toml ./
27-
COPY MANIFEST.in ./
28-
COPY README.md ./
29-
RUN pip install .[all]
30-
31-
# COPY License
32-
# -----------
33-
COPY LICENSE /app/
34-
35-
# Build the Docs
36-
# --------------
37-
COPY docs/__init__.py ./docs/
38-
COPY docs/app.py ./docs/
39-
COPY docs/examples.py ./docs/
40-
COPY docs/source ./docs/source
19+
COPY docs ./docs
4120
COPY branding ./branding
42-
RUN sphinx-build -v -W -b html docs/source docs/build
21+
22+
# Install and Build Docs
23+
# ----------------------
24+
WORKDIR /app/docs
25+
RUN pipx run poetry install
26+
RUN pipx run poetry run sphinx-build -v -W -b html source build
4327

4428
# Define Entrypoint
4529
# -----------------
4630
ENV PORT 5000
4731
ENV REACTPY_DEBUG_MODE=1
4832
ENV REACTPY_CHECK_VDOM_SPEC=0
49-
CMD python scripts/run_docs.py
33+
CMD pipx run poetry run python main.py

Diff for: docs/Makefile

-19
This file was deleted.
File renamed without changes.

Diff for: docs/app.py renamed to docs/docs_app/app.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33

44
from sanic import Sanic, response
55

6+
from docs_app.examples import get_normalized_example_name, load_examples
67
from reactpy import component
78
from reactpy.backend.sanic import Options, configure, use_request
89
from reactpy.core.types import ComponentConstructor
910

10-
from .examples import get_normalized_example_name, load_examples
11+
THIS_DIR = Path(__file__).parent
12+
DOCS_DIR = THIS_DIR.parent
13+
DOCS_BUILD_DIR = DOCS_DIR / "build"
1114

12-
13-
HERE = Path(__file__).parent
1415
REACTPY_MODEL_SERVER_URL_PREFIX = "/_reactpy"
1516

1617
logger = getLogger(__name__)
@@ -40,13 +41,13 @@ def reload_examples():
4041
_EXAMPLES: dict[str, ComponentConstructor] = {}
4142

4243

43-
def make_app():
44-
app = Sanic("docs_app")
44+
def make_app(name: str):
45+
app = Sanic(name)
4546

46-
app.static("/docs", str(HERE / "build"))
47+
app.static("/docs", str(DOCS_BUILD_DIR))
4748

4849
@app.route("/")
49-
async def forward_to_index(request):
50+
async def forward_to_index(_):
5051
return response.redirect("/docs/index.html")
5152

5253
configure(

Diff for: scripts/live_docs.py renamed to docs/docs_app/dev.py

+5-12
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,19 @@
1313
get_parser,
1414
)
1515

16-
from docs.app import make_app, reload_examples
16+
from docs_app.app import make_app, reload_examples
1717
from reactpy.backend.sanic import serve_development_app
1818
from reactpy.testing import clear_reactpy_web_modules_dir
1919

20-
2120
# these environment variable are used in custom Sphinx extensions
2221
os.environ["REACTPY_DOC_EXAMPLE_SERVER_HOST"] = "127.0.0.1:5555"
2322
os.environ["REACTPY_DOC_STATIC_SERVER_HOST"] = ""
2423

25-
_running_reactpy_servers = []
26-
2724

2825
def wrap_builder(old_builder):
2926
# This is the bit that we're injecting to get the example components to reload too
3027

31-
app = make_app()
28+
app = make_app("docs_dev_app")
3229

3330
thread_started = threading.Event()
3431

@@ -87,8 +84,8 @@ def main():
8784
ignore_handler = _get_ignore_handler(args)
8885
server.watch(srcdir, builder, ignore=ignore_handler)
8986
for dirpath in args.additional_watched_dirs:
90-
dirpath = os.path.realpath(dirpath)
91-
server.watch(dirpath, builder, ignore=ignore_handler)
87+
real_dirpath = os.path.realpath(dirpath)
88+
server.watch(real_dirpath, builder, ignore=ignore_handler)
9289
server.watch(outdir, ignore=ignore_handler)
9390

9491
if not args.no_initial_build:
@@ -100,12 +97,8 @@ def main():
10097

10198
def opener():
10299
time.sleep(args.delay)
103-
webbrowser.open("http://%s:%s/index.html" % (args.host, args.port))
100+
webbrowser.open(f"http://{args.host}:{args.port}/index.html")
104101

105102
threading.Thread(target=opener, daemon=True).start()
106103

107104
server.serve(port=portn, host=args.host, root=outdir)
108-
109-
110-
if __name__ == "__main__":
111-
main()

Diff for: docs/examples.py renamed to docs/docs_app/examples.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
from __future__ import annotations
22

3+
from collections.abc import Iterator
34
from io import StringIO
45
from pathlib import Path
56
from traceback import format_exc
6-
from typing import Callable, Iterator
7+
from typing import Callable
78

89
import reactpy
910
from reactpy.types import ComponentType
1011

11-
1212
HERE = Path(__file__)
13-
SOURCE_DIR = HERE.parent / "source"
13+
SOURCE_DIR = HERE.parent.parent / "source"
1414
CONF_FILE = SOURCE_DIR / "conf.py"
1515
RUN_ReactPy = reactpy.run
1616

@@ -148,7 +148,6 @@ def __init__(self, max_lines: int = 10):
148148

149149
def set_callback(self, function: Callable[[str], None]) -> None:
150150
self._callback = function
151-
return None
152151

153152
def getvalue(self) -> str:
154153
return "".join(self._lines)

Diff for: docs/docs_app/prod.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import os
2+
3+
from docs_app.app import make_app
4+
5+
app = make_app("docs_prod_app")
6+
7+
8+
def main() -> None:
9+
app.run(
10+
host="0.0.0.0", # noqa: S104
11+
port=int(os.environ.get("PORT", 5000)),
12+
workers=int(os.environ.get("WEB_CONCURRENCY", 1)),
13+
debug=bool(int(os.environ.get("DEBUG", "0"))),
14+
)

0 commit comments

Comments
 (0)