diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..6376137
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,39 @@
+# If this file is renamed, the incrementing run attempt number will be reset.
+
+name: CI
+
+on:
+ push:
+ branches: [ "dev", "main" ]
+ pull_request:
+ branches: [ "dev", "main" ]
+
+env:
+ CI_BUILD_NUMBER_BASE: ${{ github.run_number }}
+ CI_TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
+
+jobs:
+ build:
+
+ runs-on: ubuntu-24.04
+
+ permissions:
+ contents: write
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 10.0.x
+ - name: Compute build number
+ run: |
+ echo "CI_BUILD_NUMBER=$(($CI_BUILD_NUMBER_BASE+200))" >> $GITHUB_ENV
+ - name: Build and Publish
+ env:
+ DOTNET_CLI_TELEMETRY_OPTOUT: true
+ NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ shell: pwsh
+ run: |
+ ./Build.ps1
diff --git a/Build.ps1 b/Build.ps1
index f3d5c51..952dce0 100644
--- a/Build.ps1
+++ b/Build.ps1
@@ -1,57 +1,77 @@
-# This script originally (c) 2016 Serilog Contributors - license Apache 2.0
-
-echo "build: Build started"
+Write-Output "build: Build started"
Push-Location $PSScriptRoot
+Write-Output "build: Tool versions follow"
+
+dotnet --version
+dotnet --list-sdks
+
if(Test-Path .\artifacts) {
- echo "build: Cleaning .\artifacts"
- Remove-Item .\artifacts -Force -Recurse
+ Write-Output "build: Cleaning ./artifacts"
+ Remove-Item ./artifacts -Force -Recurse
}
& dotnet restore --no-cache
-$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL];
-$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
-$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)).Replace("/", "-"))-$revision"}[$branch -eq "main" -and $revision -ne "local"]
+$dbp = [Xml] (Get-Content .\Directory.Build.props)
+$versionPrefix = $dbp.Project.PropertyGroup.VersionPrefix
+
+Write-Output "build: Package version prefix is $versionPrefix"
-echo "build: Version suffix is $suffix"
+$branch = @{ $true = $env:CI_TARGET_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$NULL -ne $env:CI_TARGET_BRANCH];
+$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:CI_BUILD_NUMBER, 10); $false = "local" }[$NULL -ne $env:CI_BUILD_NUMBER];
+$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)) -replace '([^a-zA-Z0-9\-]*)', '')-$revision"}[$branch -eq "main" -and $revision -ne "local"]
-foreach ($src in ls src/*) {
+Write-Output "build: Package version suffix is $suffix"
+
+foreach ($src in Get-ChildItem src/*) {
Push-Location $src
- echo "build: Packaging project in $src"
+ Write-Output "build: Packaging project in $src"
if ($suffix) {
- & dotnet pack -c Release -o ..\..\artifacts --version-suffix=$suffix --include-source
+ & dotnet pack -c Release -o ../../artifacts --version-suffix=$suffix
} else {
- & dotnet pack -c Release -o ..\..\artifacts --include-source
+ & dotnet pack -c Release -o ../../artifacts
}
- if($LASTEXITCODE -ne 0) { exit 1 }
+ if($LASTEXITCODE -ne 0) { throw "Packaging failed" }
Pop-Location
}
-foreach ($test in ls test/*.Benchmarks) {
- Push-Location $test
-
- echo "build: Building performance test project in $test"
-
- & dotnet build -c Release
- if($LASTEXITCODE -ne 0) { exit 2 }
+Write-Output "build: Checking complete solution builds"
+& dotnet build
+if($LASTEXITCODE -ne 0) { throw "Solution build failed" }
- Pop-Location
-}
-foreach ($test in ls test/*.Tests) {
+foreach ($test in Get-ChildItem test/*.Tests) {
Push-Location $test
- echo "build: Testing project in $test"
+ Write-Output "build: Testing project in $test"
& dotnet test -c Release
- if($LASTEXITCODE -ne 0) { exit 3 }
+ if($LASTEXITCODE -ne 0) { throw "Testing failed" }
Pop-Location
}
Pop-Location
+
+if ($env:NUGET_API_KEY) {
+ # GitHub Actions will only supply this to branch builds and not PRs. We publish
+ # builds from any branch this action targets (i.e. main and dev).
+
+ Write-Output "build: Publishing NuGet packages"
+
+ foreach ($nupkg in Get-ChildItem artifacts/*.nupkg) {
+ & dotnet nuget push -k $env:NUGET_API_KEY -s https://api.nuget.org/v3/index.json "$nupkg"
+ if($LASTEXITCODE -ne 0) { throw "Publishing failed" }
+ }
+
+ if (!($suffix)) {
+ Write-Output "build: Creating release for version $versionPrefix"
+
+ iex "gh release create v$versionPrefix --title v$versionPrefix --generate-notes $(get-item ./artifacts/*.nupkg) $(get-item ./artifacts/*.snupkg)"
+ }
+}
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..6c791fe
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,18 @@
+
+
+ enable
+ enable
+ latest
+ true
+ 3.2.0
+ Apache-2.0
+ true
+
+ true
+ ../../asset/Superpower.snk
+ true
+ true
+ snupkg
+ NETSDK1138
+
+
diff --git a/README.md b/README.md
index 321ef94..3172391 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Superpower [](https://ci.appveyor.com/project/datalust/superpower) [](https://www.nuget.org/packages/Superpower/) [](http://stackoverflow.com/questions/tagged/superpower)
+# Superpower [](https://www.nuget.org/packages/Superpower/)
A [parser combinator](https://en.wikipedia.org/wiki/Parser_combinator) library based on
[Sprache](https://github.com/sprache/Sprache). Superpower generates friendlier error messages through its support for
diff --git a/Superpower.sln b/Superpower.sln
index 2b5bf04..b83a124 100644
--- a/Superpower.sln
+++ b/Superpower.sln
@@ -7,7 +7,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AC295EEA-D31
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "global", "global", "{66B005E9-A083-41E8-BD89-4D6E753CD8BF}"
ProjectSection(SolutionItems) = preProject
- appveyor.yml = appveyor.yml
Benchmark.ps1 = Benchmark.ps1
Build.ps1 = Build.ps1
LICENSE = LICENSE
diff --git a/Superpower.sln.DotSettings b/Superpower.sln.DotSettings
index 4886e1b..cafafd4 100644
--- a/Superpower.sln.DotSettings
+++ b/Superpower.sln.DotSettings
@@ -1,5 +1,7 @@
<Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="AA_BB" /></Policy>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Type parameters"><ElementKinds><Kind Name="TYPE_PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="T" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="AA_BB" /></Policy></Policy>
+ True
True
True
True
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index a1dbc90..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-version: '{build}'
-skip_tags: true
-image: Visual Studio 2022
-build_script:
-- ps: ./Build.ps1
-test: off
-artifacts:
-- path: artifacts/Superpower.*.nupkg
-deploy:
-- provider: NuGet
- api_key:
- secure: wW4TJY85P9BSN53XNfB0IE2WqskPu0RdsWelB1tQco1wql3g8ov5yhmk5v8dXy81
- skip_symbols: true
- on:
- branch: /^(main|dev)$/
-- provider: GitHub
- auth_token:
- secure: hX+cZmW+9BCXy7vyH8myWsYdtQHyzzil9K5yvjJv7dK9XmyrGYYDj/DPzMqsXSjo
- artifact: /Superpower.*\.nupkg/
- tag: v$(appveyor_build_version)
- on:
- branch: main
diff --git a/global.json b/global.json
index e972eb1..8287d38 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.300",
+ "version": "10.0.201",
"rollForward": "latestFeature"
}
}
diff --git a/sample/DateTimeTextParser/DateTimeParser.csproj b/sample/DateTimeTextParser/DateTimeParser.csproj
index 792814b..7323467 100644
--- a/sample/DateTimeTextParser/DateTimeParser.csproj
+++ b/sample/DateTimeTextParser/DateTimeParser.csproj
@@ -2,8 +2,9 @@
Exe
- net6.0
+ net10.0
enable
+ false
diff --git a/sample/IntCalc/IntCalc.csproj b/sample/IntCalc/IntCalc.csproj
index 3dc4d1d..5088caa 100644
--- a/sample/IntCalc/IntCalc.csproj
+++ b/sample/IntCalc/IntCalc.csproj
@@ -2,8 +2,9 @@
Exe
- net6.0
+ net10.0
enable
+ false
diff --git a/sample/JsonParser/JsonParser.csproj b/sample/JsonParser/JsonParser.csproj
index 5c6f8ea..7bce2e8 100644
--- a/sample/JsonParser/JsonParser.csproj
+++ b/sample/JsonParser/JsonParser.csproj
@@ -2,8 +2,9 @@
Exe
- net6.0
+ net10.0
enable
+ false
diff --git a/src/Superpower/Model/TextSpan.cs b/src/Superpower/Model/TextSpan.cs
index c8f0358..50342af 100644
--- a/src/Superpower/Model/TextSpan.cs
+++ b/src/Superpower/Model/TextSpan.cs
@@ -233,6 +233,16 @@ public string ToStringValue()
return Source!.Substring(Position.Absolute, Length);
}
+ ///
+ /// Compute the string value of this span and return the view of source directly.
+ ///
+ /// A view of string with the value of this span.
+ public ReadOnlySpan AsReadOnlySpan()
+ {
+ EnsureHasValue();
+ return Source!.AsSpan(Position.Absolute, Length);
+ }
+
///
/// Compare the contents of this span with .
///
diff --git a/src/Superpower/Superpower.csproj b/src/Superpower/Superpower.csproj
index 0aff1bd..b9dcc4e 100644
--- a/src/Superpower/Superpower.csproj
+++ b/src/Superpower/Superpower.csproj
@@ -2,22 +2,11 @@
netstandard2.0;net6.0;net8.0
A parser combinator library for C#
- 3.1.0
Datalust;Superpower Contributors;Sprache Contributors
- true
- true
- ../../asset/Superpower.snk
- true
- true
superpower;parser
https://github.com/datalust/superpower
false
Superpower-White-400px.png
- Apache-2.0
- https://github.com/datalust/superpower
- git
- enable
- latest
$(DefineConstants);CHECKED
@@ -25,4 +14,7 @@
+
+
+
diff --git a/test/Superpower.Benchmarks/Superpower.Benchmarks.csproj b/test/Superpower.Benchmarks/Superpower.Benchmarks.csproj
index 731dc82..1161f25 100644
--- a/test/Superpower.Benchmarks/Superpower.Benchmarks.csproj
+++ b/test/Superpower.Benchmarks/Superpower.Benchmarks.csproj
@@ -1,9 +1,10 @@
- net6.0;net8.0
+ net8.0;net10.0
true
enable
+ false
@@ -11,14 +12,14 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
diff --git a/test/Superpower.Tests/Model/TextSpanTest.cs b/test/Superpower.Tests/Model/TextSpanTest.cs
new file mode 100644
index 0000000..af17a64
--- /dev/null
+++ b/test/Superpower.Tests/Model/TextSpanTest.cs
@@ -0,0 +1,27 @@
+using System;
+using Superpower.Model;
+using Xunit;
+
+namespace Superpower.Tests.Model
+{
+ public class TextSpanTest
+ {
+ [Theory]
+ [InlineData("hello", 0, 5, "hello")]
+ [InlineData("hello", 1, 3, "ell")]
+ [InlineData("hello", 2, 0, "")]
+ [InlineData("The quick brown fox jumps over the lazy dog", 9, 7, " brown ")]
+ public void AsReadOnlySpanWorks(string input, int start, int length, string expected)
+ {
+ var span = new TextSpan(input).Skip(start).First(length);
+ var readOnlySpan = span.AsReadOnlySpan();
+ Assert.Equal(expected, readOnlySpan.ToString());
+ }
+
+ [Fact]
+ public void AsReadOnlySpanEnsureHasValue()
+ {
+ Assert.Throws(() => TextSpan.None.AsReadOnlySpan());
+ }
+ }
+}
diff --git a/test/Superpower.Tests/Parsers/SpanTests.cs b/test/Superpower.Tests/Parsers/SpanTests.cs
index e6a0a5e..00ecbe3 100644
--- a/test/Superpower.Tests/Parsers/SpanTests.cs
+++ b/test/Superpower.Tests/Parsers/SpanTests.cs
@@ -18,7 +18,7 @@ public class SpanTests
public void RegularExpressionParsersAreApplied(
string input,
string regex,
- string match,
+ string? match,
int start = 0,
int length = -1)
{
diff --git a/test/Superpower.Tests/Superpower.Tests.csproj b/test/Superpower.Tests/Superpower.Tests.csproj
index 0615251..81ec1bc 100644
--- a/test/Superpower.Tests/Superpower.Tests.csproj
+++ b/test/Superpower.Tests/Superpower.Tests.csproj
@@ -1,6 +1,6 @@
- net6.0;net8.0
+ net8.0;net10.0
Superpower.Tests
../../asset/Superpower.snk
true
@@ -11,16 +11,17 @@
false
false
enable
+ false
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
\ No newline at end of file