Deploy-time placeholders were spread across four independent
implementations: sed in the Gitea deploy script, ansible.builtin.replace
in two playbooks, a hardcoded suffix in bin/sls_hla_launch_gui.sh, and
another in agebd/pv.py. Each defined its own values, so nothing kept them
in sync and a missed substitution failed silently.
Step 1 -- one source of truth:
* config/environments.yml declares every deploy-time token, its value
per environment, and where tokens are allowed to live. An environment
that is missing a token, or defines an undeclared one, is a load-time
error.
* agebd.subs loads it and renders. Rendering is a strict regex over
declared token names rather than a template engine: the rendered
files are EPICS db/substitution files and Qt XML, and an unknown
token must raise rather than survive into the output.
* scripts/ci/check_subs.py enforces the contract in CI: tokens in a
rendered path are declared, declared tokens only appear where they
are rendered or generated, and no pre-migration delimiters survive.
Step 2 -- separate the two substitution stages by delimiter:
* Creation-time (copier, once per new service) keeps {{ token }}.
Deploy-time (every deploy, per environment) becomes @@token@@.
* This drops the {{ '{{ token }}' }} escaping from templates/, which
existed only because one Jinja pass had to emit syntax for a second.
* Angle brackets were tried first and rejected: << >> is not
well-formed XML, and cli parses qt/*.ui with ElementTree.
* The existing sed and ansible consumers are repointed at the new
delimiters so this stays behaviour-preserving. Routing them through
agebd.subs is step 3.
Also fixes, as a side effect of having one implementation:
* The sed pattern '{{ *agebd_env_suffix_upper* }}' quantified 'r'
rather than the space, so it only matched one exact spacing.
* agebd.subs.read_ioc_port compares service names case-insensitively;
ansible/tasks/utils/get-ioc-port.yml still compares CamelCase
registry names against a lowercase input and never matches.
qt/*.ui is declared as a render path but nothing renders it yet -- the
Qt deploy step is still a plain rsync. Wiring that up is step 4.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
43 lines
680 B
TOML
43 lines
680 B
TOML
[project]
|
|
name = "agebd"
|
|
version = "0.1.0"
|
|
description = "SLS HLA Framework"
|
|
requires-python = "==3.10.*"
|
|
|
|
dependencies = [
|
|
"h5py>=3.16.0",
|
|
"pyepics>=3.5.10",
|
|
"typer>=0.23.2",
|
|
"gitpython>=3.1.50",
|
|
"pyyaml>=6.0.3",
|
|
]
|
|
|
|
# Dev dependencies
|
|
[dependency-groups]
|
|
dev = [
|
|
"pyright>=1.1.410",
|
|
"pytest>=8.4.2",
|
|
"pytest-env>=1.7.0",
|
|
"pytest-mock>=3.15.1",
|
|
"ruff>=0.15.19",
|
|
"twine>=6.2.0",
|
|
]
|
|
|
|
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[tool.uv]
|
|
package = true
|
|
|
|
[tool.ruff]
|
|
include = [
|
|
"src/**/*.py",
|
|
"tests/**/*.py",
|
|
]
|
|
line-length = 100
|
|
|
|
[tool.ruff.lint]
|
|
# use isort to sort imports
|
|
extend-select = ["I"]
|