Skip to content

feat: create dotnet new project templates for analyzer/generator projects #5

Description

@crazycrank

Context

Creating a new Roslyn analyzer or source generator project that uses Scribe requires significant manual setup — even more so now that the Scribe SDK (#4) is in place, because the SDK's existence makes it possible to scaffold a fully working project from a template with zero manual configuration.

Currently, developers must:

  1. Create a new class library project
  2. Manually configure all analyzer/generator properties (or adopt the SDK)
  3. Add the correct PackageReferences with the right PrivateAssets settings
  4. Set up the test project with analyzer testing infrastructure
  5. Configure LocalDev if working cross-repo

dotnet new templates can automate all of this into a single command.

Goal

Create a template pack NuGet package (BulletsForHumanity.Scribe.Templates) containing project templates that scaffold fully working analyzer/generator projects.

Depends on: #4 (Scribe SDK) — templates use the SDK.
Related: #8 (Solution Analyzer support) — templates should consider the standalone vs. solution-local distinction.

Key Design Decisions (from SDK implementation)

  • Templates must use the Scribe SDK (<Project Sdk="BulletsForHumanity.Scribe.Sdk">) — not raw boilerplate
  • Templates auto-include BulletsForHumanity.Scribe as a PackageReference — the SDK deliberately does not auto-reference Scribe (to support SDK-only use cases), but templates should include it since they scaffold generator/analyzer code that uses Quill and other Scribe APIs
  • global.json with SDK version symbol — each template includes a global.json with "msbuild-sdks": { "BulletsForHumanity.Scribe.Sdk": "{{SdkVersion}}" }, where {{SdkVersion}} is a template symbol injected at install time from the template pack version

Proposed templates

1. scribe-analyzer — Roslyn Analyzer Project

Scaffolds a project with:

  • Scribe SDK via global.json
  • PackageReference to BulletsForHumanity.Scribe (auto-included)
  • PackageReference to Microsoft.CodeAnalysis.CSharp
  • A sample DiagnosticAnalyzer with a DiagnosticDescriptor
  • A companion code fixer
dotnet new scribe-analyzer -n MyAnalyzer

2. scribe-generator — Roslyn Source Generator Project

Scaffolds a project with:

  • Scribe SDK via global.json
  • PackageReference to BulletsForHumanity.Scribe (auto-included)
  • PackageReference to Microsoft.CodeAnalysis.CSharp
  • A sample IIncrementalGenerator using the Transform → Register → Render pattern
  • Quill usage for source output (demonstrating the recommended pattern)
dotnet new scribe-generator -n MyGenerator

3. scribe-analyzer-test — Analyzer/Generator Test Project

Scaffolds a test project with:

  • xUnit v3, Shouldly
  • CSharpAnalyzerVerifier / CSharpCodeFixVerifier setup from Microsoft.CodeAnalysis.Testing
  • A sample test that verifies the sample analyzer from template 1 or 2
  • Project reference to the analyzer/generator project
dotnet new scribe-analyzer-test -n MyAnalyzer.Tests

Implementation plan

1. Template pack structure

templates/
  scribe-analyzer/
    .template.config/
      template.json
    MyAnalyzer.csproj
    SampleAnalyzer.cs
    SampleCodeFix.cs
  scribe-generator/
    .template.config/
      template.json
    MyGenerator.csproj
    SampleGenerator.cs
  scribe-analyzer-test/
    .template.config/
      template.json
    MyAnalyzer.Tests.csproj
    SampleAnalyzerTests.cs
BulletsForHumanity.Scribe.Templates.csproj   ← pack-only project

2. template.json configuration

Each template needs:

  • identity, shortName, sourceName (for name substitution)
  • tags for discoverability (type: project, language: C#)
  • symbols for template parameters (e.g. --framework for optional multi-targeting)
  • sources with rename/exclude rules

3. Pack as a template NuGet package

The .csproj uses <PackageType>Template</PackageType> and includes the template directories as content.

4. Installation and usage

# Install
dotnet new install BulletsForHumanity.Scribe.Templates

# Use
dotnet new scribe-analyzer -n MyAnalyzer
dotnet new scribe-analyzer-test -n MyAnalyzer.Tests

Templates also appear in Visual Studio's "New Project" dialog automatically once installed.

Hints

  • See Microsoft's template authoring docs for the template.json schema.
  • The sourceName field in template.json controls find-and-replace of the template name (e.g. "sourceName": "MyAnalyzer" → replaced with whatever -n value the user provides).
  • Include a global.json in the template with "msbuild-sdks": { "BulletsForHumanity.Scribe.Sdk": "version" } — use a template symbol to inject the current SDK version.
  • The sample analyzer/generator code should be simple but functional — a real diagnostic that fires, a real generator that emits code. Not just empty stubs.
  • Consider using the Quill builder in the generator template sample to demonstrate the recommended pattern.

Acceptance criteria

  • dotnet new install BulletsForHumanity.Scribe.Templates installs successfully
  • dotnet new scribe-analyzer -n Foo creates a buildable analyzer project using the Scribe SDK with Scribe auto-included
  • dotnet new scribe-generator -n Foo creates a buildable generator project using the Scribe SDK with Scribe auto-included
  • dotnet new scribe-analyzer-test -n Foo.Tests creates a buildable test project
  • Generated global.json contains the correct SDK version symbol
  • The sample analyzer produces a real diagnostic when built and consumed
  • The sample generator produces real source output when built and consumed
  • The sample test project passes with dotnet test
  • Templates appear in Visual Studio's "New Project" dialog after installation
  • dotnet pack on the generated projects produces correct analyzer NuGet packages
  • Documentation: README updated with template installation and usage instructions

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions