diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fee6a04a..bf898f8f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -85,7 +85,7 @@ body: attributes: label: .NET Version description: "Output of `dotnet --version`" - placeholder: "e.g., 8.0.300" + placeholder: "e.g., 10.0.100" - type: input id: os diff --git a/.github/workflows/verso-ci.yml b/.github/workflows/verso-ci.yml index 50dcd256..2732f658 100644 --- a/.github/workflows/verso-ci.yml +++ b/.github/workflows/verso-ci.yml @@ -40,9 +40,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 8.0.x - 10.0.x + dotnet-version: "10.0.x" # The Python kernel launches the user's own interpreter, so a large part of its suite needs # a real one on PATH and reports a missing prerequisite without it. Pinned rather than left @@ -135,31 +133,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 8.0.x - 10.0.x - - - name: Bundle blazor.web.js for CLI - run: | - DIR="src/Verso.Cli/bin/Release/net8.0/wwwroot/_framework" - mkdir -p "$DIR" - DLL=$(find "$DOTNET_ROOT/shared/Microsoft.AspNetCore.App" \ - -path "*/8.*/Microsoft.AspNetCore.Components.Endpoints.dll" | head -1) - if [ -z "$DLL" ]; then - echo "::warning::Could not find .NET 8 Components.Endpoints.dll" - exit 0 - fi - dotnet new console -o /tmp/_ebjs --no-restore -f net8.0 - cat > /tmp/_ebjs/Program.cs << 'EOF' - var asm = System.Reflection.Assembly.LoadFrom(args[0]); - using var s = asm.GetManifestResourceStream("_framework/blazor.web.js"); - if (s == null) { Console.Error.WriteLine("Resource not found"); return; } - Directory.CreateDirectory(Path.GetDirectoryName(args[1])!); - using var f = File.Create(args[1]); - s.CopyTo(f); - Console.WriteLine($"Extracted blazor.web.js ({f.Length} bytes)"); - EOF - dotnet run --project /tmp/_ebjs -- "$DLL" "$DIR/blazor.web.js" + dotnet-version: "10.0.x" - name: Build run: dotnet build Verso.sln -c Release @@ -187,6 +161,9 @@ jobs: dotnet pack samples/showcase/slide-studio/src/Verso.Showcase.SlideStudio/Verso.Showcase.SlideStudio.csproj -c Release -p:GeneratePackageOnBuild=false -o packages dotnet pack samples/showcase/dag-notebook/src/Verso.Showcase.DagNotebook/Verso.Showcase.DagNotebook.csproj -c Release -p:GeneratePackageOnBuild=false -o packages + - name: Check the CLI tool carries blazor.web.js + run: unzip -l packages/Verso.Cli.*.nupkg | grep -q "tools/net10.0/any/wwwroot/_framework/blazor.web.js" + # The showcases sit outside Verso.sln, so their tests are not part of the main test run. - name: Test showcase samples run: | @@ -223,9 +200,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 8.0.x - 10.0.x + dotnet-version: "10.0.x" # Builds the CLI it serves from along with the tests, so the run always serves this commit. - name: Run browser tests diff --git a/.github/workflows/verso-release.yml b/.github/workflows/verso-release.yml index 0f26c468..4208d390 100644 --- a/.github/workflows/verso-release.yml +++ b/.github/workflows/verso-release.yml @@ -34,9 +34,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 8.0.x - 10.0.x + dotnet-version: "10.0.x" # The Python kernel launches a real interpreter, and a large part of its suite treats a # missing one as a failure on a build server rather than a skip. Pinned here for the same @@ -51,31 +49,6 @@ jobs: - name: Install Python test dependencies run: python -m pip install --upgrade pip jedi - - name: Bundle blazor.web.js for CLI - run: | - # blazor.web.js is embedded in Components.Endpoints.dll in .NET 8/9 - # but not in .NET 10+. Extract it so verso serve works when the tool - # rolls forward to a runtime that no longer bundles the script. - DIR="src/Verso.Cli/bin/Release/net8.0/wwwroot/_framework" - mkdir -p "$DIR" - DLL=$(find "$DOTNET_ROOT/shared/Microsoft.AspNetCore.App" \ - -path "*/8.*/Microsoft.AspNetCore.Components.Endpoints.dll" | head -1) - if [ -z "$DLL" ]; then - echo "::warning::Could not find .NET 8 Components.Endpoints.dll" - exit 0 - fi - dotnet new console -o /tmp/_ebjs --no-restore -f net8.0 - cat > /tmp/_ebjs/Program.cs << 'EOF' - var asm = System.Reflection.Assembly.LoadFrom(args[0]); - using var s = asm.GetManifestResourceStream("_framework/blazor.web.js"); - if (s == null) { Console.Error.WriteLine("Resource not found"); return; } - Directory.CreateDirectory(Path.GetDirectoryName(args[1])!); - using var f = File.Create(args[1]); - s.CopyTo(f); - Console.WriteLine($"Extracted blazor.web.js ({f.Length} bytes)"); - EOF - dotnet run --project /tmp/_ebjs -- "$DLL" "$DIR/blazor.web.js" - - name: Build run: dotnet build Verso.sln -c Release -p:Version=${{ steps.version.outputs.version }} @@ -107,6 +80,9 @@ jobs: dotnet pack samples/showcase/slide-studio/src/Verso.Showcase.SlideStudio/Verso.Showcase.SlideStudio.csproj -c Release -p:Version=${{ steps.version.outputs.version }} -p:GeneratePackageOnBuild=false -o packages dotnet pack samples/showcase/dag-notebook/src/Verso.Showcase.DagNotebook/Verso.Showcase.DagNotebook.csproj -c Release -p:Version=${{ steps.version.outputs.version }} -p:GeneratePackageOnBuild=false -o packages + - name: Check the CLI tool carries blazor.web.js + run: unzip -l packages/Verso.Cli.*.nupkg | grep -q "tools/net10.0/any/wwwroot/_framework/blazor.web.js" + - name: Upload NuGet packages uses: actions/upload-artifact@v4 with: @@ -129,9 +105,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 8.0.x - 10.0.x + dotnet-version: "10.0.x" - name: Set version run: npm version ${{ needs.build-and-test.outputs.version }} --no-git-tag-version diff --git a/Directory.Build.props b/Directory.Build.props index 4759ffbc..57884a03 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -17,7 +17,7 @@ published by newer releases. --> 1.3.0 - net8.0;net10.0 + net10.0 diff --git a/README.md b/README.md index 8f46ffd6..e80970df 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

License: MIT - .NET 8 | 10 + .NET 10 CI NuGet GitHub Release @@ -46,7 +46,7 @@ dotnet tool install -g Verso.Cli verso serve ``` -Requirements: the VS Code extension needs the [.NET runtime, version 8.0 or later](https://dotnet.microsoft.com/download/dotnet) and offers to install it for you if it is missing; the `verso` CLI needs the [.NET SDK](https://dotnet.microsoft.com/download/dotnet/10.0) for `dotnet tool install`. [Node.js 18+](https://nodejs.org/) and [Python 3.8 or newer](https://www.python.org/downloads/) are optional; they enable the JavaScript/TypeScript and Python kernels (JavaScript falls back to the pure .NET Jint interpreter when Node.js is absent). +Requirements: the VS Code extension needs the [.NET runtime, version 10.0 or later](https://dotnet.microsoft.com/download/dotnet/10.0) and offers to install it for you if it is missing; the `verso` CLI needs the [.NET SDK](https://dotnet.microsoft.com/download/dotnet/10.0) for `dotnet tool install`. [Node.js 18+](https://nodejs.org/) and [Python 3.8 or newer](https://www.python.org/downloads/) are optional; they enable the JavaScript/TypeScript and Python kernels (JavaScript falls back to the pure .NET Jint interpreter when Node.js is absent). ## Why Verso diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index 9b0e792d..a4f0aff9 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -7,10 +7,10 @@ The original copyright notices and license texts are provided for each component | Component | Version | License | Project | |---|---|---|---| -| Microsoft.CodeAnalysis (Roslyn) | 4.12.0 | MIT | [dotnet/roslyn](https://github.com/dotnet/roslyn) | +| Microsoft.CodeAnalysis (Roslyn) | 5.0.0 | MIT | [dotnet/roslyn](https://github.com/dotnet/roslyn) | | NuGet.Protocol | 6.9.1 | Apache-2.0 | [NuGet/NuGet.Client](https://github.com/NuGet/NuGet.Client) | -| Microsoft.AspNetCore.Components | 8.0.0 | MIT | [dotnet/aspnetcore](https://github.com/dotnet/aspnetcore) | -| Microsoft.PowerShell.SDK | 7.4.7 | MIT | [PowerShell/PowerShell](https://github.com/PowerShell/PowerShell) | +| Microsoft.AspNetCore.Components | 10.0.14 | MIT | [dotnet/aspnetcore](https://github.com/dotnet/aspnetcore) | +| Microsoft.PowerShell.SDK | 7.6.9 | MIT | [PowerShell/PowerShell](https://github.com/PowerShell/PowerShell) | | FSharp.Compiler.Service | 43.12.202 | MIT | [dotnet/fsharp](https://github.com/dotnet/fsharp) | | Jint | 4.12.0 | BSD-2-Clause | [sebastienros/jint](https://github.com/sebastienros/jint) | | Markdig | 0.37.0 | BSD-2-Clause | [lunet-io/markdig](https://github.com/lunet-io/markdig) | diff --git a/docs/extensions/best-practices.md b/docs/extensions/best-practices.md index b535ee91..15fcf024 100644 --- a/docs/extensions/best-practices.md +++ b/docs/extensions/best-practices.md @@ -90,10 +90,10 @@ Where possible, keep your extensions stateless. The Dice sample demonstrates thi ### Random Number Generators -If using `Random`, be aware that `System.Random` is not thread-safe prior to .NET 6. On .NET 8, `Random.Shared` is the preferred thread-safe option: +If using `Random`, be aware that `System.Random` is not thread-safe prior to .NET 6. `Random.Shared` is the thread-safe option: ```csharp -// Good - thread-safe on .NET 8 +// Good - thread-safe var roll = Random.Shared.Next(1, sides + 1); // Risky - private instance may be called from multiple threads diff --git a/docs/extensions/getting-started.md b/docs/extensions/getting-started.md index f37675f0..4c01e824 100644 --- a/docs/extensions/getting-started.md +++ b/docs/extensions/getting-started.md @@ -4,7 +4,7 @@ This guide walks you through creating your first Verso extension, from setting u ## Prerequisites -- [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) or later +- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) or later - A code editor (Visual Studio, VS Code, or Rider) - Familiarity with C# and async/await @@ -12,7 +12,7 @@ Verify your SDK installation: ```bash dotnet --version -# Should output 8.0.x or higher +# Should output 10.0.x or higher ``` ## Installing the Verso Extension Template @@ -89,7 +89,7 @@ The generated `.csproj` references the `Verso.Abstractions` NuGet package and en ```xml - net8.0 + net10.0 enable enable true @@ -145,7 +145,7 @@ dotnet build MyDashboard/ dotnet build MyDashboard/MyDashboard.Tests/ ``` -The build output (DLL) will be in `bin/Debug/net8.0/`. Because `GeneratePackageOnBuild` is set, a `.nupkg` is also produced on each build. +The build output (DLL) will be in `bin/Debug/net10.0/`. Because `GeneratePackageOnBuild` is set, a `.nupkg` is also produced on each build. ## Running Tests @@ -164,7 +164,7 @@ During development you can load your extension straight from its build output, w **From a notebook**, use the `#!extension` magic command with the path to your compiled assembly: ``` -#!extension ./MyDashboard/bin/Debug/net8.0/MyDashboard.dll +#!extension ./MyDashboard/bin/Debug/net10.0/MyDashboard.dll ``` The path is resolved relative to the notebook's directory, and local assemblies load without a consent prompt. @@ -172,7 +172,7 @@ The path is resolved relative to the notebook's directory, and local assemblies **From the CLI**, point any command at a directory of extension assemblies with `--extensions`: ```bash -verso serve notebook.verso --extensions ./MyDashboard/bin/Debug/net8.0/ +verso serve notebook.verso --extensions ./MyDashboard/bin/Debug/net10.0/ ``` Verso scans that directory for extension DLLs and loads them alongside the built-ins. The `--extensions` flag works on `serve`, `run`, `repl`, `convert`, and `export`. In VS Code, set the `verso.extensionsPath` setting instead. diff --git a/docs/extensions/packaging-and-publishing.md b/docs/extensions/packaging-and-publishing.md index edcefee6..80b3c295 100644 --- a/docs/extensions/packaging-and-publishing.md +++ b/docs/extensions/packaging-and-publishing.md @@ -9,7 +9,7 @@ The Verso extension template generates a `.csproj` that is already configured fo ```xml - net8.0 + net10.0 enable enable @@ -195,7 +195,7 @@ Once your package is on NuGet.org (or any feed in a user's NuGet configuration), - macOS and Linux: `~/.verso/extensions////` - Windows: `%APPDATA%\verso\extensions\\\\` -The `` segment records the runtime the assemblies were installed for, so hosts running on different .NET versions each keep a compatible copy side by side. A package that multi-targets (for example `net8.0` and `net10.0`) lets each host pick the newest lib group its runtime can load; a single `net8.0` target also works on newer runtimes. +The `` segment records the runtime the assemblies were installed for, so hosts running on different .NET versions each keep a compatible copy side by side. Extensions that reference Verso.Abstractions 1.3.0 or later target `net10.0`. Packages built earlier for `net8.0` still load, because a newer runtime runs older assets. Because an extension is executable code, Verso asks the user to approve a package the first time it loads, and remembers that approval per version. A new version prompts again. Keep this in mind when you publish updates: bumping the version is a deliberate re-consent point for your users, not a silent upgrade. diff --git a/docs/extensions/testing-extensions.md b/docs/extensions/testing-extensions.md index 01453a32..cb2122d7 100644 --- a/docs/extensions/testing-extensions.md +++ b/docs/extensions/testing-extensions.md @@ -11,7 +11,7 @@ Add `Verso.Testing` (and a test framework) to your test project: ```xml - net8.0 + net10.0 enable enable false diff --git a/docs/guides/cli-reference.md b/docs/guides/cli-reference.md index b8d6866e..3179f43f 100644 --- a/docs/guides/cli-reference.md +++ b/docs/guides/cli-reference.md @@ -14,7 +14,7 @@ dotnet tool install -g Verso.Cli dotnet tool update -g Verso.Cli ``` -It requires the .NET 8.0 SDK or later. After installing, `verso --help` lists the commands, and every command has its own `--help`. +It requires the .NET 10 SDK or later. After installing, `verso --help` lists the commands, and every command has its own `--help`. ## Global options diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md index 39ec0c03..c040e460 100644 --- a/docs/guides/getting-started.md +++ b/docs/guides/getting-started.md @@ -12,7 +12,7 @@ Install the **Verso Notebook** extension (`datafication.verso-notebook`) from th ### Command line -Verso is also a .NET global tool. It needs the .NET 8.0 SDK or later: +Verso is also a .NET global tool. It needs the .NET 10 SDK or later: ```bash dotnet tool install -g Verso.Cli diff --git a/docs/guides/managing-extensions.md b/docs/guides/managing-extensions.md index f8ec46cb..3006a0db 100644 --- a/docs/guides/managing-extensions.md +++ b/docs/guides/managing-extensions.md @@ -22,7 +22,7 @@ Installed packages are unpacked into a managed store on disk: - macOS and Linux: `~/.verso/extensions////` - Windows: `%APPDATA%\verso\extensions\\\\` -Each version lives in its own folder, so multiple versions can coexist. Inside a version folder, assemblies are grouped by the .NET runtime they were installed for (for example `net8.0`), so notebook hosts running on different .NET versions can share the same store. +Each version lives in its own folder, so multiple versions can coexist. Inside a version folder, assemblies are grouped by the .NET runtime they were installed for (for example `net10.0`), so notebook hosts running on different .NET versions can share the same store. Once a package is installed, its row lists what it added: a kernel, a layout engine, a theme, and so on. A package that loaded but contributed no extension point at all is marked as adding nothing, which is worth knowing since the marketplace searches all of NuGet and will happily install an ordinary library. @@ -74,7 +74,7 @@ You do not need to publish to a feed to try an extension you are building. Two o - From a notebook, use the `#!extension` magic command with a path to the compiled assembly: ``` - #!extension ./MyExtension/bin/Debug/net8.0/MyExtension.dll + #!extension ./MyExtension/bin/Debug/net10.0/MyExtension.dll ``` The path is resolved relative to the notebook's directory, and a local assembly loads without a consent prompt. @@ -82,7 +82,7 @@ You do not need to publish to a feed to try an extension you are building. Two o - From the CLI, point any command at a directory of extension assemblies: ```bash - verso serve notebook.verso --extensions ./MyExtension/bin/Debug/net8.0/ + verso serve notebook.verso --extensions ./MyExtension/bin/Debug/net10.0/ ``` The `--extensions` flag works on `serve`, `run`, `repl`, `convert`, and `export`. In VS Code, set the `verso.extensionsPath` setting to the same directory. diff --git a/docs/showcase/overview.md b/docs/showcase/overview.md index 6f8dc27d..02ff97fd 100644 --- a/docs/showcase/overview.md +++ b/docs/showcase/overview.md @@ -45,7 +45,7 @@ dotnet build samples/showcase/grid-studio/src/Verso.Showcase.GridStudio Load the result into a notebook with a `#!extension` line naming the built assembly, then switch layouts. The path resolves relative to the notebook's folder: ``` -#!extension ./src/Verso.Showcase.GridStudio/bin/Debug/net8.0/Verso.Showcase.GridStudio.dll +#!extension ./src/Verso.Showcase.GridStudio/bin/Debug/net10.0/Verso.Showcase.GridStudio.dll ``` This is the loop to work in if you are reading a sample in order to write your own layout: edit, build, reopen, look. diff --git a/samples/cell-types/Verso.Sample.Diagram.Tests/Verso.Sample.Diagram.Tests.csproj b/samples/cell-types/Verso.Sample.Diagram.Tests/Verso.Sample.Diagram.Tests.csproj index dbeaff0b..97b82f08 100644 --- a/samples/cell-types/Verso.Sample.Diagram.Tests/Verso.Sample.Diagram.Tests.csproj +++ b/samples/cell-types/Verso.Sample.Diagram.Tests/Verso.Sample.Diagram.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/cell-types/Verso.Sample.Diagram/Verso.Sample.Diagram.csproj b/samples/cell-types/Verso.Sample.Diagram/Verso.Sample.Diagram.csproj index 4b427801..37fccad5 100644 --- a/samples/cell-types/Verso.Sample.Diagram/Verso.Sample.Diagram.csproj +++ b/samples/cell-types/Verso.Sample.Diagram/Verso.Sample.Diagram.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/extensions/Verso.Sample.Dice.Tests/Verso.Sample.Dice.Tests.csproj b/samples/extensions/Verso.Sample.Dice.Tests/Verso.Sample.Dice.Tests.csproj index 676e53c2..708c66e2 100644 --- a/samples/extensions/Verso.Sample.Dice.Tests/Verso.Sample.Dice.Tests.csproj +++ b/samples/extensions/Verso.Sample.Dice.Tests/Verso.Sample.Dice.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/extensions/Verso.Sample.Dice/Verso.Sample.Dice.csproj b/samples/extensions/Verso.Sample.Dice/Verso.Sample.Dice.csproj index 63c433ca..2e15eaa1 100644 --- a/samples/extensions/Verso.Sample.Dice/Verso.Sample.Dice.csproj +++ b/samples/extensions/Verso.Sample.Dice/Verso.Sample.Dice.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/kernels/Verso.Sample.Perl/Verso.Sample.Perl.csproj b/samples/kernels/Verso.Sample.Perl/Verso.Sample.Perl.csproj index ece5bf9d..45d43ace 100644 --- a/samples/kernels/Verso.Sample.Perl/Verso.Sample.Perl.csproj +++ b/samples/kernels/Verso.Sample.Perl/Verso.Sample.Perl.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/layouts/Verso.Sample.Slides.Tests/Verso.Sample.Slides.Tests.csproj b/samples/layouts/Verso.Sample.Slides.Tests/Verso.Sample.Slides.Tests.csproj index 6e145235..b002048f 100644 --- a/samples/layouts/Verso.Sample.Slides.Tests/Verso.Sample.Slides.Tests.csproj +++ b/samples/layouts/Verso.Sample.Slides.Tests/Verso.Sample.Slides.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/layouts/Verso.Sample.Slides/Verso.Sample.Slides.csproj b/samples/layouts/Verso.Sample.Slides/Verso.Sample.Slides.csproj index bb3cbd86..c43ba3ab 100644 --- a/samples/layouts/Verso.Sample.Slides/Verso.Sample.Slides.csproj +++ b/samples/layouts/Verso.Sample.Slides/Verso.Sample.Slides.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/layouts/Verso.Sample.Sparkline.Tests/Verso.Sample.Sparkline.Tests.csproj b/samples/layouts/Verso.Sample.Sparkline.Tests/Verso.Sample.Sparkline.Tests.csproj index bdec21ec..be4f17ab 100644 --- a/samples/layouts/Verso.Sample.Sparkline.Tests/Verso.Sample.Sparkline.Tests.csproj +++ b/samples/layouts/Verso.Sample.Sparkline.Tests/Verso.Sample.Sparkline.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/layouts/Verso.Sample.Sparkline/Verso.Sample.Sparkline.csproj b/samples/layouts/Verso.Sample.Sparkline/Verso.Sample.Sparkline.csproj index 5c13ed98..3121705a 100644 --- a/samples/layouts/Verso.Sample.Sparkline/Verso.Sample.Sparkline.csproj +++ b/samples/layouts/Verso.Sample.Sparkline/Verso.Sample.Sparkline.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/samples/notebooks/sql/sql-getting-started.verso b/samples/notebooks/sql/sql-getting-started.verso index 592b6fd7..92321e5b 100644 --- a/samples/notebooks/sql/sql-getting-started.verso +++ b/samples/notebooks/sql/sql-getting-started.verso @@ -23,7 +23,7 @@ "id": "00000002-0001-0001-0001-000000000030", "type": "code", "language": "csharp", - "source": "#r \u0022nuget: Microsoft.Data.Sqlite, 8.0.8\u0022" + "source": "#r \u0022nuget: Microsoft.Data.Sqlite, 10.0.14\u0022" }, { "id": "00000002-0001-0001-0001-000000000003", diff --git a/samples/notebooks/sql/sql-intellisense-and-schema.verso b/samples/notebooks/sql/sql-intellisense-and-schema.verso index ba90e965..49ed0f5b 100644 --- a/samples/notebooks/sql/sql-intellisense-and-schema.verso +++ b/samples/notebooks/sql/sql-intellisense-and-schema.verso @@ -23,7 +23,7 @@ "id": "10000001-0001-0001-0001-000000000003", "type": "code", "language": "csharp", - "source": "#r \u0022nuget: Microsoft.Data.Sqlite, 8.0.8\u0022" + "source": "#r \u0022nuget: Microsoft.Data.Sqlite, 10.0.14\u0022" }, { "id": "10000001-0001-0001-0001-000000000004", diff --git a/samples/notebooks/sql/sql-scaffold-ef-core.verso b/samples/notebooks/sql/sql-scaffold-ef-core.verso index 70cb9b3f..666ecc4f 100644 --- a/samples/notebooks/sql/sql-scaffold-ef-core.verso +++ b/samples/notebooks/sql/sql-scaffold-ef-core.verso @@ -23,7 +23,7 @@ "id": "00000003-0001-0001-0001-000000000003", "type": "code", "language": "csharp", - "source": "#r \u0022nuget: Microsoft.Data.Sqlite, 8.0.8\u0022\n#r \u0022nuget: Microsoft.EntityFrameworkCore.Sqlite, 8.0.8\u0022" + "source": "#r \u0022nuget: Microsoft.Data.Sqlite, 10.0.14\u0022\n#r \u0022nuget: Microsoft.EntityFrameworkCore.Sqlite, 10.0.14\u0022" }, { "id": "00000003-0001-0001-0001-000000000004", diff --git a/samples/showcase/dag-notebook/README.md b/samples/showcase/dag-notebook/README.md index c7154c10..64178521 100644 --- a/samples/showcase/dag-notebook/README.md +++ b/samples/showcase/dag-notebook/README.md @@ -65,7 +65,7 @@ opens straight into the layout. You can also install it yourself from the **Exte (search `Verso.Showcase`) and switch to **DAG Notebook** from the layout picker. To run against a local build instead, load the freshly built assembly with -`#!extension ./src/Verso.Showcase.DagNotebook/bin/Debug/net8.0/Verso.Showcase.DagNotebook.dll` +`#!extension ./src/Verso.Showcase.DagNotebook/bin/Debug/net10.0/Verso.Showcase.DagNotebook.dll` (the path resolves relative to the notebook's folder), then switch to **DAG Notebook**. The demo notebook seeds a small pricing model: base inputs feed revenue, revenue feeds profit, diff --git a/samples/showcase/dag-notebook/dag-notebook-widget.verso b/samples/showcase/dag-notebook/dag-notebook-widget.verso index c515de94..518a2157 100644 --- a/samples/showcase/dag-notebook/dag-notebook-widget.verso +++ b/samples/showcase/dag-notebook/dag-notebook-widget.verso @@ -17,7 +17,7 @@ { "id": "da610000-0001-4000-8000-000000000001", "type": "markdown", - "source": "# A control at the top of the graph\n\nThis notebook uses the **DAG Notebook** layout. Cells that share variables are linked with chips,\nand running a cell re-runs the cells that depend on it.\n\nA widget is the other way a value changes. A Python cell shares one of its widget's traits as a\nnotebook variable, which puts that variable at the top of the dependency graph with a control\nbehind it rather than a computation. Move the control and the cells below it run, in order,\nwithout anything being clicked.\n\nThe `↻` chip marks the variable that follows the control.\n\n**The re-running is the layout's doing, not the widget's.** `#!bind` shares the value in any\nlayout; it is this one that treats the control as a producer and runs what depends on it. If the\nheader above does not read **DAG Notebook** and the cells carry no chips, the layout is not\nactive and moving the slider will correctly do nothing. This notebook declares\n`Verso.Showcase.DagNotebook` as a required extension, so the host installs it from NuGet and\nopens straight into the layout; if it did not, pick **DAG Notebook** from the layout picker.\nTo run against a local build instead, load the freshly built assembly with a first cell reading\n`#!extension ./src/Verso.Showcase.DagNotebook/bin/Debug/net8.0/Verso.Showcase.DagNotebook.dll`,\nor start the host with `--extensions ./src/Verso.Showcase.DagNotebook/bin/Debug/net8.0`." + "source": "# A control at the top of the graph\n\nThis notebook uses the **DAG Notebook** layout. Cells that share variables are linked with chips,\nand running a cell re-runs the cells that depend on it.\n\nA widget is the other way a value changes. A Python cell shares one of its widget's traits as a\nnotebook variable, which puts that variable at the top of the dependency graph with a control\nbehind it rather than a computation. Move the control and the cells below it run, in order,\nwithout anything being clicked.\n\nThe `↻` chip marks the variable that follows the control.\n\n**The re-running is the layout's doing, not the widget's.** `#!bind` shares the value in any\nlayout; it is this one that treats the control as a producer and runs what depends on it. If the\nheader above does not read **DAG Notebook** and the cells carry no chips, the layout is not\nactive and moving the slider will correctly do nothing. This notebook declares\n`Verso.Showcase.DagNotebook` as a required extension, so the host installs it from NuGet and\nopens straight into the layout; if it did not, pick **DAG Notebook** from the layout picker.\nTo run against a local build instead, load the freshly built assembly with a first cell reading\n`#!extension ./src/Verso.Showcase.DagNotebook/bin/Debug/net10.0/Verso.Showcase.DagNotebook.dll`,\nor start the host with `--extensions ./src/Verso.Showcase.DagNotebook/bin/Debug/net10.0`." }, { "id": "da610000-0002-4000-8000-000000000002", diff --git a/samples/showcase/form-studio/tests/Verso.Showcase.FormStudio.Tests/Verso.Showcase.FormStudio.Tests.csproj b/samples/showcase/form-studio/tests/Verso.Showcase.FormStudio.Tests/Verso.Showcase.FormStudio.Tests.csproj index 4f3111f0..b5f2c011 100644 --- a/samples/showcase/form-studio/tests/Verso.Showcase.FormStudio.Tests/Verso.Showcase.FormStudio.Tests.csproj +++ b/samples/showcase/form-studio/tests/Verso.Showcase.FormStudio.Tests/Verso.Showcase.FormStudio.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 12 enable enable diff --git a/samples/showcase/image-studio/README.md b/samples/showcase/image-studio/README.md index 35b6b132..627e48dd 100644 --- a/samples/showcase/image-studio/README.md +++ b/samples/showcase/image-studio/README.md @@ -45,7 +45,7 @@ into the layout. You can also install it yourself from the **Extensions** pane ( `Verso.Showcase`) and switch to **Image Studio** from the layout picker. To run against a local build instead, load the freshly built assembly with -`#!extension ./src/Verso.Showcase.ImageStudio/bin/Debug/net8.0/Verso.Showcase.ImageStudio.dll` +`#!extension ./src/Verso.Showcase.ImageStudio/bin/Debug/net10.0/Verso.Showcase.ImageStudio.dll` (the path resolves relative to the notebook's folder), then switch to **Image Studio**. You will land on a seeded composition: a sunset gradient, a soft sun, a dot grid, a procedural diff --git a/samples/showcase/image-studio/tests/Verso.Showcase.ImageStudio.Tests/Verso.Showcase.ImageStudio.Tests.csproj b/samples/showcase/image-studio/tests/Verso.Showcase.ImageStudio.Tests/Verso.Showcase.ImageStudio.Tests.csproj index 15e17072..51f80d4a 100644 --- a/samples/showcase/image-studio/tests/Verso.Showcase.ImageStudio.Tests/Verso.Showcase.ImageStudio.Tests.csproj +++ b/samples/showcase/image-studio/tests/Verso.Showcase.ImageStudio.Tests/Verso.Showcase.ImageStudio.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 12 enable enable diff --git a/samples/showcase/slide-studio/README.md b/samples/showcase/slide-studio/README.md index a9e3dad8..fa8580ae 100644 --- a/samples/showcase/slide-studio/README.md +++ b/samples/showcase/slide-studio/README.md @@ -91,7 +91,7 @@ opens straight into the layout. You can also install it yourself from the **Exte (search `Verso.Showcase`) and switch to **Slide Studio** from the layout picker. To run against a local build instead, load the freshly built assembly with -`#!extension ./src/Verso.Showcase.SlideStudio/bin/Debug/net8.0/Verso.Showcase.SlideStudio.dll` +`#!extension ./src/Verso.Showcase.SlideStudio/bin/Debug/net10.0/Verso.Showcase.SlideStudio.dll` (the path resolves relative to the notebook's folder), then switch to **Slide Studio**. The demo notebook is a small quarterly review deck: a title slide, a results table, a chart, a diff --git a/samples/showcase/slide-studio/tests/Verso.Showcase.SlideStudio.Tests/Verso.Showcase.SlideStudio.Tests.csproj b/samples/showcase/slide-studio/tests/Verso.Showcase.SlideStudio.Tests/Verso.Showcase.SlideStudio.Tests.csproj index fe7b9054..806507b3 100644 --- a/samples/showcase/slide-studio/tests/Verso.Showcase.SlideStudio.Tests/Verso.Showcase.SlideStudio.Tests.csproj +++ b/samples/showcase/slide-studio/tests/Verso.Showcase.SlideStudio.Tests/Verso.Showcase.SlideStudio.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 12 enable enable diff --git a/src/Verso.Abstractions/Verso.Abstractions.csproj b/src/Verso.Abstractions/Verso.Abstractions.csproj index 37291698..d37b08d2 100644 --- a/src/Verso.Abstractions/Verso.Abstractions.csproj +++ b/src/Verso.Abstractions/Verso.Abstractions.csproj @@ -11,8 +11,22 @@ Verso.Abstractions Verso Abstractions Pure interfaces and types for the Verso extensible notebook platform. + + true + 1.2.3 + + + + + diff --git a/src/Verso.Blazor.Shared/Verso.Blazor.Shared.csproj b/src/Verso.Blazor.Shared/Verso.Blazor.Shared.csproj index 50649f31..b0ed689f 100644 --- a/src/Verso.Blazor.Shared/Verso.Blazor.Shared.csproj +++ b/src/Verso.Blazor.Shared/Verso.Blazor.Shared.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable @@ -40,7 +40,7 @@ - + diff --git a/src/Verso.Blazor.Wasm/Verso.Blazor.Wasm.csproj b/src/Verso.Blazor.Wasm/Verso.Blazor.Wasm.csproj index f57c0fdc..02372aa2 100644 --- a/src/Verso.Blazor.Wasm/Verso.Blazor.Wasm.csproj +++ b/src/Verso.Blazor.Wasm/Verso.Blazor.Wasm.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable @@ -11,7 +11,7 @@ - + diff --git a/src/Verso.Blazor/Verso.Blazor.csproj b/src/Verso.Blazor/Verso.Blazor.csproj index b8ecdb5e..6846c0f6 100644 --- a/src/Verso.Blazor/Verso.Blazor.csproj +++ b/src/Verso.Blazor/Verso.Blazor.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/src/Verso.Cli/Hosting/BlazorHostBuilder.cs b/src/Verso.Cli/Hosting/BlazorHostBuilder.cs index 30018484..824de531 100644 --- a/src/Verso.Cli/Hosting/BlazorHostBuilder.cs +++ b/src/Verso.Cli/Hosting/BlazorHostBuilder.cs @@ -110,10 +110,10 @@ public static WebApplication Build(ServeOptions options) // Middleware pipeline (matches Verso.Blazor/Program.cs) // // Serve the bundled wwwroot that ships alongside the assembly. This - // covers blazor.web.js (extracted at build time) and, in Production + // covers blazor.web.js (copied there at build time) and, in Production // mode (global tool install), all other static assets. In Development - // mode the manifest handles most assets, but blazor.web.js is not in - // the manifest so we still need this provider. + // mode the build output's wwwroot holds only blazor.web.js and the + // static web assets manifest serves everything else. var wwwrootPath = Path.Combine(blazorAssemblyDir, "wwwroot"); if (Directory.Exists(wwwrootPath)) { diff --git a/src/Verso.Cli/README.md b/src/Verso.Cli/README.md index cb27d8a1..2ec5582d 100644 --- a/src/Verso.Cli/README.md +++ b/src/Verso.Cli/README.md @@ -15,7 +15,7 @@ dotnet tool install Verso.Cli dotnet tool update -g Verso.Cli ``` -Requires .NET 8.0 SDK or later. +Requires the .NET 10 SDK or later. ## Global Options @@ -199,7 +199,7 @@ Displays version, runtime, and extension information. ``` $ verso info Verso CLI 1.0.0 -Runtime: .NET 8.0.11 +Runtime: .NET 10.0.3 Engine: Verso 1.0.0 Extensions: verso.kernel.csharp C# Kernel 1.0.0 diff --git a/src/Verso.Cli/Verso.Cli.csproj b/src/Verso.Cli/Verso.Cli.csproj index f81fb9a1..ca91f85d 100644 --- a/src/Verso.Cli/Verso.Cli.csproj +++ b/src/Verso.Cli/Verso.Cli.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 10 enable enable @@ -24,19 +24,23 @@ - + + + true + + - - <_BlazorWebJsFromNuGet Include="$(NuGetPackageRoot)microsoft.aspnetcore.app.internal.assets/*/_framework/blazor.web.js" /> - - - + Condition="'$(BlazorFrameworkStaticWebAssetRoot)' != '' AND Exists('$(BlazorFrameworkStaticWebAssetRoot)/blazor.web.js')" /> + - + diff --git a/src/Verso.FSharp/Kernel/FSharpKernel.cs b/src/Verso.FSharp/Kernel/FSharpKernel.cs index 4866da98..7ca2d320 100644 --- a/src/Verso.FSharp/Kernel/FSharpKernel.cs +++ b/src/Verso.FSharp/Kernel/FSharpKernel.cs @@ -80,7 +80,7 @@ internal FSharpKernel(FSharpKernelOptions options) new SettingDefinition("langVersion", Strings.Setting_LangVersion_Label, Strings.Setting_LangVersion_Description, SettingType.StringChoice, "preview", "Compiler", - new SettingConstraints(Choices: new[] { "default", "latest", "latestmajor", "preview", "5.0", "6.0", "7.0", "8.0", "9.0" })), + new SettingConstraints(Choices: new[] { "default", "latest", "latestmajor", "preview", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0" })), new SettingDefinition("publishPrivateBindings", Strings.Setting_PublishPrivateBindings_Label, Strings.Setting_PublishPrivateBindings_Description, SettingType.Boolean, false, "Variables"), diff --git a/src/Verso.Host/Verso.Host.csproj b/src/Verso.Host/Verso.Host.csproj index ce81df1a..0a7c13b2 100644 --- a/src/Verso.Host/Verso.Host.csproj +++ b/src/Verso.Host/Verso.Host.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 LatestMajor 10 enable diff --git a/src/Verso.PowerShell/Verso.PowerShell.csproj b/src/Verso.PowerShell/Verso.PowerShell.csproj index a796e6ed..54d4edf9 100644 --- a/src/Verso.PowerShell/Verso.PowerShell.csproj +++ b/src/Verso.PowerShell/Verso.PowerShell.csproj @@ -37,7 +37,7 @@ - + diff --git a/src/Verso/Verso.csproj b/src/Verso/Verso.csproj index 747dd092..4ef5af6a 100644 --- a/src/Verso/Verso.csproj +++ b/src/Verso/Verso.csproj @@ -47,10 +47,10 @@ - - - - + + + + diff --git a/templates/Verso.Extension.Template/MyExtension.Tests/MyExtension.Tests.csproj b/templates/Verso.Extension.Template/MyExtension.Tests/MyExtension.Tests.csproj index af583262..028b0a8d 100644 --- a/templates/Verso.Extension.Template/MyExtension.Tests/MyExtension.Tests.csproj +++ b/templates/Verso.Extension.Template/MyExtension.Tests/MyExtension.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 12 enable enable diff --git a/templates/Verso.Extension.Template/MyExtension.csproj b/templates/Verso.Extension.Template/MyExtension.csproj index b439c180..e8186a49 100644 --- a/templates/Verso.Extension.Template/MyExtension.csproj +++ b/templates/Verso.Extension.Template/MyExtension.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 12 enable enable diff --git a/templates/Verso.Templates/Verso.Templates.csproj b/templates/Verso.Templates/Verso.Templates.csproj index 97669b4f..fcc4124d 100644 --- a/templates/Verso.Templates/Verso.Templates.csproj +++ b/templates/Verso.Templates/Verso.Templates.csproj @@ -5,7 +5,7 @@ Verso.Templates Verso Templates Project templates for building Verso extensions. - net8.0 + net10.0 true false content diff --git a/tests/Verso.Abstractions.Tests/Verso.Abstractions.Tests.csproj b/tests/Verso.Abstractions.Tests/Verso.Abstractions.Tests.csproj index 3ae7a80a..94c2f9de 100644 --- a/tests/Verso.Abstractions.Tests/Verso.Abstractions.Tests.csproj +++ b/tests/Verso.Abstractions.Tests/Verso.Abstractions.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.Ado.Tests/Verso.Ado.Tests.csproj b/tests/Verso.Ado.Tests/Verso.Ado.Tests.csproj index 2435fdf2..8124db95 100644 --- a/tests/Verso.Ado.Tests/Verso.Ado.Tests.csproj +++ b/tests/Verso.Ado.Tests/Verso.Ado.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable @@ -13,8 +13,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Verso.Blazor.Shared.Tests/Verso.Blazor.Shared.Tests.csproj b/tests/Verso.Blazor.Shared.Tests/Verso.Blazor.Shared.Tests.csproj index 2b8b82b1..ec1e41c0 100644 --- a/tests/Verso.Blazor.Shared.Tests/Verso.Blazor.Shared.Tests.csproj +++ b/tests/Verso.Blazor.Shared.Tests/Verso.Blazor.Shared.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable @@ -13,9 +13,9 @@ - + - + diff --git a/tests/Verso.Cli.Tests/Verso.Cli.Tests.csproj b/tests/Verso.Cli.Tests/Verso.Cli.Tests.csproj index 49a5b189..e13f9548 100644 --- a/tests/Verso.Cli.Tests/Verso.Cli.Tests.csproj +++ b/tests/Verso.Cli.Tests/Verso.Cli.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.DataFrame.Tests/Verso.DataFrame.Tests.csproj b/tests/Verso.DataFrame.Tests/Verso.DataFrame.Tests.csproj index fb4dcd45..a8353a1a 100644 --- a/tests/Verso.DataFrame.Tests/Verso.DataFrame.Tests.csproj +++ b/tests/Verso.DataFrame.Tests/Verso.DataFrame.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.E2E.Tests/Verso.E2E.Tests.csproj b/tests/Verso.E2E.Tests/Verso.E2E.Tests.csproj index 2bc857f5..af3cf5bf 100644 --- a/tests/Verso.E2E.Tests/Verso.E2E.Tests.csproj +++ b/tests/Verso.E2E.Tests/Verso.E2E.Tests.csproj @@ -6,7 +6,7 @@ --> - net8.0 + net10.0 latest enable enable @@ -39,7 +39,7 @@ <_Parameter1>VersoCliPath - <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../../src/Verso.Cli/bin/$(Configuration)/net8.0/Verso.Cli.dll')) + <_Parameter2>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../../src/Verso.Cli/bin/$(Configuration)/$(TargetFramework)/Verso.Cli.dll')) diff --git a/tests/Verso.FSharp.Tests/Kernel/SettingsTests.cs b/tests/Verso.FSharp.Tests/Kernel/SettingsTests.cs index 8eaeaef4..dcb92f30 100644 --- a/tests/Verso.FSharp.Tests/Kernel/SettingsTests.cs +++ b/tests/Verso.FSharp.Tests/Kernel/SettingsTests.cs @@ -66,6 +66,7 @@ public void SettingDefinitions_LangVersion_HasChoiceConstraint() Assert.IsNotNull(def.Constraints?.Choices); CollectionAssert.Contains(def.Constraints!.Choices!.ToList(), "preview"); CollectionAssert.Contains(def.Constraints.Choices!.ToList(), "default"); + CollectionAssert.Contains(def.Constraints.Choices!.ToList(), "10.0"); } [TestMethod] diff --git a/tests/Verso.FSharp.Tests/Verso.FSharp.Tests.csproj b/tests/Verso.FSharp.Tests/Verso.FSharp.Tests.csproj index 60c29003..1dccbd1b 100644 --- a/tests/Verso.FSharp.Tests/Verso.FSharp.Tests.csproj +++ b/tests/Verso.FSharp.Tests/Verso.FSharp.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.Host.Tests/Verso.Host.Tests.csproj b/tests/Verso.Host.Tests/Verso.Host.Tests.csproj index d7603d1f..a61ec144 100644 --- a/tests/Verso.Host.Tests/Verso.Host.Tests.csproj +++ b/tests/Verso.Host.Tests/Verso.Host.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.Http.Tests/Verso.Http.Tests.csproj b/tests/Verso.Http.Tests/Verso.Http.Tests.csproj index dab12bfe..8df71637 100644 --- a/tests/Verso.Http.Tests/Verso.Http.Tests.csproj +++ b/tests/Verso.Http.Tests/Verso.Http.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.JavaScript.Tests/Verso.JavaScript.Tests.csproj b/tests/Verso.JavaScript.Tests/Verso.JavaScript.Tests.csproj index 25e07ba0..1ca64e6b 100644 --- a/tests/Verso.JavaScript.Tests/Verso.JavaScript.Tests.csproj +++ b/tests/Verso.JavaScript.Tests/Verso.JavaScript.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.PowerShell.Tests/Verso.PowerShell.Tests.csproj b/tests/Verso.PowerShell.Tests/Verso.PowerShell.Tests.csproj index a71ed707..fcd73065 100644 --- a/tests/Verso.PowerShell.Tests/Verso.PowerShell.Tests.csproj +++ b/tests/Verso.PowerShell.Tests/Verso.PowerShell.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.Python.Tests/Verso.Python.Tests.csproj b/tests/Verso.Python.Tests/Verso.Python.Tests.csproj index 8e80bd20..63ac9cc0 100644 --- a/tests/Verso.Python.Tests/Verso.Python.Tests.csproj +++ b/tests/Verso.Python.Tests/Verso.Python.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 10 enable enable diff --git a/tests/Verso.Tests/Verso.Tests.csproj b/tests/Verso.Tests/Verso.Tests.csproj index a3d76099..d84ea353 100644 --- a/tests/Verso.Tests/Verso.Tests.csproj +++ b/tests/Verso.Tests/Verso.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 11 enable enable diff --git a/vscode/README.md b/vscode/README.md index 613c6fcb..cf6b5ac1 100644 --- a/vscode/README.md +++ b/vscode/README.md @@ -27,7 +27,7 @@ C#, F#, SQL, HTTP, Markdown, HTML, Mermaid, and JavaScript work immediately. Pyt | Requirement | Needed for | Notes | |-------------|-----------|-------| -| **.NET runtime 8.0 or later** | Everything | .NET 8, 9, and 10 are all supported. If no compatible runtime is found, Verso offers to install one when you open a notebook, using the .NET Install Tool. To use a specific installation, set `verso.dotnetPath`. | +| **.NET runtime 10.0 or later** | Everything | .NET 10 and later are supported. If no compatible runtime is found, Verso offers to install one when you open a notebook, using the .NET Install Tool. To use a specific installation, set `verso.dotnetPath`. | | **Python 3.8 or newer** | Python cells | Including 3.13 and 3.14. Cells run in that interpreter as a separate process, so an active virtual environment or conda environment is picked up automatically and its packages are simply there. Run `#!python --list` in a cell to see what was found. | | **Node.js 18 or later** | TypeScript cells, npm packages, full Node APIs | Optional. Without it, JavaScript runs on the bundled Jint interpreter, a pure .NET ES2024 engine, and TypeScript is unavailable. Auto-detected on PATH and at Homebrew, nvm, Volta, and fnm locations. | | **A ligature-capable font** | Font ligatures | Optional. Verso respects `editor.fontLigatures` and prepends Cascadia Code and Fira Code to your font stack, so installing [either](https://github.com/microsoft/cascadia-code) [font](https://github.com/tonsky/FiraCode) is all that is needed. | diff --git a/vscode/src/extension.ts b/vscode/src/extension.ts index c4393220..d098bff9 100644 --- a/vscode/src/extension.ts +++ b/vscode/src/extension.ts @@ -206,9 +206,9 @@ export function resolveHostPath( for (const cfg of configs) { const candidates = [ // Direct workspace is the Verso project - path.join(folder.uri.fsPath, "src", "Verso.Host", "bin", cfg, "net8.0", "Verso.Host.dll"), + path.join(folder.uri.fsPath, "src", "Verso.Host", "bin", cfg, "net10.0", "Verso.Host.dll"), // Workspace is a parent - path.join(folder.uri.fsPath, "tools", "Verso", "src", "Verso.Host", "bin", cfg, "net8.0", "Verso.Host.dll"), + path.join(folder.uri.fsPath, "tools", "Verso", "src", "Verso.Host", "bin", cfg, "net10.0", "Verso.Host.dll"), ]; for (const candidate of candidates) { if (existsSync(candidate)) { @@ -220,7 +220,7 @@ export function resolveHostPath( // Fallback: relative to extension path (works in dev host / local install) for (const cfg of configs) { - const extensionRelative = path.join(context.extensionPath, "..", "src", "Verso.Host", "bin", cfg, "net8.0", "Verso.Host.dll"); + const extensionRelative = path.join(context.extensionPath, "..", "src", "Verso.Host", "bin", cfg, "net10.0", "Verso.Host.dll"); if (existsSync(extensionRelative)) { return extensionRelative; } diff --git a/vscode/src/host/dotnetRuntime.ts b/vscode/src/host/dotnetRuntime.ts index 0ca13eae..2bc327e8 100644 --- a/vscode/src/host/dotnetRuntime.ts +++ b/vscode/src/host/dotnetRuntime.ts @@ -1,5 +1,6 @@ import * as vscode from "vscode"; import * as fs from "fs"; +import * as path from "path"; import { log } from "../log"; import { HostStartError } from "./hostProcess"; @@ -33,7 +34,7 @@ const SETUP_DOCS_URL = // The lowest runtime the host is known to support; used only when the host's // runtimeconfig.json cannot be read. The real requirement is read dynamically // so it tracks the host's target framework across upgrades without edits here. -const DEFAULT_RUNTIME_VERSION = "8.0"; +const DEFAULT_RUNTIME_VERSION = "10.0"; // A missing runtime otherwise prompts once per notebook opened, and VS Code // restores several notebook tabs at once on startup. Debounce so a burst of @@ -97,12 +98,24 @@ async function resolveDotnetCommandUncached( } // 2. A runtime we previously acquired for the user lives at a private path off - // PATH; reuse it while it still exists. (Self-heals if it was removed: we - // fall through and the next failed start re-offers acquisition.) + // PATH; reuse it while it still exists and is new enough for this host. + // (Self-heals if it was removed: we fall through and the next failed start + // re-offers acquisition.) const acquired = context.globalState.get(ACQUIRED_DOTNET_KEY); if (acquired && fs.existsSync(acquired)) { - log.info(`Using previously acquired .NET runtime: ${acquired}`); - return acquired; + const required = getRequiredRuntimeVersion(hostDllPath); + if (hasRuntimeAtLeast(acquired, required)) { + log.info(`Using previously acquired .NET runtime: ${acquired}`); + return acquired; + } + // Acquired for an older host (for example .NET 8 before the host moved to + // .NET 10). Using it would fail with "framework not found" even when a + // newer .NET is on PATH, so forget it and let PATH decide. + log.info( + `Previously acquired .NET runtime at ${acquired} has no ${required} or later ` + + `runtime; ignoring it.` + ); + await context.globalState.update(ACQUIRED_DOTNET_KEY, undefined); } // 3. Fall back to a system 'dotnet'. If absent, the host start surfaces the @@ -111,7 +124,25 @@ async function resolveDotnetCommandUncached( } /** - * Reads the required shared-runtime version (major.minor, e.g. "8.0") from the + * Reports whether the .NET installation that owns `dotnetPath` has a shared + * runtime whose major version is at least the major of `requiredVersion`. The + * host rolls forward to newer majors, so any later major also qualifies. + * Exported for tests. + */ +export function hasRuntimeAtLeast(dotnetPath: string, requiredVersion: string): boolean { + const requiredMajor = parseInt(requiredVersion, 10); + const sharedDir = path.join(path.dirname(dotnetPath), "shared", "Microsoft.NETCore.App"); + try { + return fs + .readdirSync(sharedDir) + .some((name) => parseInt(name, 10) >= requiredMajor); + } catch { + return false; + } +} + +/** + * Reads the required shared-runtime version (major.minor, e.g. "10.0") from the * host's runtimeconfig.json so acquisition and messaging track the host's target * framework automatically. Falls back to {@link DEFAULT_RUNTIME_VERSION} if * unreadable. diff --git a/vscode/test/suite/dotnetRuntime.test.ts b/vscode/test/suite/dotnetRuntime.test.ts new file mode 100644 index 00000000..59bd5c5f --- /dev/null +++ b/vscode/test/suite/dotnetRuntime.test.ts @@ -0,0 +1,94 @@ +import * as assert from "assert"; +import * as fs from "fs"; +import * as os from "os"; +import * as path from "path"; +import * as vscode from "vscode"; +import { hasRuntimeAtLeast, resolveDotnetCommand } from "../../src/host/dotnetRuntime"; + +const ACQUIRED_DOTNET_KEY = "verso.acquiredDotnetPath"; + +suite("dotnetRuntime: previously acquired runtime", () => { + let root: string; + + setup(() => { + root = fs.mkdtempSync(path.join(os.tmpdir(), "verso-dotnet-")); + }); + + teardown(() => { + fs.rmSync(root, { recursive: true, force: true }); + }); + + // Lays out a private .NET install the way the .NET Install Tool does: the + // dotnet executable next to shared/Microsoft.NETCore.App/ folders. + function fakeInstall(name: string, runtimeVersions: string[]): string { + const dir = path.join(root, name); + for (const version of runtimeVersions) { + fs.mkdirSync(path.join(dir, "shared", "Microsoft.NETCore.App", version), { recursive: true }); + } + fs.mkdirSync(dir, { recursive: true }); + const dotnet = path.join(dir, process.platform === "win32" ? "dotnet.exe" : "dotnet"); + fs.writeFileSync(dotnet, ""); + return dotnet; + } + + function fakeHost(name: string, frameworkVersion: string): string { + const dir = path.join(root, name); + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync( + path.join(dir, "Verso.Host.runtimeconfig.json"), + JSON.stringify({ + runtimeOptions: { framework: { name: "Microsoft.NETCore.App", version: frameworkVersion } }, + }) + ); + return path.join(dir, "Verso.Host.dll"); + } + + function fakeContext(acquired: string | undefined): vscode.ExtensionContext { + const state = new Map(); + if (acquired) { + state.set(ACQUIRED_DOTNET_KEY, acquired); + } + return { + globalState: { + get: (key: string) => state.get(key), + update: async (key: string, value: unknown) => { + if (value === undefined) { + state.delete(key); + } else { + state.set(key, value); + } + }, + }, + } as unknown as vscode.ExtensionContext; + } + + test("hasRuntimeAtLeast accepts the same or a later major", () => { + assert.strictEqual(hasRuntimeAtLeast(fakeInstall("ten", ["10.0.3"]), "10.0"), true); + assert.strictEqual(hasRuntimeAtLeast(fakeInstall("eleven", ["11.0.0"]), "10.0"), true); + }); + + test("hasRuntimeAtLeast rejects an older major or a missing shared folder", () => { + assert.strictEqual(hasRuntimeAtLeast(fakeInstall("eight", ["8.0.16"]), "10.0"), false); + assert.strictEqual(hasRuntimeAtLeast(fakeInstall("empty", []), "10.0"), false); + }); + + test("an acquired runtime that is too old is forgotten in favor of PATH", async () => { + const dotnet = fakeInstall("old", ["8.0.16"]); + const context = fakeContext(dotnet); + + const command = await resolveDotnetCommand(context, fakeHost("host-old", "10.0.0")); + + assert.strictEqual(command, "dotnet"); + assert.strictEqual(context.globalState.get(ACQUIRED_DOTNET_KEY), undefined); + }); + + test("an acquired runtime that is new enough is still used", async () => { + const dotnet = fakeInstall("new", ["8.0.16", "10.0.3"]); + const context = fakeContext(dotnet); + + const command = await resolveDotnetCommand(context, fakeHost("host-new", "10.0.0")); + + assert.strictEqual(command, dotnet); + assert.strictEqual(context.globalState.get(ACQUIRED_DOTNET_KEY), dotnet); + }); +});