3
3
# Depend on `FORCE` to ensure the target is always run
4
4
FORCE :
5
5
6
- # TODO-barret; Use `pybin/activate && COMMAND` approach, not `$(COMMAND)` approach
7
-
8
6
.DEFAULT_GOAL := help
9
7
10
8
define BROWSER_PYSCRIPT
@@ -46,13 +44,8 @@ VENV = .venv
46
44
PYBIN = $(VENV ) /bin
47
45
PIP = $(PYBIN ) /pip
48
46
PYTHON = $(PYBIN ) /python
49
- UV = $(PYBIN ) /uv
50
- PYBIN_ACTIVATE = $(PYBIN ) /activate
51
47
SITE_PACKAGES =$(VENV ) /lib/python$(PYTHON_VERSION ) /site-packages
52
48
53
- # /----------------
54
-
55
-
56
49
57
50
# -----------------
58
51
# Core virtual environment and installing
@@ -67,78 +60,61 @@ $(VENV):
67
60
$(PYBIN ) /pip install --upgrade pip
68
61
69
62
$(PYBIN ) : $(VENV )
70
- $(PYBIN_ACTIVATE ) : $(PYBIN )
71
63
$(PIP ) : $(PYBIN )
72
64
73
- UV_PKG = $(SITE_PACKAGES ) /uv
74
- $(UV ) : $( UV_PKG )
75
- $( UV_PKG ) : $(PIP )
65
+ UV = $(SITE_PACKAGES ) /uv
66
+ $(UV ) :
67
+ $( MAKE ) $(PYBIN )
76
68
@echo " -------- Installing uv --------"
77
- $(PIP ) install uv # avoid circular dependency
78
-
79
- # /----------------
69
+ . $(PYBIN ) /activate && \
70
+ pip install uv
80
71
81
72
# -----------------
82
73
# Python package executables
83
74
# -----------------
84
75
# Use `FOO=$(PYBIN)/foo` to define the path to a package's executable
85
- # Use `FOO_PKG=$(SITE_PACKAGES)/foo` to define the path to a package's site-packages directory
86
-
87
- # Depend on `$(FOO_PKG)` to ensure the package is installed,
88
- # but use `$(FOO)` to actually run the package's executable
89
-
90
- # BLACK = $(PYTHON) -m black
91
- BLACK_PKG = $(SITE_PACKAGES ) /black
92
- ISORT = $(PYBIN ) /isort
93
- ISORT_PKG = $(SITE_PACKAGES ) /isort
94
- FLAKE8 = $(PYBIN ) /flake8
95
- FLAKE8_PKG = $(SITE_PACKAGES ) /flake8
96
- PYTEST = $(PYBIN ) /pytest
97
- PYTEST_PKG = $(SITE_PACKAGES ) /pytest
98
- COVERAGE = $(PYBIN ) /coverage
99
- COVERAGE_PKG = $(SITE_PACKAGES ) /coverage
100
- PYRIGHT = $(PYBIN ) /pyright
101
- PYRIGHT_PKG = $(SITE_PACKAGES ) /pyright
102
- PLAYWRIGHT = $(PYBIN ) /playwright
103
- PLAYWRIGHT_PKG = $(SITE_PACKAGES ) /playwright
104
- $(BLACK_PKG ) $(ISORT_PKG ) $(FLAKE8_PKG ) $(PYTEST_PKG ) $(COVERAGE_PKG ) $(PYRIGHT_PKG ) $(PLAYWRIGHT_PKG ) :
76
+ # Depend on `$(FOO)` to ensure the package is installed,
77
+ # but use `$(PYBIN)/foo` to actually run the package's executable
78
+ RUFF = $(SITE_PACKAGES ) /ruff
79
+ PYTEST = $(SITE_PACKAGES ) /pytest
80
+ COVERAGE = $(SITE_PACKAGES ) /coverage
81
+ PYRIGHT = $(SITE_PACKAGES ) /pyright
82
+ PLAYWRIGHT = $(SITE_PACKAGES ) /playwright
83
+ $(PYTEST ) $(COVERAGE ) $(PYRIGHT ) $(PLAYWRIGHT ) :
105
84
@$(MAKE ) install-deps
106
- # touch $@ # update timestamp of target file
107
85
108
- # /----------------
109
86
110
87
# -----------------
111
88
# Helper packages not defined in `setup.cfg`
112
89
# -----------------
113
90
114
- TRCLI_PKG = $(SITE_PACKAGES ) /trcli
115
- $(TRCLI_PKG ) :
116
- @$(MAKE ) $(UV )
91
+ TRCLI = $(SITE_PACKAGES ) /trcli
92
+ $(TRCLI ) : $(UV )
117
93
@echo " -------- Installing trcli --------"
118
- $( UV ) pip install trcli
119
- # @touch $(PYBIN)/trcli # update timestamp
94
+ . $( PYBIN ) /activate && \
95
+ uv pip install trcli
120
96
121
- TWINE_PKG = $(SITE_PACKAGES ) /twine
122
- $(TWINE_PKG ) :
123
- @$(MAKE ) $(UV )
97
+ TWINE = $(SITE_PACKAGES ) /twine
98
+ $(TWINE ) : $(UV )
124
99
@echo " -------- Installing twine --------"
125
- $( UV ) pip install twine
126
- # @touch $(PYBIN)/twine # update timestamp
100
+ . $( PYBIN ) /activate && \
101
+ uv pip install twine
127
102
128
- RSCONNECT_PKG = $(SITE_PACKAGES ) /rsconnect
129
- $(RSCONNECT_PKG ) : # # install the main version of rsconnect till pypi version supports shiny express
130
- @$(MAKE ) $(UV )
131
- $(UV ) pip install rsconnect @ git+https://github.com/rstudio/rsconnect-python.git
103
+ RSCONNECT = $(SITE_PACKAGES ) /rsconnect
104
+ $(RSCONNECT ) : $(UV ) # # install the main version of rsconnect till pypi version supports shiny express
105
+ @echo " -------- Installing rsconnect --------"
106
+ . $(PYBIN ) /activate && \
107
+ uv pip install rsconnect @ git+https://github.com/rstudio/rsconnect-python.git
132
108
133
- # /----------------
134
109
135
110
# -----------------
136
111
# Type stubs
137
112
# -----------------
138
113
139
- typings/uvicorn : $(PYRIGHT_PKG )
114
+ typings/uvicorn : $(PYRIGHT )
140
115
@echo " -------- Creating stub for uvicorn --------"
141
- $(PYRIGHT ) --createstub uvicorn
116
+ . $(PYBIN ) /activate && \
117
+ pyright --createstub uvicorn
142
118
143
119
typings/matplotlib/__init__.pyi : # # grab type stubs from GitHub
144
120
@echo " -------- Creating stub for matplotlib --------"
@@ -147,14 +123,38 @@ typings/matplotlib/__init__.pyi: ## grab type stubs from GitHub
147
123
mv typings/python-type-stubs/stubs/matplotlib typings/
148
124
rm -rf typings/python-type-stubs
149
125
150
- typings/seaborn : $(PYRIGHT_PKG )
126
+ typings/seaborn : $(PYRIGHT )
151
127
@echo " -------- Creating stub for seaborn --------"
152
- $(PYRIGHT ) --createstub seaborn
128
+ . $(PYBIN ) /activate && \
129
+ pyright --createstub seaborn
153
130
154
131
pyright-typings : typings/uvicorn typings/matplotlib/__init__.pyi typings/seaborn
155
- # /----------------
156
132
133
+ # -----------------
134
+ # Install
135
+ # -----------------
136
+ # # install the package to the active Python's site-packages
137
+ # Note that instead of --force-reinstall, we uninstall and then install, because
138
+ # --force-reinstall also reinstalls all deps. And if we also used --no-deps, then the
139
+ # deps wouldn't be installed the first time.
140
+ install : dist $(PIP ) FORCE
141
+ . $(PYBIN ) /activate && \
142
+ pip uninstall -y shiny && \
143
+ pip install dist/shiny* .whl
144
+
145
+ install-deps : $(UV ) FORCE # # install dependencies
146
+ . $(PYBIN ) /activate && \
147
+ uv pip install -e " .[dev,test]" --refresh
148
+
149
+
150
+
151
+ # ## If caching is ever used, we could run:
152
+ # install-deps: ## install latest dependencies
153
+ # pip install --editable ".[dev,test]" --upgrade --upgrade-strategy eager
157
154
155
+ # -----------------
156
+ # Clean files
157
+ # -----------------
158
158
clean : clean-build clean-pyc clean-test # # remove all build, test, coverage and Python artifacts
159
159
160
160
clean-build : FORCE # # remove build artifacts
@@ -177,110 +177,126 @@ clean-test: FORCE ## remove test and coverage artifacts
177
177
rm -fr .pytest_cache
178
178
rm -rf typings/
179
179
180
-
181
-
180
+ # -----------------
181
+ # Check lint, test, and format of code
182
+ # -----------------
182
183
check : check-lint check-types check-tests # # check code, style, types, and test (basic CI)
183
184
check-fix : format check-lint check-types check-tests # # check and format code, style, types, and test
184
185
check-lint : check-ruff # # check code formatting and style
185
186
186
- check-ruff : $(PYBIN ) FORCE
187
+ check-ruff : $(RUFF ) FORCE
187
188
@echo " -------- Running ruff lint and formatting checks --------"
188
189
@# Check imports in addition to code
189
190
@# Reason for two commands: https://github.com/astral-sh/ruff/issues/8232
190
- # $(PYBIN)/ruff check --select I .
191
+ # . $(PYBIN)/activate && \
192
+ # ruff check --select I --fix .
191
193
# Check lints
192
- $(PYBIN ) /ruff check .
194
+ . $(PYBIN ) /activate && \
195
+ ruff check .
193
196
# Check formatting
194
- $(PYBIN ) /ruff format --check .
195
- check-types : pyright-typings $(PYRIGHT_PKG ) FORCE
197
+ . $(PYBIN ) /activate && \
198
+ ruff format --check .
199
+ check-types : pyright-typings $(PYRIGHT ) FORCE # # check types with pyright
196
200
@echo " -------- Checking types with pyright --------"
197
- $(PYBIN ) /pyright
198
- check-tests : $(PYTEST_PKG ) FORCE
201
+ . $(PYBIN ) /activate && \
202
+ pyright
203
+ check-tests : $(PYTEST ) FORCE
199
204
@echo " -------- Running tests with pytest --------"
200
- $(PYTHON ) tests/pytest/asyncio_prevent.py
201
- $(PYTEST )
205
+ . $(PYBIN ) /activate && \
206
+ python tests/pytest/asyncio_prevent.py
207
+ . $(PYBIN ) /activate && \
208
+ pytest
202
209
203
210
204
- pyright : check-types # # check types with pyright
205
- lint : check-lint # # check style with flake8
211
+ pyright : check-types
212
+ lint : check-lint
206
213
test : check-tests # # check tests quickly with the default Python
207
214
215
+ # -----------------
216
+ # Fix formatting of code
217
+ # -----------------
208
218
format : format-ruff # # format code
209
219
210
- format-ruff : $(PYBIN ) FORCE
220
+ format-ruff : $(RUFF ) FORCE
211
221
@echo " -------- Formatting code with ruff --------"
212
222
@# Reason for two commands: https://github.com/astral-sh/ruff/issues/8232
213
223
@# Fix imports
214
- $(PYBIN ) /ruff check --select I --fix .
224
+ . $(PYBIN ) /activate && \
225
+ ruff check --select I --fix .
215
226
@# Fix formatting
216
- $(PYBIN ) /ruff format .
227
+ . $(PYBIN ) /activate && \
228
+ ruff format .
217
229
218
-
219
- # format: format-black format-isort ## format code with black and isort
220
- # format-black: $(BLACK_PKG) FORCE
221
- # @echo "-------- Formatting code with black --------"
222
- # $(PYTHON) -m black .
223
- # format-isort: $(ISORT_PKG) FORCE
224
- # @echo "-------- Sorting imports with isort --------"
225
- # $(ISORT) .
226
-
227
- docs : FORCE # # docs: build docs with quartodoc
230
+ # -----------------
231
+ # Documentation
232
+ # -----------------
233
+ # Install docs deps; Used in `./docs/Makefile`
234
+ install-docs : $(UV ) FORCE
235
+ . $(PYBIN ) /activate && \
236
+ uv pip install -e " .[dev,test,doc]" \
237
+ " htmltools @ git+https://github.com/posit-dev/py-htmltools.git" \
238
+ " shinylive @ git+https://github.com/posit-dev/py-shinylive.git"
239
+
240
+ docs : $(PYBIN ) FORCE # # docs: build quartodoc docs
241
+ $(MAKE ) install-docs
228
242
@echo " -------- Building docs with quartodoc --------"
229
243
@cd docs && make quartodoc
230
244
231
- docs-preview : FORCE # # docs: preview docs in browser
245
+ docs-preview : $(PYBIN ) FORCE # # docs: preview docs in browser
246
+ $(MAKE ) install-docs
232
247
@echo " -------- Previewing docs in browser --------"
233
248
@cd docs && make serve
234
249
250
+ # -----------------
251
+ # Testing with playwright
252
+ # -----------------
253
+
235
254
# Default `SUB_FILE` to empty
236
255
SUB_FILE: =
237
256
238
- install-playwright : $(PLAYWRIGHT_PKG ) FORCE
257
+ install-playwright : $(PLAYWRIGHT ) FORCE
239
258
@echo " -------- Installing playwright browsers --------"
240
- @$(PLAYWRIGHT ) install --with-deps
259
+ @. $(PYBIN ) /activate && \
260
+ playwright install --with-deps
241
261
242
- playwright-shiny : install-playwright $(PYTEST_PKG ) FORCE # # end-to-end tests with playwright
243
- $(PYTEST ) tests/playwright/shiny/$(SUB_FILE )
262
+ playwright-shiny : install-playwright $(PYTEST ) FORCE # # end-to-end tests with playwright
263
+ . $(PYBIN ) /activate && \
264
+ pytest tests/playwright/shiny/$(SUB_FILE )
244
265
245
- playwright-deploys : install-playwright $(RSCONNECT_PKG ) $(PYTEST_PKG ) FORCE # # end-to-end tests on examples with playwright
246
- $(PYTEST ) tests/playwright/deploys/$(SUB_FILE )
266
+ playwright-deploys : install-playwright $(RSCONNECT ) $(PYTEST ) FORCE # # end-to-end tests on examples with playwright
267
+ . $(PYBIN ) /activate && \
268
+ pytest tests/playwright/deploys/$(SUB_FILE )
247
269
248
- playwright-examples : install-playwright $(PYTEST_PKG ) FORCE # # end-to-end tests on examples with playwright
249
- $(PYTEST ) tests/playwright/examples/$(SUB_FILE )
270
+ playwright-examples : install-playwright $(PYTEST ) FORCE # # end-to-end tests on examples with playwright
271
+ . $(PYBIN ) /activate && \
272
+ pytest tests/playwright/examples/$(SUB_FILE )
250
273
251
- playwright-debug : install-playwright $(PYTEST_PKG ) FORCE # # All end-to-end tests, chrome only, headed
252
- $(PYTEST ) -c tests/playwright/playwright-pytest.ini tests/playwright/$(SUB_FILE )
274
+ playwright-debug : install-playwright $(PYTEST ) FORCE # # All end-to-end tests, chrome only, headed
275
+ . $(PYBIN ) /activate && \
276
+ pytest -c tests/playwright/playwright-pytest.ini tests/playwright/$(SUB_FILE )
253
277
254
278
playwright-show-trace : FORCE # # Show trace of failed tests
255
279
npx playwright show-trace test-results/* /trace.zip
256
280
257
- testrail-junit : install-playwright $(TRCLI_PKG ) $(PYTEST_PKG ) FORCE # # end-to-end tests with playwright and generate junit report
258
- $(PYTEST ) tests/playwright/shiny/$(SUB_FILE ) --junitxml=report.xml
281
+ testrail-junit : install-playwright $(TRCLI ) $(PYTEST ) FORCE # # end-to-end tests with playwright and generate junit report
282
+ . $(PYBIN ) /activate && \
283
+ pytest tests/playwright/shiny/$(SUB_FILE ) --junitxml=report.xml
259
284
260
- coverage : $(PYTEST_PKG ) $(COVERAGE_PKG ) FORCE # # check combined code coverage (must run e2e last)
261
- $(PYTEST ) --cov-report term-missing --cov=shiny tests/pytest/ tests/playwright/shiny/$(SUB_FILE )
262
- $(PYBIN ) /coverage html
263
- $(BROWSER ) htmlcov/index.html
285
+ coverage : $(PYTEST ) $(COVERAGE ) FORCE # # check combined code coverage (must run e2e last)
286
+ . $(PYBIN ) /activate && \
287
+ pytest --cov-report term-missing --cov=shiny tests/pytest/ tests/playwright/shiny/$(SUB_FILE ) && \
288
+ coverage html && \
289
+ $(BROWSER ) htmlcov/index.html
264
290
265
- release : $(TWINE_PKG ) dist FORCE # # package and upload a release
266
- $(PYBIN ) /twine upload dist/*
291
+ # -----------------
292
+ # Release
293
+ # -----------------
294
+ release : $(TWINE ) dist FORCE # # package and upload a release
295
+ . $(PYBIN ) /activate && \
296
+ twine upload dist/*
267
297
268
298
dist : clean $(PYTHON ) FORCE # # builds source and wheel package
269
- $(PYTHON ) setup.py sdist
270
- $(PYTHON ) setup.py bdist_wheel
299
+ . $(PYBIN ) /activate && \
300
+ python setup.py sdist && \
301
+ python setup.py bdist_wheel
271
302
ls -l dist
272
-
273
- # # install the package to the active Python's site-packages
274
- # Note that instead of --force-reinstall, we uninstall and then install, because
275
- # --force-reinstall also reinstalls all deps. And if we also used --no-deps, then the
276
- # deps wouldn't be installed the first time.
277
- install : dist $(PIP ) FORCE
278
- $(PIP ) uninstall -y shiny
279
- $(PIP ) install dist/shiny* .whl
280
-
281
- install-deps : $(UV ) FORCE # # install dependencies
282
- $(UV ) pip install -e " .[dev,test]" --refresh
283
-
284
- # ## If caching is ever used, we could run:
285
- # install-deps: ## install latest dependencies
286
- # pip install --editable ".[dev,test]" --upgrade --upgrade-strategy eager
0 commit comments