From b1d65b33d8f12852a726d6720717ac6efbffddeb Mon Sep 17 00:00:00 2001 From: Smaug123 <3138005+Smaug123@users.noreply.github.com> Date: Fri, 7 Jun 2024 18:31:16 +0100 Subject: [PATCH] Initial commit --- .config/dotnet-tools.json | 12 + .editorconfig | 40 +++ .envrc | 1 + .fantomasignore | 1 + .github/CODEOWNERS | 3 + .github/dependabot.yml | 8 + .github/workflows/dotnet.yaml | 217 ++++++++++++++++ .github/workflows/tag.sh | 120 +++++++++ .gitignore | 12 + Directory.Build.props | 16 ++ Example/Example.fsproj | 17 ++ Example/Program.fs | 21 ++ README.md | 14 ++ WoofWare.DotnetRuntimeLocator.sln | 34 +++ WoofWare.DotnetRuntimeLocator/Boilerplate.cs | 28 +++ .../DotnetEnvironmentFrameworkInfo.cs | 29 +++ .../DotnetEnvironmentInfo.cs | 231 ++++++++++++++++++ .../DotnetEnvironmentSdkInfo.cs | 27 ++ .../InteropStructs.cs | 46 ++++ .../SurfaceBaseline.txt | 47 ++++ .../Test/Test.fsproj | 26 ++ .../Test/TestDotnetEnvironmentInfo.fs | 19 ++ .../Test/TestSurface.fs | 23 ++ .../WoofWare.DotnetRuntimeLocator.csproj | 40 +++ WoofWare.DotnetRuntimeLocator/logo.png | Bin 0 -> 75554 bytes WoofWare.DotnetRuntimeLocator/version.json | 10 + flake.lock | 61 +++++ flake.nix | 66 +++++ nix/deps.nix | 224 +++++++++++++++++ 29 files changed, 1393 insertions(+) create mode 100644 .config/dotnet-tools.json create mode 100644 .editorconfig create mode 100644 .envrc create mode 100644 .fantomasignore create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/dotnet.yaml create mode 100644 .github/workflows/tag.sh create mode 100644 .gitignore create mode 100644 Directory.Build.props create mode 100644 Example/Example.fsproj create mode 100644 Example/Program.fs create mode 100644 README.md create mode 100644 WoofWare.DotnetRuntimeLocator.sln create mode 100644 WoofWare.DotnetRuntimeLocator/Boilerplate.cs create mode 100644 WoofWare.DotnetRuntimeLocator/DotnetEnvironmentFrameworkInfo.cs create mode 100644 WoofWare.DotnetRuntimeLocator/DotnetEnvironmentInfo.cs create mode 100644 WoofWare.DotnetRuntimeLocator/DotnetEnvironmentSdkInfo.cs create mode 100644 WoofWare.DotnetRuntimeLocator/InteropStructs.cs create mode 100644 WoofWare.DotnetRuntimeLocator/SurfaceBaseline.txt create mode 100644 WoofWare.DotnetRuntimeLocator/Test/Test.fsproj create mode 100644 WoofWare.DotnetRuntimeLocator/Test/TestDotnetEnvironmentInfo.fs create mode 100644 WoofWare.DotnetRuntimeLocator/Test/TestSurface.fs create mode 100644 WoofWare.DotnetRuntimeLocator/WoofWare.DotnetRuntimeLocator.csproj create mode 100644 WoofWare.DotnetRuntimeLocator/logo.png create mode 100644 WoofWare.DotnetRuntimeLocator/version.json create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/deps.nix diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..c1e4bf5 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "fantomas": { + "version": "6.3.8", + "commands": [ + "fantomas" + ] + } + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e744fe1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,40 @@ +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +# ReSharper properties +resharper_xml_indent_size = 2 +resharper_xml_max_line_length = 100 +resharper_xml_tab_width = 2 + +[*.{csproj,fsproj,sqlproj,targets,props,ts,tsx,css,json}] +indent_style = space +indent_size = 2 + +[*.{fs,fsi}] +fsharp_bar_before_discriminated_union_declaration = true +fsharp_space_before_uppercase_invocation = true +fsharp_space_before_class_constructor = true +fsharp_space_before_member = true +fsharp_space_before_colon = true +fsharp_space_before_semicolon = true +fsharp_multiline_bracket_style = aligned +fsharp_newline_between_type_definition_and_members = true +fsharp_align_function_signature_to_indentation = true +fsharp_alternative_long_member_definitions = true +fsharp_multi_line_lambda_closing_newline = true +fsharp_experimental_keep_indent_in_branch = true +fsharp_max_value_binding_width = 80 +fsharp_max_record_width = 0 +max_line_length = 120 +end_of_line = lf + +[*.{appxmanifest,build,dtd,nuspec,xaml,xamlx,xoml,xsd}] +indent_style = space +indent_size = 2 +tab_width = 2 diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.fantomasignore b/.fantomasignore new file mode 100644 index 0000000..9b42106 --- /dev/null +++ b/.fantomasignore @@ -0,0 +1 @@ +.direnv/ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..203a3b5 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# See: https://help.github.com/articles/about-codeowners/ + +* @G-Research/rqf @G-Research/gr-oss diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1d54482 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +# yaml-language-server: $schema=https://json.schemastore.org/dependabot-2.0.json +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/dotnet.yaml b/.github/workflows/dotnet.yaml new file mode 100644 index 0000000..6abf99e --- /dev/null +++ b/.github/workflows/dotnet.yaml @@ -0,0 +1,217 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/github-workflow.json +name: .NET + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +env: + DOTNET_NOLOGO: true + DOTNET_CLI_TELEMETRY_OPTOUT: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + NUGET_XMLDOC_MODE: '' + DOTNET_MULTILEVEL_LOOKUP: 0 + +jobs: + build-windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # so that NerdBank.GitVersioning has access to history + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + - name: Restore dependencies + run: dotnet restore + - name: Test + run: dotnet test + - name: Run example + run: ".\\Example\\bin\\Release\\net8.0\\win-x64\\Example.exe" + + build: + strategy: + matrix: + config: + - Release + - Debug + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # so that NerdBank.GitVersioning has access to history + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Restore dependencies + run: nix develop --command dotnet restore + - name: Build + run: nix develop --command dotnet build --no-restore --configuration ${{matrix.config}} + - name: Test + run: nix develop --command dotnet test --no-build --verbosity normal --configuration ${{matrix.config}} + + build-nix: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Build + run: nix build + + check-dotnet-format: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run Fantomas + run: nix run .#fantomas -- --check . + + check-nix-format: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run Alejandra + run: nix develop --command alejandra --check . + + linkcheck: + name: Check links + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run link checker + run: nix develop --command markdown-link-check README.md + + flake-check: + name: Check flake + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Flake check + run: nix flake check + + nuget-pack: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # so that NerdBank.GitVersioning has access to history + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Restore dependencies + run: nix develop --command dotnet restore + - name: Build + run: nix develop --command dotnet build --no-restore --configuration Release + - name: Pack + run: nix develop --command dotnet pack --configuration Release + - name: Upload NuGet artifact + uses: actions/upload-artifact@v4 + with: + name: nuget-package + path: WoofWare.DotnetRuntimeLocator/bin/Release/WoofWare.DotnetRuntimeLocator.*.nupkg + + expected-pack: + needs: [nuget-pack] + runs-on: ubuntu-latest + steps: + - name: Download NuGet artifact + uses: actions/download-artifact@v4 + with: + name: nuget-package + path: packed + - name: Check NuGet contents + # Verify that there is exactly one nupkg in the artifact that would be NuGet published + run: if [[ $(find packed -maxdepth 1 -name 'WoofWare.DotnetRuntimeLocator.*.nupkg' -printf c | wc -c) -ne "1" ]]; then exit 1; fi + + github-release-dry-run: + needs: [nuget-pack] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Download NuGet artifact + uses: actions/download-artifact@v4 + with: + name: nuget-package + - name: Tag and release + env: + DRY_RUN: 1 + GITHUB_TOKEN: mock-token + run: sh .github/workflows/tag.sh + + all-required-checks-complete: + needs: [check-dotnet-format, check-nix-format, build, build-nix, linkcheck, flake-check, nuget-pack, expected-pack, github-release-dry-run] + runs-on: ubuntu-latest + steps: + - run: echo "All required checks complete." + + nuget-publish: + runs-on: ubuntu-latest + if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }} + needs: [all-required-checks-complete] + environment: main-deploy + steps: + - uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Download NuGet artifact + uses: actions/download-artifact@v4 + with: + name: nuget-package + path: packed + - name: Publish to NuGet + run: nix develop --command dotnet nuget push "packed/WoofWare.DotnetRuntimeLocator.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate + + github-release: + runs-on: ubuntu-latest + if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }} + needs: [all-required-checks-complete] + environment: main-deploy + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - name: Download NuGet artifact + uses: actions/download-artifact@v4 + with: + name: nuget-package + - name: Tag and release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: sh .github/workflows/tag.sh diff --git a/.github/workflows/tag.sh b/.github/workflows/tag.sh new file mode 100644 index 0000000..e2795f1 --- /dev/null +++ b/.github/workflows/tag.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +echo "Dry-run? $DRY_RUN!" + +find . -maxdepth 1 -type f ! -name "$(printf "*\n*")" -name '*.nupkg' | while IFS= read -r file +do + tag=$(basename "$file" .nupkg) + git tag "$tag" + ${DRY_RUN:+echo} git push origin "$tag" +done + +export TAG +TAG=$(find . -maxdepth 1 -type f -name 'WoofWare.DotnetRuntimeLocator.*.nupkg' -exec sh -c 'basename "$1" .nupkg' shell {} \; | grep -v Attributes) + +case "$TAG" in + *" +"*) + echo "Error: TAG contains a newline; multiple plugins found." + exit 1 + ;; +esac + +# target_commitish empty indicates the repo default branch +curl_body='{"tag_name":"'"$TAG"'","target_commitish":"","name":"'"$TAG"'","draft":false,"prerelease":false,"generate_release_notes":false}' + +echo "cURL body: $curl_body" + +failed_output=$(cat <<'EOF' +{ + "message": "Validation Failed", + "errors": [ + { + "resource": "Release", + "code": "already_exists", + "field": "tag_name" + } + ], + "documentation_url": "https://docs.github.com/rest/releases/releases#create-a-release" +} +EOF +) + +success_output=$(cat <<'EOF' +{ + "url": "https://api.github.com/repos/Smaug123/WoofWare.DotnetRuntimeLocator/releases/158152116", + "assets_url": "https://api.github.com/repos/Smaug123/WoofWare.DotnetRuntimeLocator/releases/158152116/assets", + "upload_url": "https://uploads.github.com/repos/Smaug123/WoofWare.DotnetRuntimeLocator/releases/158152116/assets{?name,label}", + "html_url": "https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator/releases/tag/WoofWare.DotnetRuntimeLocator.2.1.30", + "id": 158152116, + "author": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "node_id": "RE_kwDOJfksgc4JbTW0", + "tag_name": "WoofWare.DotnetRuntimeLocator.2.1.30", + "target_commitish": "main", + "name": "WoofWare.DotnetRuntimeLocator.2.1.30", + "draft": false, + "prerelease": false, + "created_at": "2024-05-30T11:00:55Z", + "published_at": "2024-05-30T11:03:02Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/Smaug123/WoofWare.DotnetRuntimeLocator/tarball/WoofWare.DotnetRuntimeLocator.2.1.30", + "zipball_url": "https://api.github.com/repos/Smaug123/WoofWare.DotnetRuntimeLocator/zipball/WoofWare.DotnetRuntimeLocator.2.1.30", + "body": null +} +EOF +) + +HANDLE_OUTPUT='' +handle_error() { + ERROR_OUTPUT="$1" + exit_message=$(echo "$ERROR_OUTPUT" | jq -r --exit-status 'if .errors | length == 1 then .errors[0].code else null end') + if [ "$exit_message" = "already_exists" ] ; then + HANDLE_OUTPUT="Did not create GitHub release because it already exists at this version." + else + echo "Unexpected error output from curl: $(cat curl_output.json)" + echo "JQ output: $(exit_message)" + exit 2 + fi +} + +run_tests() { + handle_error "$failed_output" + if [ "$HANDLE_OUTPUT" != "Did not create GitHub release because it already exists at this version." ]; then + echo "Bad output from handler: $HANDLE_OUTPUT" + exit 3 + fi + HANDLE_OUTPUT='' + echo "Tests passed." +} + +run_tests + +if [ "$DRY_RUN" != 1 ] ; then + if curl --fail-with-body -L -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $GITHUB_TOKEN" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/Smaug123/WoofWare.DotnetRuntimeLocator/releases -d "$curl_body" > curl_output.json; then + echo "Curl succeeded." + else + handle_error "$(cat curl_output.json)" + echo "$HANDLE_OUTPUT" + fi +fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38fb0e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ +.idea/ +*.sln.DotSettings.user +.DS_Store +result +.analyzerpackages/ +analysis.sarif +.direnv/ diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..cbf2f3e --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,16 @@ + + + embedded + true + [UNDEFINED] + true + true + true + embedded + FS3388,FS3559 + + + + + + diff --git a/Example/Example.fsproj b/Example/Example.fsproj new file mode 100644 index 0000000..18f0d71 --- /dev/null +++ b/Example/Example.fsproj @@ -0,0 +1,17 @@ + + + + Exe + net8.0 + true + + + + + + + + + + + diff --git a/Example/Program.fs b/Example/Program.fs new file mode 100644 index 0000000..26250a3 --- /dev/null +++ b/Example/Program.fs @@ -0,0 +1,21 @@ +namespace Example + +open System +open WoofWare.DotnetRuntimeLocator + +module Program = + [] + let main argv = + let info = DotnetEnvironmentInfo.Get () + Console.WriteLine info + Console.WriteLine ("SDKs:") + + for sdk in info.Sdks do + Console.WriteLine $"SDK: %O{sdk}" + + Console.WriteLine ("Frameworks:") + + for f in info.Frameworks do + Console.WriteLine $"Framework: %O{f}" + + 0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..debcfa2 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# WoofWare.DotnetRuntimeLocator + +Helpers to locate the .NET runtime and SDKs programmatically. +(If you're parsing `dotnet --list-runtimes`, you're doing it wrong!) + +## Usage + +See [the example](Example/Program.fs). + +```fsharp +let info = DotnetEnvironmentInfo.Get () +// or, if you already know a path to the `dotnet` executable... +let info = DotnetEnvironmentInfo.Get "/path/to/dotnet" +``` diff --git a/WoofWare.DotnetRuntimeLocator.sln b/WoofWare.DotnetRuntimeLocator.sln new file mode 100644 index 0000000..b293925 --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.DotnetRuntimeLocator", "WoofWare.DotnetRuntimeLocator\WoofWare.DotnetRuntimeLocator.csproj", "{6AEC4B30-8AFE-4071-A5FB-DBA6EB2D8194}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Test", "WoofWare.DotnetRuntimeLocator\Test\Test.fsproj", "{7123924E-E6C5-4612-9E2E-2C4B8D14C7B2}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Example", "Example\Example.fsproj", "{C295BC67-F932-4225-9183-7173B26E1F9E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6AEC4B30-8AFE-4071-A5FB-DBA6EB2D8194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AEC4B30-8AFE-4071-A5FB-DBA6EB2D8194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AEC4B30-8AFE-4071-A5FB-DBA6EB2D8194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AEC4B30-8AFE-4071-A5FB-DBA6EB2D8194}.Release|Any CPU.Build.0 = Release|Any CPU + {7123924E-E6C5-4612-9E2E-2C4B8D14C7B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7123924E-E6C5-4612-9E2E-2C4B8D14C7B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7123924E-E6C5-4612-9E2E-2C4B8D14C7B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7123924E-E6C5-4612-9E2E-2C4B8D14C7B2}.Release|Any CPU.Build.0 = Release|Any CPU + {C295BC67-F932-4225-9183-7173B26E1F9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C295BC67-F932-4225-9183-7173B26E1F9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C295BC67-F932-4225-9183-7173B26E1F9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C295BC67-F932-4225-9183-7173B26E1F9E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/WoofWare.DotnetRuntimeLocator/Boilerplate.cs b/WoofWare.DotnetRuntimeLocator/Boilerplate.cs new file mode 100644 index 0000000..698fadd --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/Boilerplate.cs @@ -0,0 +1,28 @@ +namespace System.Runtime.CompilerServices +{ + internal class RequiredMemberAttribute : Attribute + { + } + + internal class CompilerFeatureRequiredAttribute : Attribute + { + public CompilerFeatureRequiredAttribute(string name) + { + } + } +} + +namespace System.Diagnostics.CodeAnalysis +{ + [AttributeUsage(AttributeTargets.Constructor)] + internal sealed class SetsRequiredMembersAttribute : Attribute + { + } +} + +namespace System.Runtime.CompilerServices +{ + internal static class IsExternalInit + { + } +} diff --git a/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentFrameworkInfo.cs b/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentFrameworkInfo.cs new file mode 100644 index 0000000..5909afa --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentFrameworkInfo.cs @@ -0,0 +1,29 @@ +using System.IO; +using System.Runtime.InteropServices; + +namespace WoofWare.DotnetRuntimeLocator; + +/// +/// Information about a single instance of the .NET runtime. +/// +/// The name of this runtime, e.g. "Microsoft.NETCore.App" +/// +/// The path to this runtime, e.g. "/usr/bin/dotnet/shared/Microsoft.AspNetCore.App" (I'm guessing at +/// the prefix here, I use Nix so my paths are all different) +/// +/// The version of this runtime, e.g. "8.0.5" +public record DotnetEnvironmentFrameworkInfo(string Name, string Path, string Version) +{ + internal static DotnetEnvironmentFrameworkInfo FromNative( + InteropStructs.DotnetEnvironmentFrameworkInfoNative native) + { + if (native.size < 0 || native.size > int.MaxValue) + throw new InvalidDataException("size field did not fit in an int"); + + var size = (int)native.size; + if (size != Marshal.SizeOf(native)) + throw new InvalidDataException($"size field {size} did not match expected size {Marshal.SizeOf(native)}"); + + return new DotnetEnvironmentFrameworkInfo(native.name, native.path, native.version); + } +} diff --git a/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentInfo.cs b/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentInfo.cs new file mode 100644 index 0000000..d917d1f --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentInfo.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +namespace WoofWare.DotnetRuntimeLocator; + +/// +/// Information known to `dotnet` about what frameworks and runtimes are available. +/// +/// Version of the runtime, e.g. "8.0.5" +/// +/// A commit hash of the .NET runtime (as of this writing, this is probably a hash from +/// https://github.com/dotnet/runtime). +/// +/// Collection of .NET SDKs we were able to find. +/// Collection of .NET runtimes we were able to find. +public record DotnetEnvironmentInfo( + string HostFxrVersion, + string HostFxrCommitHash, + IReadOnlyList Sdks, + IReadOnlyList Frameworks) +{ + private static readonly Lazy HostFxr = new(() => + { + // First, we might be self-contained: try and find it next to us. + var selfContainedAttempt = Directory.GetParent(Assembly.GetExecutingAssembly().Location); + if (selfContainedAttempt != null) + { + var attempt = selfContainedAttempt.EnumerateFiles("*hostfxr*").FirstOrDefault(); + if (attempt != null) return attempt; + } + + var runtimeDir = new DirectoryInfo(RuntimeEnvironment.GetRuntimeDirectory()); + var parent1 = runtimeDir.Parent ?? + throw new Exception("Unable to locate the host/fxr directory in the .NET runtime"); + var parent2 = parent1.Parent ?? + throw new Exception("Unable to locate the host/fxr directory in the .NET runtime"); + var parent3 = parent2.Parent ?? + throw new Exception("Unable to locate the host/fxr directory in the .NET runtime"); + var fxrDir = new DirectoryInfo(Path.Combine(parent3.FullName, "host", "fxr")); + return fxrDir.EnumerateDirectories().First().EnumerateFiles("*hostfxr*").First(); + }); + + private static FileInfo ResolveAllSymlinks(FileInfo f) + { + while (!ReferenceEquals(null, f.LinkTarget)) + { + var parent = f.Directory ?? new DirectoryInfo("/"); + f = new FileInfo(Path.Combine(parent.FullName, f.LinkTarget)); + } + + return f; + } + + /// + /// Takes a DotnetEnvironmentInfoNative and a return location, which must fit a DotnetEnvironmentInfo. + /// Renders the DotnetEnvironmentInfoNative and stores it in the return location. + /// + private static void StoreResult(IntPtr envInfo, IntPtr retLoc) + { + var toRet = FromNativeConstructor.FromNative( + Marshal.PtrToStructure(envInfo)); + var handle = GCHandle.FromIntPtr(retLoc); + handle.Target = toRet; + } + + private static unsafe DotnetEnvironmentInfo CallDelegate(string? dotnetExePath, RuntimeDelegate f) + { + byte[]? dotnet = null; + if (dotnetExePath != null) + { + dotnet = Encoding.ASCII.GetBytes(dotnetExePath); + } + fixed (byte* dotnetPath = dotnet) + { + DotnetEnvironmentInfo? toRet = null; + var handle = GCHandle.Alloc(toRet); + try + { + var del = (StoreResultDelegate)StoreResult; + var callback = Marshal.GetFunctionPointerForDelegate(del); + + var rc = f.Invoke((IntPtr)dotnetPath, IntPtr.Zero, callback, GCHandle.ToIntPtr(handle)); + if (rc != 0) throw new Exception($"Could not obtain .NET environment information (exit code: {rc})"); + + if (ReferenceEquals(null, handle.Target)) + throw new NullReferenceException( + "Unexpectedly failed to populate DotnetEnvironmentInfo, despite the native call succeeding."); + return (DotnetEnvironmentInfo)handle.Target; + } + finally + { + handle.Free(); + } + } + } + + /// + /// Get the environment information that is available to the specified `dotnet` executable. + /// + /// A `dotnet` (or `dotnet.exe`) executable, e.g. one from /usr/bin/dotnet. Set this to null if you want us to just do our best. + /// Information about the environment available to the given executable. + /// Throws on any failure; handles nothing gracefully. + public static DotnetEnvironmentInfo GetSpecific(FileInfo? dotnetExe) + { + var hostFxr = HostFxr.Value; + var lib = NativeLibrary.Load(hostFxr.FullName); + try + { + var ptr = NativeLibrary.GetExport(lib, "hostfxr_get_dotnet_environment_info"); + if (ptr == IntPtr.Zero) throw new Exception("Unable to load function from native library"); + + var f = Marshal.GetDelegateForFunctionPointer(ptr); + string? dotnetParent = null; + if (dotnetExe != null) + { + var dotnetNoSymlinks = ResolveAllSymlinks(dotnetExe); + var parent = dotnetNoSymlinks.Directory; + if (parent != null) + { + dotnetParent = parent.FullName; + } + } + return CallDelegate(dotnetParent, f); + } + finally + { + NativeLibrary.Free(lib); + } + } + + private static FileInfo? FindDotnetAbove(DirectoryInfo path) + { + while (true) + { + var candidate = Path.Combine(path.FullName, "dotnet"); + if (File.Exists(candidate)) return new FileInfo(candidate); + + if (ReferenceEquals(path.Parent, null)) return null; + + path = path.Parent; + } + } + + /// + /// Get the environment information that is available to some arbitrary `dotnet` executable we were able to find. + /// + /// Information about the environment available to `dotnet`. + /// Throws on any failure; handles nothing gracefully. + public static DotnetEnvironmentInfo Get() + { + var dotnetExe = FindDotnetAbove(new DirectoryInfo(RuntimeEnvironment.GetRuntimeDirectory())); + + if (ReferenceEquals(dotnetExe, null)) + { + // This can happen! Maybe we're self-contained. + return GetSpecific(null); + } + + return GetSpecific(dotnetExe); + } + + /// + /// The signature of hostfxr_get_dotnet_environment_info. + /// Its implementation is + /// https://github.com/dotnet/runtime/blob/2dba5a3587de19160fb09129dcd3d7a4089b67b5/src/native/corehost/fxr/hostfxr.cpp#L357 + /// Takes: + /// * The ASCII-encoded path to the directory which contains the `dotnet` executable + /// * A structure which is reserved for future use and which must currently be null + /// * A pointer to a callback which takes two arguments: a DotnetEnvironmentInfoNative + /// (https://github.com/dotnet/runtime/blob/2dba5a3587de19160fb09129dcd3d7a4089b67b5/src/native/corehost/hostfxr.h#L311) + /// and a context object you supplied. + /// This callback is represented by the type `StoreResultDelegate`. + /// * A pointer to the context object you want to consume in the callback. + /// Returns zero on success. + /// + internal delegate int RuntimeDelegate(IntPtr pathToDotnetExeDirectory, IntPtr mustBeNull, IntPtr outputCallback, + IntPtr outputArg); + + /// + /// The callback which you pass to RuntimeDelegate. + /// Takes: + /// * a DotnetEnvironmentInfoNative + /// (https://github.com/dotnet/runtime/blob/2dba5a3587de19160fb09129dcd3d7a4089b67b5/src/native/corehost/hostfxr.h#L311) + /// * a context object, which is up to you to define and to pass into the RuntimeDelegate. + /// + internal delegate void StoreResultDelegate(IntPtr envInfo, IntPtr retLoc); +} + +internal class FromNativeConstructor +{ + internal static DotnetEnvironmentInfo FromNative(InteropStructs.DotnetEnvironmentInfoNative native) + { + if (native.size < 0 || native.size > int.MaxValue) + throw new InvalidDataException("size field did not fit in an int"); + var size = (int)native.size; + if (native.framework_count < 0 || native.framework_count > int.MaxValue) + throw new InvalidDataException("framework_count field did not fit in an int"); + var frameworkCount = (int)native.framework_count; + if (native.sdk_count < 0 || native.sdk_count > int.MaxValue) + throw new InvalidDataException("sdk_count field did not fit in an int"); + var sdkCount = (int)native.sdk_count; + + if (size != Marshal.SizeOf(native)) + throw new InvalidDataException($"size field {size} did not match expected size {Marshal.SizeOf(native)}"); + + var frameworks = new List((int)native.framework_count); + for (var i = 0; i < frameworkCount; i++) + { + var frameworkInfo = new IntPtr(native.frameworks.ToInt64() + + i * Marshal.SizeOf()); + frameworks.Add(DotnetEnvironmentFrameworkInfo.FromNative( + Marshal.PtrToStructure(frameworkInfo))); + } + + var sdks = new List((int)native.sdk_count); + for (var i = 0; i < sdkCount; i++) + { + var sdkInfo = new IntPtr(native.sdks.ToInt64() + + i * Marshal.SizeOf()); + sdks.Add(DotnetEnvironmentSdkInfo.FromNative( + Marshal.PtrToStructure(sdkInfo))); + } + + return new DotnetEnvironmentInfo(native.hostfxr_version, native.hostfxr_commit_hash, sdks, frameworks); + } +} diff --git a/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentSdkInfo.cs b/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentSdkInfo.cs new file mode 100644 index 0000000..b76c42b --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/DotnetEnvironmentSdkInfo.cs @@ -0,0 +1,27 @@ +using System.IO; +using System.Runtime.InteropServices; + +namespace WoofWare.DotnetRuntimeLocator; + +/// +/// Information about a single instance of the .NET SDK. +/// +/// +/// The path to this SDK, e.g. "/usr/bin/dotnet/sdk/8.0.300" (I'm guessing at the prefix there, I use +/// Nix so my paths are different) +/// +/// e.g. "8.0.300" +public record DotnetEnvironmentSdkInfo(string Path, string Version) +{ + internal static DotnetEnvironmentSdkInfo FromNative(InteropStructs.DotnetEnvironmentSdkInfoNative native) + { + if (native.size < 0 || native.size > int.MaxValue) + throw new InvalidDataException("size field did not fit in an int"); + + var size = (int)native.size; + if (size != Marshal.SizeOf(native)) + throw new InvalidDataException($"size field {size} did not match expected size {Marshal.SizeOf(native)}"); + + return new DotnetEnvironmentSdkInfo(native.path, native.version); + } +} diff --git a/WoofWare.DotnetRuntimeLocator/InteropStructs.cs b/WoofWare.DotnetRuntimeLocator/InteropStructs.cs new file mode 100644 index 0000000..c3a3f85 --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/InteropStructs.cs @@ -0,0 +1,46 @@ +using System; +using System.Runtime.InteropServices; + +namespace WoofWare.DotnetRuntimeLocator; + +internal static class InteropStructs +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal struct DotnetEnvironmentSdkInfoNative + { + public nuint size; + public string version; + public string path; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal struct DotnetEnvironmentFrameworkInfoNative + { + public nuint size; + public string name; + public string version; + public string path; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal struct DotnetEnvironmentInfoNative + { + public nuint size; + public string hostfxr_version; + public string hostfxr_commit_hash; + + public nuint sdk_count; + + /// + /// Pointer to an array of DotnetEnvironmentSdkInfoNative, of length `sdk_count` + /// + public IntPtr sdks; + + public nuint framework_count; + + /// + /// Pointer to an array of DotnetEnvironmentFrameworkInfoNative, of length `framework_count` + /// + public IntPtr frameworks; + } +} diff --git a/WoofWare.DotnetRuntimeLocator/SurfaceBaseline.txt b/WoofWare.DotnetRuntimeLocator/SurfaceBaseline.txt new file mode 100644 index 0000000..8c34e00 --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/SurfaceBaseline.txt @@ -0,0 +1,47 @@ +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo inherit obj, implements WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo System.IEquatable +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo..ctor [constructor]: (string, string, string) +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.$ [method]: unit -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.Deconstruct [method]: (System.String&, System.String&, System.String&) -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.get_Name [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.get_Path [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.get_Version [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.Name [property]: string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.op_Equality [static method]: (WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo) -> bool +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.op_Inequality [static method]: (WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo) -> bool +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.Path [property]: string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.set_Name [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.set_Path [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.set_Version [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo.Version [property]: string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo inherit obj, implements WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo System.IEquatable +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo..ctor [constructor]: (string, string, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo System.Collections.Generic.IReadOnlyList, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo System.Collections.Generic.IReadOnlyList) +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.$ [method]: unit -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.Deconstruct [method]: (System.String&, System.String&, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyList) -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.Frameworks [property]: WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo System.Collections.Generic.IReadOnlyList +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.Get [static method]: unit -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.get_Frameworks [method]: unit -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo System.Collections.Generic.IReadOnlyList +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.get_HostFxrCommitHash [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.get_HostFxrVersion [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.get_Sdks [method]: unit -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo System.Collections.Generic.IReadOnlyList +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.GetSpecific [static method]: System.IO.FileInfo -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.HostFxrCommitHash [property]: string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.HostFxrVersion [property]: string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.op_Equality [static method]: (WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo) -> bool +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.op_Inequality [static method]: (WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo) -> bool +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.Sdks [property]: WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo System.Collections.Generic.IReadOnlyList +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.set_Frameworks [method]: WoofWare.DotnetRuntimeLocator.DotnetEnvironmentFrameworkInfo System.Collections.Generic.IReadOnlyList -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.set_HostFxrCommitHash [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.set_HostFxrVersion [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentInfo.set_Sdks [method]: WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo System.Collections.Generic.IReadOnlyList -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo inherit obj, implements WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo System.IEquatable +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo..ctor [constructor]: (string, string) +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.$ [method]: unit -> WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.Deconstruct [method]: (System.String&, System.String&) -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.get_Path [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.get_Version [method]: unit -> string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.op_Equality [static method]: (WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo) -> bool +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.op_Inequality [static method]: (WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo, WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo) -> bool +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.Path [property]: string +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.set_Path [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.set_Version [method]: string -> unit +WoofWare.DotnetRuntimeLocator.DotnetEnvironmentSdkInfo.Version [property]: string \ No newline at end of file diff --git a/WoofWare.DotnetRuntimeLocator/Test/Test.fsproj b/WoofWare.DotnetRuntimeLocator/Test/Test.fsproj new file mode 100644 index 0000000..cea00be --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/Test/Test.fsproj @@ -0,0 +1,26 @@ + + + + net8.0 + false + true + + + + + + + + + + + + + + + + + + + + diff --git a/WoofWare.DotnetRuntimeLocator/Test/TestDotnetEnvironmentInfo.fs b/WoofWare.DotnetRuntimeLocator/Test/TestDotnetEnvironmentInfo.fs new file mode 100644 index 0000000..e892c06 --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/Test/TestDotnetEnvironmentInfo.fs @@ -0,0 +1,19 @@ +namespace WoofWare.DotnetRuntimeLocator.Test + +open System +open FsUnitTyped +open WoofWare.DotnetRuntimeLocator +open NUnit.Framework + +[] +module TestDotnetEnvironmentInfo = + + [] + let ``Can locate the runtime`` () = + let runtimes = DotnetEnvironmentInfo.Get () + + // In the test setup, there should be an SDK! + runtimes.Sdks |> Seq.length |> shouldBeGreaterThan 0 + runtimes.Frameworks |> Seq.length |> shouldBeGreaterThan 0 + + Console.WriteLine $"%O{runtimes}" diff --git a/WoofWare.DotnetRuntimeLocator/Test/TestSurface.fs b/WoofWare.DotnetRuntimeLocator/Test/TestSurface.fs new file mode 100644 index 0000000..cafcd6c --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/Test/TestSurface.fs @@ -0,0 +1,23 @@ +namespace WoofWare.DotnetRuntimeLocator.Test + +open NUnit.Framework +open ApiSurface + +[] +module TestSurface = + let assembly = typeof.Assembly + + [] + let ``Ensure API surface has not been modified`` () = ApiSurface.assertIdentical assembly + + [] + let ``Update API surface`` () = + ApiSurface.writeAssemblyBaseline assembly + + [] + let ``Ensure public API is fully documented`` () = + DocCoverage.assertFullyDocumented assembly + + [] + let ``Ensure version is monotonic`` () = + MonotonicVersion.validate assembly "WoofWare.DotnetRuntimeLocator" diff --git a/WoofWare.DotnetRuntimeLocator/WoofWare.DotnetRuntimeLocator.csproj b/WoofWare.DotnetRuntimeLocator/WoofWare.DotnetRuntimeLocator.csproj new file mode 100644 index 0000000..bb04fe1 --- /dev/null +++ b/WoofWare.DotnetRuntimeLocator/WoofWare.DotnetRuntimeLocator.csproj @@ -0,0 +1,40 @@ + + + + net6.0 + enable + latest + false + true + true + Patrick Stevens + Copyright (c) Patrick Stevens 2024 + Helpers to locate the .NET runtime and SDKs + git + https://github.com/Smaug123/WoofWare.DotnetRuntimeLocator + MIT + README.md + logo.png + runtime;locate;sdk;list-runtimes;list-sdks + true + + + + + + + + + + + + True + \ + + + True + \ + + + + diff --git a/WoofWare.DotnetRuntimeLocator/logo.png b/WoofWare.DotnetRuntimeLocator/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..89f4d2f331dfdfd13573f062ea1fd9451607f66d GIT binary patch literal 75554 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