Scaffold
Opt-in launcher generator: generate_launchers, runnable as
python -m duho.scaffold. Core duho never imports this module.
duho.scaffold
Opt-in launcher generator: emit a run-from-checkout launcher pair for an app.
Opt-in dev tool. Core duho never imports this module; you activate it
explicitly with import duho.scaffold or python -m duho.scaffold. Its
symbols are in this module's own __all__ but deliberately NOT on the
top-level duho.__all__ -- it is a project-scaffolding helper, not runtime
surface.
What it generates
For a target application laid out as <root>/bin/ + <root>/<libdir>/<app>
(a package importable once <root>/<libdir> is on PYTHONPATH),
:func:generate_launchers writes a matched launcher pair into <root>/bin/:
bin/<app>-- a POSIXshwrapper that resolves its own directory, computes the app root (the parent ofbin/), prepends<root>/<libdir>toPYTHONPATH, andexecs"${PYTHON:-python3}" -m <app> "$@";bin/<app>.cmd-- the Windows cousin doing the same via%~dp0and%PYTHON%(defaultpython), running%PYTHON% -m <app> %*.
Both launchers are small, dependency-free, and honor a PYTHON environment
override so a caller can pin the interpreter. The generator writes plain
files (it copies/emits text -- it never creates symlinks, which need privilege
on Windows and add failure modes); the POSIX file additionally gets its
executable bit set best-effort (skipped on platforms without chmod support).
By default an existing launcher is not clobbered -- pass overwrite=True
(--force on the CLI) to rewrite a launcher a user may have customized.
The CLI dogfoods duho itself: python -m duho.scaffold <app> [--root DIR]
[--libdir lib] [--python PY] [--force] is implemented as a :class:duho.Cmd.
generate_launchers(app, root, *, libdir='lib', python=None, overwrite=False)
Write a POSIX + Windows launcher pair for app into <root>/bin/.
Emits <root>/bin/<app> (POSIX sh) and <root>/bin/<app>.cmd
(Windows), each of which puts <root>/<libdir> on PYTHONPATH and runs
python -m <app> -- so the app runs from a checkout without being
installed. The bin/ directory is created if missing. Returns the list of
written paths (POSIX first, then .cmd).
Parameters
app:
The app's importable module name (the <app> in python -m <app>).
root:
The app root directory (the parent of bin/); bin/ is created
under it.
libdir:
The subdirectory under root holding the app package, prepended to
PYTHONPATH (default "lib"; a src-layout app passes
libdir="src").
python:
Interpreter token baked in as the default (overridable at runtime via
the PYTHON env var). None uses the per-flavor default
(python3 for POSIX, python for Windows).
overwrite:
When False (default), refuse to clobber an existing launcher --
raising :class:FileExistsError naming the first conflict, so a
user-customized launcher is never silently overwritten. True rewrites.
The generator writes plain files (never symlinks) and sets the POSIX launcher's executable bit best-effort (a no-op where the platform/filesystem doesn't support it).
Raises :class:ValueError for an app that is not a dotted ASCII
identifier, a libdir that is not a relative, ..-free ASCII path
free of quote/backtick/$/%/backslash/newline characters, or a
python with the same forbidden characters -- all three are
interpolated into generated shell/batch text, so a
hyphenated/path-like/hostile value would otherwise produce a launcher that
cannot work, escapes bin/, or executes unintended commands.
Source code in src/duho/scaffold.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | |
main(argv=None)
python -m duho.scaffold entry point: dispatch :class:ScaffoldCmd.
Source code in src/duho/scaffold.py
339 340 341 | |
CLI
duho.scaffold.ScaffoldCmd is the duho.Cli command backing
python -m duho.scaffold; run python -m duho.scaffold --help for its full,
generated usage (<app> [--root DIR] [--libdir lib] [--python PY] [--force]).