Release v3.4.0
Summary
Implements issue #150: a self-contained template engine (Cratis.Templating) compatible with the dotnet new template.json format, and the cratis new command on top of it. Acquiring, rendering and finishing a template — including resolving Version="*" package references to concrete versions — works on a machine with no .NET installed at all. The engine core is derived from dotnet/templating (MIT) with attribution retained; no Microsoft.TemplateEngine.* dependency anywhere.
Added
Cratis.Templating— a template engine implementing the full currenttemplate.jsoncontract: all 24 published top-level properties plusglobalCustomOperations/specialCustomOperations, all five symbol types, all 12 generators, the full value-form set, the four condition evaluators (C++, C++2, MSBuild, VB), conditional processing for every documented file family (including MSBuildConditionattributes), custom operations, constraints, baselines, localization overlays, and GUID replacement — with unknown constructs failing loudly by name rather than being ignored (#150)cratis new— lists the catalogued templates and instantiates them with dotnet-new compatible-n/-osemantics, dynamic parameter binding with choice validation,--parametershelp,--dry-run,--force, interactive prompts with non-interactive equivalents, the explicit--allow-scripts yes|no|promptcontract for script post actions, and JSON output via--format(#150)- Template package acquisition through the CLI's own NuGet v3 client — service index/flat container,
NuGet.Configdiscovery with credentials, local folder feeds, an offline-capable disk cache under~/.cratis/templatesisolated from the dotnet template store (#150) - All eight documented post actions implemented natively — package/project references added by editing project XML with versions resolved through the same NuGet configuration,
.sln/.slnxwritten directly, file permissions, JSON properties, manual instructions, script execution under the explicit policy, and restore (the one toolchain-dependent action) reported with instructions when dotnet is absent (#150) - Unit specs for the engine (expressions, conditionals, symbols, value forms, parsing, instantiation, post actions, globs, NuGet configuration and client, the package store, token replacement, file family detection, constraints, localization, baselines, placeholder filenames and GUID replacement), CLI specs for parameter binding, the catalogue and settings validation, and a conformance suite rendering vendored templates through the real engine (#150)
- The upstream
Microsoft.TemplateEngine.TestTemplatescorpus (MIT, 56 groups, 100 manifests) vendored at a pinned upstream commit with provenance recorded, and a phase-one conformance gate that parses every manifest: 98 parse cleanly, the two intentionally-invalid templates fail with named errors, and none fail silently (#150) cratis new --language— required when instantiating:csharp(C#;c#accepted),kotlinorjava, case-insensitive. The language selects the template package and the template used when none is named —csharpinstantiates thecratistemplate fromCratis.Templatestoday, andkotlin/javaare wired for their comingcratis-kotlin/cratis-javapackages, resolving to a named error until those publish (#150)cratis new --database— selects the database backend for the scaffolded application (mongodbdefault, pluspostgresql,mssql,sqlite, matched case-insensitively). The selection becomes the template'sDatabaseparameter value — injected in the choice's canonical casing — so templates author database support like any parameter; templates without the parameter reject an explicit selection with a named error (#150)- A differential oracle that renders the four Cratis templates through both this engine and
dotnet newand diffs the trees — opt-in viaCRA_TIS_DIFFERENTIAL=1, isolatedDOTNET_CLI_HOME, and strictly a test-time oracle. It is green: all four templates render byte-equivalently todotnet new, modulo generated GUIDs, resolved versions and years. Building it surfaced and fixed two real engine defects: a child-process pipe-drain deadlock in script/restore post actions, and add-reference fidelity (in-placeVersion="*"replacement preserving indentation, and honoring the documentedtargetFilesargument) (#150) - Documentation: the creating-projects guide and template catalogue under
Documentation/new/, a README section,THIRD-PARTY-NOTICES.mdfor the derived engine core, andSPECIFICATION.mdrecording the implemented contract version and source precedence (#150)
Changed
- The CLI solution gains the
Cratis.Templating,Cratis.Templating.SpecsandCratis.Templating.Conformanceprojects;Cratis.Clireferences the engine for the new command (#150) - Manifest parsing now matches the upstream corpus exactly: case-insensitive property names with insignificant whitespace,
precedence/rename/generatorVersionsalternate forms, string-array post action arguments, boolean condition literals, and the legacyonlyIf/id/applyFileRenamesTo*properties accepted (#150)