Skip to content

Git-based template system: implement Phases 2-6 (catalog client, list/search/refresh/new, polyglot engine) #16998

@mitchdenny

Description

@mitchdenny

Background

PR #16927 landed Phase 1 of the git-based template system: spec, gitTemplatesEnabled feature flag, and four stub subcommands behind it (aspire template list, search, refresh, new). This issue tracks the remaining phases needed to make the feature actually usable.

This work resumes the spike from PR #14763, but with a key architectural change: template discovery is delegated to a single aspire.dev HTTP endpoint instead of a federated walk of aspire-template-index.json files. That removes per-repo index files, includes federation, gh-based personal/org auto-discovery, and the aspire template new-index command. CLI configuration collapses to templates.serviceUrl + templates.cacheTtlMinutes.

The full architecture is in docs/specs/git-templates.md. The phased plan is in §15 of that spec.

Current state (shipped in #16927)

  • KnownFeatures.GitTemplatesEnabled (default false).
  • aspire template command group wired into RootCommand behind the flag.
  • 4 stub subcommands that print "not yet implemented" and return Success.
  • 15 parse / feature-flag-gating tests, all passing.
  • No real implementation behind any of the commands yet.

Enable for local smoke testing:

aspire config set features.gitTemplatesEnabled true
aspire template --help

Remaining phases

Each phase below should ship as its own PR so reviews stay focused.

Phase 2: Catalog client + caching primitives

  • HTTP client for GET {templates.serviceUrl}/templates/index.json?q=&language=&limit=&cursor= with response shape per spec §3.
  • Disk cache layout under ~/.aspire/templates/:
    • index/ — HTTP-cached catalog responses keyed by full URL, honoring templates.cacheTtlMinutes (default TBD; see §13).
    • repos/<repo-hash>/<sha>/ — content-addressed git checkouts (no writes after phase 2).
  • templates.serviceUrl + templates.cacheTtlMinutes config keys with sensible defaults.
  • Decide cache size budget and eviction policy (open question in spec §13).
  • Tests: catalog client (with a fake HttpMessageHandler), TTL behavior, malformed payload handling, cursor pagination.

Phase 3: aspire template list + aspire template search <keyword>

  • Wire the catalog client into the list and search stubs.
  • Render results as a Spectre table (name, description, language, tags, publisher, verified badge).
  • Honor --language, --limit, paging via --cursor or auto-page-on-demand (decide which).
  • Tests: end-to-end with a faked catalog response; verify rendering, filtering, and pagination.

Phase 4: aspire template refresh

  • Force-refresh both the index cache and (optionally) any pre-fetched repo checkouts.
  • Decide whether refresh is global or accepts a --template <name> filter.
  • Tests: confirm cache invalidation observable in subsequent list calls.

Phase 5: aspire template new <name> [path] (single-template, .NET only)

  • Resolve <name> against the catalog → (repo, ref, path).
  • Clone or fetch into the content-addressed repos/ cache; checkout the resolved sha.
  • Apply the template via the existing dotnet template engine path (per-template manifest in spec §4 and §7).
  • Stay .NET-only for this phase; defer polyglot to phase 6.
  • Tests: full flow against a local fake git server (or git file:// remote in a temp dir); verify content lands on disk and engine variables are wired.

Phase 6: Polyglot engine support

  • Implement the language-agnostic template engine described in spec §11 (token replacement, file renaming, conditional inclusion).
  • Honor per-template manifest opting into the polyglot engine instead of the dotnet template engine.
  • Tests: end-to-end with a representative non-.NET template (Node, Python, etc.).

Cross-cutting open questions (spec §13)

These need answers before / alongside the phases above:

  • Final shape of the aspire.dev/templates/index.json response. Current schema in spec §3 is a placeholder.
  • Catalog governance: who decides what gets listed, how malicious entries are removed, signing strategy (security review TBD; spec §10 currently has a TODO).
  • Cache size budget + eviction policy.
  • Whether the catalog host is literally aspire.dev or some other domain.
  • Telemetry: what events to emit on list/search/new for catalog feedback.

References

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions