Skip to content
Merged
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
48 changes: 48 additions & 0 deletions .github/workflows/verify-generated.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Verify Generated Files

# Source-generator output under Semantics.Quantities/Generated/ is committed to the
# repo (EmitCompilerGeneratedFiles=true). This job rebuilds and fails if the committed
# files are stale, so a generated file can never drift from its generator.
#
# NOTE: this is a standalone workflow on purpose — dotnet.yml is centrally synced from a
# shared template across ktsu repos, so a step added there would be overwritten. If this
# check belongs in the shared KtsuBuild pipeline long-term, move it there and delete this.

on:
pull_request:
paths-ignore: ["**.md"]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: verify-generated-${{ github.ref }}
cancel-in-progress: true

jobs:
verify-generated:
name: Generated files up to date
# windows-latest so git's autocrlf matches the committed CRLF line endings and the
# diff doesn't flag end-of-line differences.
runs-on: windows-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"

- name: Build (regenerates source-generator output into Generated/)
run: dotnet build Semantics.Quantities/Semantics.Quantities.csproj -c Release

- name: Fail if generated files are stale
shell: bash
run: |
if ! git diff --exit-code -- 'Semantics.Quantities/Generated/'; then
echo "::error::Generated files are out of date. Run 'dotnet build Semantics.Quantities/Semantics.Quantities.csproj' and commit the changes under Semantics.Quantities/Generated/."
exit 1
fi
2 changes: 1 addition & 1 deletion Semantics.Paths/Semantics.Paths.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Sdk Name="Microsoft.NET.Sdk" />
<Sdk Name="ktsu.Sdk" />
<PropertyGroup>
<TargetFrameworks>net10.0;net9.0;net8.0;net7.0;net6.0;net5.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net10.0;net9.0;net8.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<NoWarn>$(NoWarn);CA1716;CA2225;IDE0032;CA1866;CA2249;IDE0056;IDE0057</NoWarn>
</PropertyGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5422,9 +5422,6 @@ public static class Units{
/// <summary>Singleton <c>FaradPerMeter</c> instance.</summary>
public static readonly FaradPerMeter FaradPerMeter = new FaradPerMeter();

/// <summary>Singleton <c>FootPerSecond</c> instance.</summary>
public static readonly FootPerSecond FootPerSecond = new FootPerSecond();

/// <summary>Singleton <c>Foot</c> instance.</summary>
public static readonly Foot Foot = new Foot();

Expand All @@ -5434,6 +5431,9 @@ public static class Units{
/// <summary>Singleton <c>FootLambert</c> instance.</summary>
public static readonly FootLambert FootLambert = new FootLambert();

/// <summary>Singleton <c>FootPerSecond</c> instance.</summary>
public static readonly FootPerSecond FootPerSecond = new FootPerSecond();

/// <summary>Singleton <c>Gallon</c> instance.</summary>
public static readonly Gallon Gallon = new Gallon();

Expand Down
2 changes: 1 addition & 1 deletion Semantics.Quantities/Semantics.Quantities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Sdk Name="Microsoft.NET.Sdk" />
<Sdk Name="ktsu.Sdk" />
<PropertyGroup>
<TargetFrameworks>net10.0;net9.0;net8.0;net7.0</TargetFrameworks>
<TargetFrameworks>net10.0;net9.0;net8.0</TargetFrameworks>
<NoWarn>$(NoWarn);CA1716;CA2225;KTSU0003;IDE0032</NoWarn>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
Expand Down
2 changes: 1 addition & 1 deletion Semantics.Strings/Semantics.Strings.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Sdk Name="Microsoft.NET.Sdk" />
<Sdk Name="ktsu.Sdk" />
<PropertyGroup>
<TargetFrameworks>net10.0;net9.0;net8.0;net7.0;net6.0;net5.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net10.0;net9.0;net8.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<NoWarn>$(NoWarn);CA1716;CA1866;CA2249;IDE0057</NoWarn>
</PropertyGroup>
<ItemGroup>
Expand Down
18 changes: 7 additions & 11 deletions Semantics.Test/Quantities/VectorQuantityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,11 @@ public void Speed_Plus_Speed_Returns_Speed()
}

// ------------------------------------------------------------- V0 - V0
// Locked design decision in #52: V0 - V0 should return the same V0 of T.Abs(a - b).
// Generator currently emits unsigned subtraction via the SemanticQuantity base, which
// can produce a negative magnitude. Tracked as a follow-up.
// #52: V0 - V0 returns the same V0 of T.Abs(a - b). The generated derived operator
// wins overload resolution over PhysicalQuantity's plain (signable) subtraction.

[TestMethod]
[Ignore("Locked in #52: V0 - V0 should return the same V0 of T.Abs(a - b). Generator currently emits unsigned subtraction.")]
public void Mass_Minus_Mass_Returns_Absolute_Difference_Pending52()
public void Mass_Minus_Mass_Returns_Absolute_Difference()
{
Mass<double> a = Mass<double>.FromKilogram(3.0);
Mass<double> b = Mass<double>.FromKilogram(5.0);
Expand All @@ -180,20 +178,18 @@ public void Mass_Minus_Mass_Returns_Absolute_Difference_Pending52()
}

// ---------------------------------------------------- V0 non-negativity
// Tracked in #50: factories on Vector0 quantities should reject negative inputs
// with ArgumentException. The current generator does not emit guards.
// #50: factories on Vector0 quantities reject negative inputs with ArgumentException
// via Vector0Guards.EnsureNonNegative (the guard runs after unit conversion).

[TestMethod]
[Ignore("Tracked in #50: V0 factories should reject negative inputs.")]
public void Speed_From_Negative_Throws_Pending50()
public void Speed_From_Negative_Throws()
{
_ = Assert.ThrowsExactly<System.ArgumentException>(
() => Speed<double>.FromMeterPerSecond(-1.0));
}

[TestMethod]
[Ignore("Tracked in #50: V0 factories should reject negative inputs.")]
public void Mass_From_Negative_Throws_Pending50()
public void Mass_From_Negative_Throws()
{
_ = Assert.ThrowsExactly<System.ArgumentException>(
() => Mass<double>.FromKilogram(-1.0));
Expand Down
5 changes: 4 additions & 1 deletion docs/migration-guide-2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ different dimensions throws `ArgumentException`; equality across dimensions is
| audio-engineering `Percent<T>` | the `Percent` **unit** on the Dimensionless dimension: `Ratio<T>.FromPercent(50)` and `ratio.In(Units.Percent)` |
| audio-engineering `Gain<T>` record struct | `Gain<T>` is now a generated semantic overload of `Ratio` (a record class, non-negative, widens implicitly to `Ratio`); `Unity`, `Silence`, the `Decibels` conversions, and `*` live in a partial |

## Target frameworks

The out-of-support runtimes `net5.0`, `net6.0`, and `net7.0` were dropped — `System.Text.Json` 10 (and friends) no longer ship assets for them. `ktsu.Semantics.Quantities` now targets `net8.0`–`net10.0` (it requires `INumber<T>`, so it has no `netstandard` target). `Semantics.Strings` and `Semantics.Paths` target `net8.0`–`net10.0` plus `netstandard2.0`/`netstandard2.1`, so consumers on older runtimes still resolve via `netstandard`.

## What didn't change

- `Semantics.Strings` and `Semantics.Paths` — same namespaces, same types;
Expand All @@ -224,7 +228,6 @@ different dimensions throws `ArgumentException`; equality across dimensions is
through the generated `Ratio<T>`, and (for the logarithmic ones) are
generated from `logarithmic.json`. `Percent` became a unit and `Gain` a
generated `Ratio` overload — see the removed-APIs table.
- Target frameworks: `net7.0` through `net10.0`.
- Quantities remain generic over the numeric storage type
(`where T : struct, INumber<T>`).
- `UnitSystem` and `UnitConversionException` keep their names and meaning.
Loading