Template 0.1.23: no template placeholder in the installer
Design note for the 0.1.23 migration (.template_sync/migrations/v0_1_22_to_v0_1_23.py), issue #40. How a change reaches an installed copy is described in migration_0_1_16.md: a new installer is needed, nothing edits an existing install.
1. The problem
The template's files hold placeholders (PROJECT_NAME, PYTHON_PROJ_NAME, ...) that the repository initialisation, the LabConstrictor form (CellMigrationLab/LabConstrictor_streamlit), replaces with the app's names. It replaces each placeholder only in the files it lists for it, and three files were missing from those lists:
| File | Placeholder left | Effect |
|---|---|---|
app/bash_bat_scripts/post_install.sh and .bat |
PYTHON_PROJ_NAME (since template 0.1.16) |
An app with Python code in src/ cannot be installed: the last step runs import PYTHON_PROJ_NAME and fails with No module named 'PYTHON_PROJ_NAME'. Found with StarDist2D 1.0.0. |
app/python_scripts/launch_jupyter.py |
PROJECT_NAME |
The launcher's error messages say "PROJECT_NAME could not start". |
.tools/templates/Welcome_template.ipynb |
PROJECT_NAME |
The Welcome notebook says "Welcome to PROJECT_NAME!" (LabConstrictor Playground). |
Apps that reached 0.1.16 through the migrations are not affected by the first row: the 0.1.16 migration wrote the package name. Nothing caught it, because the workflows never install the installers they build.
2. What changes
| Part | Change |
|---|---|
The form (LabConstrictor_streamlit) |
The three files are added to its placeholder lists (placeholders.py), and the form refuses to open its pull request when a placeholder is left in a file the installer ships. Its tests initialise a clone of the template's main (in its CI, also every week), so a placeholder added to the template later is caught too. |
.tools/python/check_placeholders.py (new) |
Fails when an initialisation placeholder is left in a file the installer ships (app/**, construct.yaml, setup.py, environment.yaml), and names the file, the line and the fix. It also refuses the raw, uninitialised template. Placeholders filled in later on purpose are not checked: BASE_PATH_KEYWORD (at install), PYTHON_VERSION and JUPYTERLAB_VERSION (by the requirements workflow). |
.github/workflows/release_constructor.yml |
Runs the check in both jobs, right after bump_Welcome_notebook.py: before the version commit and before any installer is built. |
The check fails the release rather than fixing the files itself: the maintainer sees what was wrong, fixes the repository once, and publishes the release again.
3. What the migration does
Every step is independent, idempotent, never deletes, never raises for a customised file (the sync pull request is still created) and keeps the line endings of each file.
- Placeholders. In
post_install.sh,post_install.bat,launch_jupyter.pyandWelcome_template.ipynb, a placeholder that is still there is replaced:PYTHON_PROJ_NAMEwith the app's Python package,PROJECT_NAMEwith the app name. A file without placeholders isunchanged. - The package is found as in the 0.1.16 migration: the single
<package>_lc_toolsmodule insrc/, else the single package insrc/, else the name insetup.py, else the[project]name ofpyproject.toml. When none is found, the file isSKIPPED: replace the placeholder by hand. - The app name is the
menu_nameofapp/menuinst/notebook_launcher.json, which the form wrote, elsePROJECT_DISPLAY_NAMEinlaunch_jupyter.py. - The check.
.tools/python/check_placeholders.pyis created. A repository with its own file of that name keeps it (SKIPPED). - The workflow. The check is added after the
bump_Welcome_notebook.pycommand in each job ofrelease_constructor.yml. A workflow without that command (customised) isSKIPPED: add the five lines by hand (see the template's file). - An uninitialised repository (
construct.yamlstill namesUNDERSCORED_PROJECT_NAME) is not touched.
4. Adopting it
Take this template version (the synchronization pull request) and release a new installer. If the release stops at "check_placeholders.py", its log lists each file and line: replace the placeholder there, commit, and publish the release again. Installed copies do not change: reinstall.
5. What is checked here, and what is not
- Tests (
tests/test_template_sync_0_1_23.py): the check on clean and broken apps; the migration on a broken 0.1.22 app (then the check passes and a second run changes nothing), on a healthy app, with CRLF, an unknown package, a customised workflow and the raw template; the sync chain from 0.1.22; the live workflow equals the 0.1.22 workflow migrated. - The check was run after the release scripts (
bump_version.py,bump_constructor.py,bump_Welcome_notebook.py) on copies of NucleiSky, LabConstrictor Playground, Guess the Condition, LabConstrictor_Demo, LabChronicle, CellTracksColab, StarDist2D, CellPatcher and VLab4Mic. It passes for all of them except the Playground, whose Welcome notebook really says "Welcome to PROJECT_NAME!": the migration repairs it. - The installers themselves are not built or installed by these tests.