Skip to content

Identifiable container names (template-based naming for both modes)#1

Open
mpasternak wants to merge 13 commits into
mainfrom
feature/identifiable-container-names
Open

Identifiable container names (template-based naming for both modes)#1
mpasternak wants to merge 13 commits into
mainfrom
feature/identifiable-container-names

Conversation

@mpasternak

Copy link
Copy Markdown
Member

Summary

Every container the plugin starts now gets a readable, identifiable name in both default and reuse mode, instead of Docker's random names (heuristic_cannon, nifty_ganguly). The name is rendered from a configurable template and encodes project + service + git branch + directory + worker.

Default template:

{project}-tc-{service}-{branch}-{dirtag}-{worker}

e.g. myproj-tc-psql-feature-x-3f9ac1b2-master

What's new

  • Naming in both modes. Default-mode containers (previously unnamed) now carry the templated name with a 4-hex {rand} suffix so overlapping/leaked runs never collide. Reuse-mode names are byte-stable ({rand} empty) so find-or-create still works, and are now scoped per (project, service, branch, directory, worker).
  • Configurable template (--testcontainers-name-template > PYTEST_TESTCONTAINERS_NAME_TEMPLATE > pyproject [tool.pytest_testcontainers].name_template > built-in default). Placeholders: {project} {service} {branch} {dir} {dirtag} {worker} {rand}. An unknown/typo'd placeholder raises NameTemplateError.
  • Extended project-name precedence: --testcontainers-project > PYTEST_TESTCONTAINERS_PROJECT > PROJECT_NAME > COMPOSE_PROJECT_NAME > pyproject [project].name > cwd basename.
  • Git identity without a subprocess: new _internal/git_identity.py reads .git/HEAD directly (handles normal clones, linked worktrees, and detached HEAD → 12-char SHA). {dirtag} is an 8-hex blake2s of the worktree-root absolute path, so the same branch checked out in two directories does not collide.
  • 255-char safety: finalize_name sanitizes the whole rendered name and, on overflow, truncates to 246 and appends an 8-char hash of the full name (deterministic, so reuse stays stable).

Backward compatibility (pre-1.0)

  • Default-mode containers are now named (the desired fix).
  • Reuse-mode name format changed, so containers reused from v0.1.0 are not found by name — a fresh one is created and the old one lingers until pytest --testcontainers-clean. Documented in the README "Upgrading from 0.1.0" note and SPEC §8.7.

Layering

Direction preserved (plugin → fixtures → makers → containers → _internal; errors is a leaf). reuse.py gained downward edges to _internal.git_identity and errors.NameTemplateError only.

Testing

  • New unit tests (no Docker): template expansion + empty-placeholder collapse, both precedence chains, branch/worktree/detached-HEAD detection, dirtag stability, finalize_name (≤255, deterministic, tail-distinguishing), reuse byte-stability vs. default {rand}, unknown/miscased placeholder → NameTemplateError, maker naming in both modes.
  • New docker_required smoke tests: a real default-mode container carries the templated name; reuse identity differs across branches.
  • Full unit suite green (82 passed); ruff check + format clean. Docs in README, SPEC.md, CLAUDE.md updated.

Process notes

Built via spec → plan → subagent-driven TDD (one implementer + reviewer per task, plus a final whole-branch review). Design and plan live under docs/superpowers/.

🤖 Generated with Claude Code

mpasternak and others added 13 commits June 18, 2026 15:09
Template-based naming of plugin containers in both default and reuse
mode, encoding (project, service, branch, dirtag, worker) with a
configurable name_template, PROJECT_NAME/COMPOSE_PROJECT_NAME project
resolution, and a deterministic 255-char trim+checksum.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…wd basename

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…_name_for

Rewire makers to container_name_for so containers are named in both default
and reuse mode (folds the makers import/call update forward to keep the
package importable after reuse_name_for is removed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Widen the placeholder regex so any {token} is checked against the valid set;
previously only lowercase tokens were validated, so {Project}/{dir2} silently
passed through and got mangled instead of raising NameTemplateError.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace lingering <project>-tc-<service>-<worker_id> references and the
stale §8.4 _compose snippet (digest_size=2 / name[:250]) with the shipped
finalize_name behavior (digest_size=4, [:246], hash of the full name) and
the default template. The normative §8.3 / §8.7 were already correct; this
clears the descriptive drift the final review flagged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant