wip
All checks were successful
default / dotnet-default-workflow (push) Successful in 1m3s

This commit is contained in:
Louis Seubert 2026-05-21 21:26:32 +02:00
commit a576264223
Signed by: louis9902
GPG key ID: 4B9DB28F826553BD
20 changed files with 170 additions and 54 deletions

View file

@ -5,7 +5,7 @@ indent_style = tab
indent_size = 4
tab_width = 4
end_of_line = lf
insert_final_newline = false
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 120
@ -14,22 +14,20 @@ indent_size = 2
indent_style = space
trim_trailing_whitespace = false
[*.{csproj,props,targets,slnx}]
[*.{csproj,props,targets,slnx,config}]
indent_size = 2
indent_style = space
[nuget.config]
indent_size = 2
indent_style = space
[*.{cs,vb}]
#### code style rule default severity ####
dotnet_analyzer_diagnostic.category-style.severity = warning
#### .NET Coding Conventions ####
[*.{cs,vb}]
# Organize usings
file_header_template = Copyright (c) The Geekeey Authors\nSPDX-License-Identifier: EUPL-1.2
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = true
dotnet_diagnostic.IDE0005.severity = suggestion # https://github.com/dotnet/roslyn/issues/41640
# this. and Me. preferences
dotnet_style_qualification_for_event = false
@ -51,9 +49,8 @@ dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
dotnet_style_require_accessibility_modifiers = for_non_interface_members
# Expression-level preferences
dotnet_diagnostic.IDE0270.severity = none
dotnet_style_coalesce_expression = true # IDE0029,IDE0030,IDE0270
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
@ -64,16 +61,17 @@ dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_compound_assignment = true
dotnet_diagnostic.IDE0045.severity = suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true # IDE0045
dotnet_style_prefer_conditional_expression_over_assignment = true
dotnet_diagnostic.IDE0046.severity = suggestion
dotnet_style_prefer_conditional_expression_over_return = true # IDE0046
dotnet_style_prefer_conditional_expression_over_return = true
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_namespace_match_folder = false # resharper: resharper_check_namespace_highlighting
dotnet_style_namespace_match_folder = false
# Field preferences
dotnet_style_readonly_field = true
@ -81,11 +79,6 @@ dotnet_style_readonly_field = true
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
# ReSharper preferences
resharper_wrap_object_and_collection_initializer_style = chop_always
resharper_check_namespace_highlighting = none
resharper_csharp_wrap_lines = false
#### C# Coding Conventions ####
[*.cs]
@ -121,6 +114,7 @@ csharp_preferred_modifier_order = public, private, protected, internal, static,
# Code-block preferences
csharp_prefer_braces = true
csharp_prefer_simple_using_statement = true
csharp_style_prefer_top_level_statements = false
# Expression-level preferences
csharp_prefer_simple_default_expression = true
@ -132,8 +126,8 @@ csharp_style_prefer_range_operator = true
csharp_style_throw_expression = true
dotnet_diagnostic.IDE0058.severity = suggestion
csharp_style_unused_value_assignment_preference = discard_variable # IDE0058
csharp_style_unused_value_expression_statement_preference = discard_variable # IDE0058
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace
@ -401,19 +395,3 @@ dotnet_naming_style.s_camelcase.required_prefix = s_
dotnet_naming_style.s_camelcase.required_suffix =
dotnet_naming_style.s_camelcase.word_separator =
dotnet_naming_style.s_camelcase.capitalization = camel_case
[*.{cs,vb}]
dotnet_analyzer_diagnostic.category-style.severity = warning
dotnet_analyzer_diagnostic.category-design.severity = warning
dotnet_analyzer_diagnostic.category-globalization.severity = notice
dotnet_analyzer_diagnostic.category-naming.severity = warning
dotnet_analyzer_diagnostic.category-performance.severity = warning
dotnet_analyzer_diagnostic.category-reliability.severity = warning
dotnet_analyzer_diagnostic.category-security.severity = warning
dotnet_analyzer_diagnostic.category-usage.severity = warning
dotnet_analyzer_diagnostic.category-maintainability.severity = warning
dotnet_diagnostic.CA1716.severity = none # Identifiers should not match keywords
dotnet_diagnostic.CA1816.severity = suggestion # Dispose methods should call SuppressFinalize
dotnet_diagnostic.CA1848.severity = none # Use the LoggerMessage delegates
dotnet_diagnostic.IDE0210.severity = none # Use top-level statements

View file

@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.0] - 2026-01-22
## [1.0.0] - 2026-05-21
### Added
@ -19,4 +19,4 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Removed
[1.0.0]: https://code.geekeey.de/geekeey/semver/releases/tag/1.0.0
[Unreleased]: https://code.geekeey.de/geekeey/semver/compare/1.0.0...HEAD
[Unreleased]: https://code.geekeey.de/geekeey/semver/compare/1.0.0...HEAD

View file

@ -24,4 +24,59 @@ You may need to add our NuGet feed to your `nuget.config` this can be done by ru
dotnet nuget add source -n geekeey https://code.geekeey.de/api/packages/geekeey/nuget/index.json
```
### Usage
### Usage
```csharp
using Geekeey.SemVer;
var version = SemanticVersion.Parse("1.2.3-beta+build.7");
var next = new SemanticVersion(1, 3, 0);
Console.WriteLine(version);
Console.WriteLine(version.Major);
Console.WriteLine(version.Prerelease);
Console.WriteLine(version.Metadata);
Console.WriteLine(version < next);
```
You can also use `TryParse` when you need to handle invalid input without exceptions.
```csharp
using Geekeey.SemVer;
if (SemanticVersion.TryParse("1.2.3-alpha", out var parsed))
{
Console.WriteLine(parsed);
}
```
Version ranges support npm-style and Maven-style syntax.
```csharp
using Geekeey.SemVer;
var npmRange = SemanticVersionRange.Parse("^1.2.3");
var mavenRange = SemanticVersionRange.Parse("[1.2.3,2.0.0)");
var candidate = SemanticVersion.Parse("1.4.2");
Console.WriteLine(npmRange.Contains(candidate));
Console.WriteLine(mavenRange.Contains(candidate));
Console.WriteLine(npmRange.ToString("m", null));
Console.WriteLine(mavenRange.ToString("ns", null));
```
Both `SemanticVersion` and `SemanticVersionRange` integrate with `System.Text.Json`.
```csharp
using System.Text.Json;
using Geekeey.SemVer;
var version = SemanticVersion.Parse("1.2.3-beta+build.7");
var range = SemanticVersionRange.Parse("^1.2.3");
var versionJson = JsonSerializer.Serialize(version);
var rangeJson = JsonSerializer.Serialize(range);
var roundTrippedVersion = JsonSerializer.Deserialize<SemanticVersion>(versionJson);
var roundTrippedRange = JsonSerializer.Deserialize<SemanticVersionRange>(rangeJson);
```

View file

@ -0,0 +1,15 @@
[*.{cs,vb}]
# disable CA1822: Mark members as static
# -> TUnit requiring instance methods for test cases
dotnet_diagnostic.CA1822.severity = none
# disable CA1707: Identifiers should not contain underscores
dotnet_diagnostic.CA1707.severity = none
# disable IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0060.severity = none
# disable IDE0005: Unnecessary using directive
dotnet_diagnostic.IDE0005.severity = none
# disable IDE0390: Method can be made synchronous
dotnet_diagnostic.IDE0390.severity = none
# disable IDE0391: Method can be made synchronous
dotnet_diagnostic.IDE0391.severity = none

View file

@ -112,4 +112,4 @@ internal sealed class SemanticVersionComparerTests
await Assert.That(SemanticVersionComparer.Priority.Equals(v1, v2)).IsFalse();
await Assert.That(SemanticVersionComparer.SortOrder.Equals(v1, v2)).IsFalse();
}
}
}

View file

@ -258,4 +258,4 @@ internal sealed class SemanticVersionRangeTests
await Assert.That(success).IsFalse();
await Assert.That(charsWritten).IsEqualTo(0);
}
}
}

View file

@ -1,7 +1,6 @@
// Copyright (c) The Geekeey Authors
// SPDX-License-Identifier: EUPL-1.2
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
@ -223,4 +222,4 @@ internal sealed class SemanticVersionTests
await Assert.That(() => JsonSerializer.Deserialize<SemanticVersion>(json))
.Throws<JsonException>();
}
}
}

View file

@ -48,4 +48,4 @@ public readonly partial record struct SemanticVersion : IComparable, IComparable
{
return left.CompareTo(right) >= 0;
}
}
}

View file

@ -109,4 +109,4 @@ public readonly partial record struct SemanticVersion : ISpanFormattable
}
#endregion
}
}

View file

@ -38,4 +38,4 @@ public readonly partial record struct SemanticVersion
writer.WriteStringValue(value.ToString("f", null));
}
}
}
}

View file

@ -152,4 +152,4 @@ public readonly partial record struct SemanticVersion : ISpanParsable<SemanticVe
version = new SemanticVersion(component[0], component[1], component[2], prerelease, metadata);
return true;
}
}
}

View file

@ -105,4 +105,4 @@ public readonly partial record struct SemanticVersion
/// details. It does not affect the precedence of the version.
/// </summary>
public string? Metadata { get; }
}
}

View file

@ -304,4 +304,4 @@ public abstract class SemanticVersionComparer : IEqualityComparer<SemanticVersio
return xParts.Length.CompareTo(yParts.Length);
}
}
}

View file

@ -223,4 +223,4 @@ public readonly partial record struct SemanticVersionRange : ISpanFormattable
{
return set.Constraints is [] or [{ Operation: Comparison.Gte, Version: { Major: 0, Minor: 0, Patch: 0 } }];
}
}
}

View file

@ -38,4 +38,4 @@ public readonly partial record struct SemanticVersionRange
writer.WriteStringValue(value.ToString());
}
}
}
}

View file

@ -1,7 +1,6 @@
// Copyright (c) The Geekeey Authors
// SPDX-License-Identifier: EUPL-1.2
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace Geekeey.SemVer;
@ -513,4 +512,4 @@ public readonly partial record struct SemanticVersionRange : ISpanParsable<Seman
set = new ConstraintSet([.. comps]);
return true;
}
}
}

View file

@ -102,4 +102,4 @@ internal readonly struct ConstraintSet
return true;
}
}
}

View file

@ -40,4 +40,4 @@ internal ref struct SpanBuffer(Span<char> buffer)
Written += n;
return true;
}
}
}

BIN
src/semver/package-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1,70 @@
SemVer is a .NET library for parsing, comparing, formatting, and serializing semantic versions and version ranges.
## Features
- **Parsing:** parse semantic version strings into structured objects.
- **Comparison:** compare versions with operators or `CompareTo`.
- **Ranges:** evaluate npm-style and Maven-style version ranges.
- **Serialization:** use `System.Text.Json` converters for versions and ranges.
## Getting Started
### Install the NuGet package:
```shell
dotnet add package Geekeey.SemVer
```
You may need to add our NuGet feed to your `nuget.config` this can be done by running the following command:
```shell
dotnet nuget add source -n geekeey https://code.geekeey.de/api/packages/geekeey/nuget/index.json
```
### Usage
```csharp
using Geekeey.SemVer;
var version = SemanticVersion.Parse("1.2.3-beta+build.7");
var next = new SemanticVersion(1, 3, 0);
Console.WriteLine(version);
Console.WriteLine(version.Major);
Console.WriteLine(version.Prerelease);
Console.WriteLine(version.Metadata);
Console.WriteLine(version < next);
if (SemanticVersion.TryParse("1.2.3-alpha", out var parsed))
{
Console.WriteLine(parsed);
}
```
Version ranges support npm-style and Maven-style syntax.
```csharp
using Geekeey.SemVer;
var npmRange = SemanticVersionRange.Parse("^1.2.3");
var mavenRange = SemanticVersionRange.Parse("[1.2.3,2.0.0)");
var candidate = SemanticVersion.Parse("1.4.2");
Console.WriteLine(npmRange.Contains(candidate));
Console.WriteLine(mavenRange.Contains(candidate));
Console.WriteLine(npmRange.ToString("m", null));
Console.WriteLine(mavenRange.ToString("ns", null));
```
Both `SemanticVersion` and `SemanticVersionRange` integrate with `System.Text.Json`.
```csharp
using System.Text.Json;
using Geekeey.SemVer;
var versionJson = JsonSerializer.Serialize(SemanticVersion.Parse("1.2.3-beta+build.7"));
var rangeJson = JsonSerializer.Serialize(SemanticVersionRange.Parse("^1.2.3"));
var roundTrippedVersion = JsonSerializer.Deserialize<SemanticVersion>(versionJson);
var roundTrippedRange = JsonSerializer.Deserialize<SemanticVersionRange>(rangeJson);
```