Skip to content
Merged

frist #512

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# RSCG - 276 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
# RSCG - 277 Examples of Roslyn Source Code Generators / 16 created by Microsoft /

The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 276 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports.
The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 277 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports.

This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem

## Latest Update : 2026-07-03 => 03 July 2026
## Latest Update : 2026-07-04 => 04 July 2026

If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)***

Expand All @@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt

## Content

Those are the 276 Roslyn Source Code Generators that I have tested you can see and download source code example.
Those are the 277 Roslyn Source Code Generators that I have tested you can see and download source code example.
( including 16 from Microsoft )
### 277. [Bennewitz.Ninja.AutoVersioning](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Bennewitz.Ninja.AutoVersioning) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category

Generated on : 2026-07-04 => 04 July 2026

<details>
<summary>Expand</summary>



Author: Brian Bennewitz

Assembly info incremental source generator.

Nuget: [https://www.nuget.org/packages/Bennewitz.Ninja.AutoVersioning/](https://www.nuget.org/packages/Bennewitz.Ninja.AutoVersioning/)


Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/Bennewitz.Ninja.AutoVersioning](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Bennewitz.Ninja.AutoVersioning)

Source: [https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning](https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning)

</details>

### 276. [TinyBDD.MSTest](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TinyBDD.MSTest) , in the [Tests](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#tests) category

Generated on : 2026-07-03 => 03 July 2026
Expand Down
2 changes: 1 addition & 1 deletion later.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Just later

## Latest Update : 2026-07-03 => 03 July 2026
## Latest Update : 2026-07-04 => 04 July 2026



Expand Down
36 changes: 36 additions & 0 deletions v2/.tours/Bennewitz.Ninja.AutoVersioning.tour
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

{
"$schema": "https://aka.ms/codetour-schema",
"title": "Bennewitz.Ninja.AutoVersioning",
"steps":
[
{
"file": "rscg_examples/Bennewitz.Ninja.AutoVersioning/src/InfoPrj/InfoPrj.csproj",
"description": "First, we add Nuget [Bennewitz.Ninja.AutoVersioning](https://www.nuget.org/packages/Bennewitz.Ninja.AutoVersioning/) in csproj ",
"pattern": "Bennewitz.Ninja.AutoVersioning"
}

,{
"file": "rscg_examples/Bennewitz.Ninja.AutoVersioning/src/InfoPrj/Program.cs",
"description": "File Program.cs \r\n>> dotnet run --project rscg_examples/Bennewitz.Ninja.AutoVersioning/src/InfoPrj/InfoPrj.csproj ",
"pattern": "this is the code"
}
Comment on lines +14 to +17


,{
"file": "rscg_examples/Bennewitz.Ninja.AutoVersioning/src/InfoPrj/obj/GX/Bennewitz.Ninja.AutoVersioning.SourceGenerators/Bennewitz.Ninja.AutoVersioning.SourceGenerators.AssemblyInfoGenerator/DirectoryBuildInfo.g.cs",
"description": "Generated File 2 from 2 : DirectoryBuildInfo.g.cs ",
"line": 1
}

,{
"file": "rscg_examples/Bennewitz.Ninja.AutoVersioning/src/InfoPrj/obj/GX/Bennewitz.Ninja.AutoVersioning.SourceGenerators/Bennewitz.Ninja.AutoVersioning.SourceGenerators.AssemblyInfoGenerator/AutoVersionedAssemblyInfo.g.cs",
"description": "Generated File 1 from 2 : AutoVersionedAssemblyInfo.g.cs ",
"line": 1
}

],

"ref": "main"

}
3 changes: 3 additions & 0 deletions v2/Generator/MultiGeneratorV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ public string[] SourceNoRSCG()
if (File.Exists(nameFile))
{
var text=await File.ReadAllTextAsync(nameFile);
text = text.Replace("(Directory.Build.props.template", $"({d.Generator!.Source}/Directory.Build.props.template");
text = text.Replace("(Build.ps1.template", $"({d.Generator!.Source}/Build.ps1.template");
text = text.Replace("(Build.sh.template", $"({d.Generator!.Source}/Build.sh.template");
text = text.Replace("(examples/", $"({d.Generator!.Source}/examples/");
text = text.Replace("(tests/", $"({d.Generator!.Source}/tests/");

Expand Down
1 change: 1 addition & 0 deletions v2/Generator/all.csv
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,4 @@ Nr,Key,Source,Category
274,Dirge, https://github.com/IkuzakIkuzok/Dirge,Disposer
275,Porticle.Enumly, https://github.com/Machibuse/Porticle.Enumly,Enum
276,TinyBDD.MSTest, https://github.com/JerrettDavis/TinyBDD,Tests
277,Bennewitz.Ninja.AutoVersioning, https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning,EnhancementProject
6 changes: 6 additions & 0 deletions v2/RSCGExamplesData/GeneratorDataRec.json
Original file line number Diff line number Diff line change
Expand Up @@ -1672,5 +1672,11 @@
"Category": 13,
"dtStart": "2026-07-03T00:00:00",
"show": true
},
{
"ID":"Bennewitz.Ninja.AutoVersioning",
"Category": 1,
"dtStart": "2026-07-04T00:00:00",
"show": true
}
]
22 changes: 22 additions & 0 deletions v2/rscg_examples/Bennewitz.Ninja.AutoVersioning/description.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"generator":{
"name":"Bennewitz.Ninja.AutoVersioning",
"nuget":[
"https://www.nuget.org/packages/Bennewitz.Ninja.AutoVersioning/"
],
"link":"https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning",
"author":"Brian Bennewitz",
"source":"https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning"
},
"data":{
"goodFor":["Generating build version numbers for .NET projects"],
"csprojDemo":"InfoPrj.csproj",
"csFiles":["Program.cs"],
"excludeDirectoryGenerated":[""],
"includeAdditionalFiles":[""]
},
"links":{
"blog":"",
"video":""
}
}
1 change: 1 addition & 0 deletions v2/rscg_examples/Bennewitz.Ninja.AutoVersioning/nuget.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Assembly info incremental source generator.
163 changes: 163 additions & 0 deletions v2/rscg_examples/Bennewitz.Ninja.AutoVersioning/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Bennewitz.Ninja.AutoVersioning

A [Roslyn incremental source generator](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) that injects assembly metadata attributes and build-time constants into .NET projects at compile time — no `AssemblyInfo.cs`, no disk writes, full IDE caching.

[![NuGet](https://img.shields.io/nuget/v/Bennewitz.Ninja.AutoVersioning.svg)](https://www.nuget.org/packages/Bennewitz.Ninja.AutoVersioning)
[![CI](https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning/actions/workflows/ci.yml/badge.svg)](https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning/actions/workflows/ci.yml)

## Requirements

.NET SDK 6.0 or later (requires Roslyn 4.0+ for `IIncrementalGenerator` support). The consuming project may target any framework — `.NET Framework 4.x`, `.NET Standard`, `.NET 6+`, etc.

## Quick Start

**1. Add the package:**

```xml
<PackageReference Include="Bennewitz.Ninja.AutoVersioning" Version="x.x.x" />
```

**2. Enable the generator** in your root `Directory.Build.props` (or any `.props` / `.csproj` imported by your build):

```xml
<PropertyGroup>
<GenerateAutoVersionedAssemblyInfo>true</GenerateAutoVersionedAssemblyInfo>
<AssemblyCompany>YourCompany</AssemblyCompany>
<AssemblyProduct>YourProduct</AssemblyProduct>

<!-- Optional: map your CI provider's variables -->
<CommitSha Condition="'$(CommitSha)' == ''">$(GITHUB_SHA)</CommitSha>
<IsContinuousIntegration>$(GITHUB_ACTIONS)</IsContinuousIntegration>
<PublicVersion Condition="'$(PublicVersion)' == ''">$(MY_VERSION_VAR)</PublicVersion>
</PropertyGroup>
```

> **Note:** The package's auto-imported `Build.props` automatically suppresses the 8 SDK-generated attributes that conflict with this generator (e.g. `AssemblyVersion`, `AssemblyCopyright`). It uses granular per-attribute suppressions rather than `<GenerateAssemblyInfo>false</GenerateAssemblyInfo>`, which means `InternalsVisibleTo` and all other SDK-generated attributes continue to work normally. Do **not** add `<GenerateAssemblyInfo>false</GenerateAssemblyInfo>` yourself — it will break `InternalsVisibleTo`.

A ready-to-use template is available at [`Directory.Build.props.template`](Directory.Build.props.template).

**3. Build.** The generator runs automatically — no further setup needed.

> **Tip:** View the generated files in your IDE under `Dependencies → Analyzers → *SourceGenerators`.

---

## Generated Output

Given a build on 2026-04-29 at 14:35 UTC for company `Acme Corp`, product `Acme App`, commit `abc1234def`, and public version `3.1.0`:

### `AutoVersionedAssemblyInfo.g.cs`

```csharp
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyDescription("Assembly Version: 2026.2.429.1435")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("Acme Corp")]
[assembly: AssemblyProduct("Acme App v2026.2.429.1435")]
[assembly: AssemblyCopyright("Copyright 2026 [Release]")]
[assembly: AssemblyVersion("2026.2.429.1435")]
[assembly: AssemblyFileVersion("2026.2.429.1435")]
[assembly: AssemblyInformationalVersion("Commit♥: abc1234def")]
[assembly: AssemblyMetadata("CommitSha", "abc1234def")]
[assembly: AssemblyMetadata("GITHUB_SHA", "abc1234def")]
[assembly: AssemblyMetadata("PublicVersion", "3.1.0")]
```

### `DirectoryBuildInfo.g.cs`

```csharp
// <auto-generated/>
namespace Bennewitz.Ninja.AutoVersioning
{
/// <summary>Build-time constants generated by the source generator.</summary>
public static class DirectoryBuildInfo
{
public const string BuildRelease = "Version 2026.2.429.1435 [built 4/29/2026 2:35:00 PM (UTC)]";
}
}
```

Use `DirectoryBuildInfo.BuildRelease` wherever you need the build version at runtime — error trackers, log enrichment, health endpoints — without reading environment variables.

---

## Configuration Reference

| MSBuild Property | Description | Required |
|---|---|---|
| `GenerateAutoVersionedAssemblyInfo` | Set to `true` to enable the generator | **Yes** |
| `AssemblyCompany` | Value for `[assembly: AssemblyCompany(...)]` | **Yes** |
| `AssemblyProduct` | Value for `[assembly: AssemblyProduct(...)]` | **Yes** |
| `CopyrightHolder` | Name shown in the copyright attribute — defaults to `AssemblyCompany` if omitted | No |
| `CommitSha` | Git commit SHA | No |
| `IsContinuousIntegration` | `true` on CI runs | No |
| `PublicVersion` | Your app's public-facing version string | No |
| `Configuration` | `Debug` / `Release` — set automatically by MSBuild | Auto |
| `BuildTimestamp` | Build start time in `yyyyMMddHHmmss` format — captured automatically at MSBuild evaluation time (before any project compiles), ensuring a consistent version across all projects in a multi-project solution build. Override on CI for an exact guarantee: `dotnet build -p:BuildTimestamp=$(date +%Y%m%d%H%M%S)` | Auto |

### CI Provider Mappings

| Provider | Commit SHA | CI flag |
|---|---|---|
| GitHub Actions | `$(GITHUB_SHA)` | `$(GITHUB_ACTIONS)` |
| GitLab CI | `$(CI_COMMIT_SHA)` | `$(GITLAB_CI)` |
| Bitbucket Pipelines | `$(BITBUCKET_COMMIT)` | `$(CI)` |

### Version Format

The generator uses **CalVer**: `YEAR.QUARTER.MMDD.HHmm`

| Part | Example | Meaning |
|---|---|---|
| Major | `2026` | Calendar year |
| Minor | `2` | Quarter (1–4) |
| Build | `429` | Month + day (`MMdd` as integer) |
| Revision | `1435` | Hour + minute (`HHmm` as integer) |

---

## How It Works

This is a modern C# `IIncrementalGenerator`. Compared to legacy `ISourceGenerator` approaches it:

- Runs **entirely in-memory** — zero files written to disk
- Uses the **Roslyn caching pipeline** — the IDE (Rider, Visual Studio) only re-runs the generator when its inputs change, eliminating background compilation loops
- Reads MSBuild properties **via `AnalyzerConfigOptionsProvider`** — safe, no direct environment variable reads

The package auto-imports `Build.props` via NuGet, which declares `CompilerVisibleProperty` items and suppresses the SDK's default `AssemblyInfo` generation (preventing CS0579 duplicate attribute errors when the generator is enabled).

### Timestamp Consistency in Multi-Project Builds

`BuildTimestamp` keeps the version consistent across every project in a solution build. See [`docs/MultiProjectBuildTimestamps.md`](docs/MultiProjectBuildTimestamps.md) for how it works and what alternative approaches were considered.

> **TL;DR:** For CI, or any local build where an exact guarantee matters more than convenience, use `-p:BuildTimestamp=...` to fix the value explicitly instead of relying on evaluation-time capture. Ready-to-use wrappers are available at [`Build.ps1.template`](Build.ps1.template) (Windows/PowerShell 7+) and [`Build.sh.template`](Build.sh.template) (Linux/macOS/bash).

### Diagnostics

| ID | Severity | Description |
|---|---|---|
| `BAUTOVERSIONING00` | Warning | Generator is installed but `GenerateAutoVersionedAssemblyInfo` is not set to `true` (single-line signal) |
| `BAUTOVERSIONING01` | Warning | Generator threw an unexpected exception |
| `BAUTOVERSIONING02` | Error | `AssemblyCompany` is not configured |
| `BAUTOVERSIONING03` | Error | `AssemblyProduct` is not configured |
| `BAUTOVERSIONING04` | Warning | Multi-line setup snippet emitted alongside BAUTOVERSIONING00 — shows the required `Directory.Build.props` configuration |

---

## Building Locally

Requires PowerShell 7+ and the .NET SDK.

```powershell
./Pack.ps1
```

The script prompts for a version (defaults to CalVer `YYYY.Q.MMDD`) and produces `.nupkg` files in `packages/Debug/` and `packages/Release/`.

---

## License

MIT © 2026 Brian Bennewitz
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Solution>
<Project Path="InfoPrj/InfoPrj.csproj" />
</Solution>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bennewitz.Ninja.AutoVersioning" Version="2026.3.701">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<PropertyGroup>
<GenerateAutoVersionedAssemblyInfo>true</GenerateAutoVersionedAssemblyInfo>
<!-- Prevents CS0579 duplicate attribute errors by suppressing only the 8 SDK-generated
attributes that this generator also emits. Using granular suppressions (rather than
GenerateAssemblyInfo=false) preserves other SDK-generated attributes such as
InternalsVisibleTo from MSBuild item groups.
NOTE: The NuGet package's auto-imported Build.props sets these automatically when
GenerateAutoVersionedAssemblyInfo=true. You only need these here if your build does
not pick up the auto-imported Build.props for some reason. -->
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>


<AssemblyCompany>AOM Company</AssemblyCompany>
<AssemblyProduct>Andrei Ignat Product</AssemblyProduct>


<CommitSha Condition="'$(CommitSha)' == ''">$(GITHUB_SHA)</CommitSha>
<IsContinuousIntegration>$(GITHUB_ACTIONS)</IsContinuousIntegration>
<PublicVersion Condition="'$(PublicVersion)' == ''">$(MY_VERSION_VAR)</PublicVersion>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using Bennewitz.Ninja.AutoVersioning;

Console.WriteLine("Hello, World!");
Console.WriteLine(DirectoryBuildInfo.BuildRelease);
Loading
Loading