44import os
55import re
66from pathlib import Path
7- from typing import Any , Callable
7+ from typing import Any , Callable , TypeVar
88
99import nox
1010from nox .sessions import Session
1515POSARGS_PATTERN = re .compile (r"^(\w+)\[(.+)\]$" )
1616
1717
18- def apply_standard_pip_upgrades (
19- function : Callable [[Session ], Any ]
20- ) -> Callable [[Session ], Any ]:
21- @functools .wraps (function )
22- def wrapper (session : Session ) -> None :
23- session .install ("--upgrade" , "pip" , "setuptools" , "wheel" )
24- return function (session )
18+ def is_in_ci () -> bool :
19+ return bool (int (os .environ .get ("CI" , 0 )))
2520
26- return wrapper
21+
22+ _Return = TypeVar ("_Return" )
23+
24+
25+ def do_first (
26+ first_session_func : Callable [[Session ], None ]
27+ ) -> Callable [[Callable [[Session ], _Return ]], Callable [[Session ], _Return ]]:
28+ """Decorator for functions defining session actions that should happen first
29+
30+ >>> @do_first
31+ >>> def setup(session):
32+ >>> ... # do some setup
33+ >>>
34+ >>> @setup
35+ >>> def the_actual_session(session):
36+ >>> ... # so actual work
37+
38+ This makes it quick an easy to define common setup actions.
39+ """
40+
41+ def setup (
42+ second_session_func : Callable [[Session ], _Return ]
43+ ) -> Callable [[Session ], _Return ]:
44+ @functools .wraps (second_session_func )
45+ def wrapper (session : Session ) -> Any :
46+ first_session_func (session )
47+ return second_session_func (session )
48+
49+ return wrapper
50+
51+ return setup
52+
53+
54+ @do_first
55+ def apply_standard_pip_upgrades (session : Session ) -> None :
56+ session .install ("--upgrade" , "pip" )
57+
58+
59+ @do_first
60+ def install_latest_npm_in_ci (session : Session ) -> None :
61+ if is_in_ci ():
62+ session .run ("npm" , "install" , "-g" , "npm@latest" )
2763
2864
2965@nox .session (reuse_venv = True )
3066@apply_standard_pip_upgrades
3167def format (session : Session ) -> None :
68+ """Auto format Python and Javascript code"""
3269 # format Python
3370 install_requirements_file (session , "check-style" )
3471 session .run ("black" , "." )
@@ -58,6 +95,7 @@ def example(session: Session) -> None:
5895
5996
6097@nox .session (reuse_venv = True )
98+ @install_latest_npm_in_ci
6199@apply_standard_pip_upgrades
62100def docs (session : Session ) -> None :
63101 """Build and display documentation in the browser (automatically reloads on change)"""
@@ -115,23 +153,31 @@ def docs_in_docker(session: Session) -> None:
115153def test (session : Session ) -> None :
116154 """Run the complete test suite"""
117155 session .notify ("test_python" , posargs = session .posargs )
118- session .notify ("test_types" )
119- session .notify ("test_style" )
120156 session .notify ("test_docs" )
121157 session .notify ("test_javascript" )
122158
123159
124160@nox .session
125- def test_short (session : Session ) -> None :
126- """Run a shortened version of the test suite"""
127- session .notify ("test_python" , posargs = session .posargs )
128- session .notify ("test_docs" )
129- session .notify ("test_javascript" )
161+ def test_python (session : Session ) -> None :
162+ """Run all Python checks"""
163+ session .notify ("test_python_suite" , posargs = session .posargs )
164+ session .notify ("test_python_types" )
165+ session .notify ("test_python_style" )
166+ session .notify ("test_python_build" )
167+
168+
169+ @nox .session
170+ def test_javascript (session : Session ) -> None :
171+ """Run all Javascript checks"""
172+ session .notify ("test_javascript_suite" )
173+ session .notify ("test_javascript_build" )
174+ session .notify ("test_javascript_style" )
130175
131176
132177@nox .session
178+ @install_latest_npm_in_ci
133179@apply_standard_pip_upgrades
134- def test_python (session : Session ) -> None :
180+ def test_python_suite (session : Session ) -> None :
135181 """Run the Python-based test suite"""
136182 session .env ["IDOM_DEBUG_MODE" ] = "1"
137183 install_requirements_file (session , "test-env" )
@@ -149,8 +195,8 @@ def test_python(session: Session) -> None:
149195
150196@nox .session
151197@apply_standard_pip_upgrades
152- def test_types (session : Session ) -> None :
153- """Perform a static type analysis of the codebase"""
198+ def test_python_types (session : Session ) -> None :
199+ """Perform a static type analysis of the Python codebase"""
154200 install_requirements_file (session , "check-types" )
155201 install_requirements_file (session , "pkg-deps" )
156202 install_requirements_file (session , "pkg-extras" )
@@ -159,8 +205,8 @@ def test_types(session: Session) -> None:
159205
160206@nox .session
161207@apply_standard_pip_upgrades
162- def test_style (session : Session ) -> None :
163- """Check that style guidelines are being followed"""
208+ def test_python_style (session : Session ) -> None :
209+ """Check that Python style guidelines are being followed"""
164210 install_requirements_file (session , "check-style" )
165211 session .run ("flake8" , "src/idom" , "tests" , "docs" )
166212 black_default_exclude = r"\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|\.svn|_build|buck-out|build|dist"
@@ -176,6 +222,15 @@ def test_style(session: Session) -> None:
176222
177223@nox .session
178224@apply_standard_pip_upgrades
225+ def test_python_build (session : Session ) -> None :
226+ """Test whether the Python package can be build for distribution"""
227+ install_requirements_file (session , "build-pkg" )
228+ session .run ("python" , "setup.py" , "bdist_wheel" , "sdist" )
229+
230+
231+ @nox .session
232+ @install_latest_npm_in_ci
233+ @apply_standard_pip_upgrades
179234def test_docs (session : Session ) -> None :
180235 """Verify that the docs build and that doctests pass"""
181236 install_requirements_file (session , "build-docs" )
@@ -192,19 +247,47 @@ def test_docs(session: Session) -> None:
192247 "docs/build" ,
193248 )
194249 session .run ("sphinx-build" , "-b" , "doctest" , "docs/source" , "docs/build" )
250+ # ensure docker image build works too
251+ session .run ("docker" , "build" , "." , "--file" , "docs/Dockerfile" , external = True )
195252
196253
197- @nox . session
198- def test_javascript ( session : Session ) -> None :
199- """Run the Javascript-based test suite and ensure it bundles succesfully"""
254+ @do_first
255+ @ install_latest_npm_in_ci
256+ def setup_client_env ( session : Session ) -> None :
200257 session .chdir (SRC / "client" )
201258 session .run ("npm" , "install" , external = True )
259+
260+
261+ @nox .session
262+ @setup_client_env
263+ def test_javascript_suite (session : Session ) -> None :
264+ """Run the Javascript-based test suite and ensure it bundles succesfully"""
202265 session .run ("npm" , "run" , "test" , external = True )
266+
267+
268+ @nox .session
269+ @setup_client_env
270+ def test_javascript_build (session : Session ) -> None :
271+ """Run the Javascript-based test suite and ensure it bundles succesfully"""
272+ session .run ("npm" , "run" , "test" , external = True )
273+
274+
275+ @nox .session
276+ @setup_client_env
277+ def test_javascript_style (session : Session ) -> None :
278+ """Check that Javascript style guidelines are being followed"""
279+ session .run ("npm" , "run" , "check-format" , external = True )
280+
281+
282+ @nox .session
283+ def build_js (session : Session ) -> None :
284+ """Build javascript client code"""
285+ session .chdir (SRC / "client" )
203286 session .run ("npm" , "run" , "build" , external = True )
204287
205288
206289@nox .session
207- def tag (session : Session ):
290+ def tag (session : Session ) -> None :
208291 """Create a new git tag"""
209292 try :
210293 session .run (
@@ -265,12 +348,6 @@ def update_version(session: Session) -> None:
265348 session .install ("-e" , "." )
266349
267350
268- @nox .session
269- def build_js (session : Session ) -> None :
270- session .chdir (SRC / "client" )
271- session .run ("npm" , "run" , "build" , external = True )
272-
273-
274351@nox .session (reuse_venv = True )
275352def latest_pull_requests (session : Session ) -> None :
276353 """A basic script for outputing changelog info"""
0 commit comments