mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-03 07:27:21 +00:00
Embedded Blazor's script into the app, since .NET 10 moved it out of the framework
This commit is contained in:
3 files changed
+92
-2
No files matched your search
@@ -45,6 +45,13 @@
|
|||||||
-->
|
-->
|
||||||
<NoWarn>IL2026, CS8974</NoWarn>
|
<NoWarn>IL2026, CS8974</NoWarn>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Since .NET 10, the scripts of Blazor come from a package, which the release embeds: see the
|
||||||
|
EmbedBlazorScript target. The SDK adds that package by itself when it spots Razor files; we
|
||||||
|
ask for it here, so that the release does not hinge on that guess.
|
||||||
|
-->
|
||||||
|
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="..\Trimming.props" />
|
<Import Project="..\Trimming.props" />
|
||||||
@@ -207,4 +214,28 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
`_framework/blazor.web.js` makes the UI interactive, and App.razor loads it. Up to .NET 9, the shared
|
||||||
|
framework served it. Since .NET 10, it is a static web asset of the package Microsoft.AspNetCore.App.Internal.Assets,
|
||||||
|
which names its folder in BlazorFrameworkStaticWebAssetRoot. Like the scoped CSS bundle above, the release
|
||||||
|
would therefore lack it: the window would show the app, but nothing in it would react. Hence: embed it
|
||||||
|
before the manifest is written.
|
||||||
|
-->
|
||||||
|
<Target Name="EmbedBlazorScript" BeforeTargets="_CalculateEmbeddedFilesManifestInputs">
|
||||||
|
<PropertyGroup>
|
||||||
|
<BlazorScriptToEmbed>$(BlazorFrameworkStaticWebAssetRoot)\blazor.web.js</BlazorScriptToEmbed>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Fail loudly instead of shipping a release without the script: a missing file here means the
|
||||||
|
package moved it, or the SDK no longer adds the package.
|
||||||
|
-->
|
||||||
|
<Error Condition="'$(BlazorFrameworkStaticWebAssetRoot)' == '' Or !Exists('$(BlazorScriptToEmbed)')"
|
||||||
|
Text="The script of Blazor was not found at '$(BlazorScriptToEmbed)'. Without it, the release starts with a window which does not react at all. Check where .NET keeps blazor.web.js and adjust the EmbedBlazorScript target." />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="$(BlazorScriptToEmbed)" Link="wwwroot\_framework\blazor.web.js" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
using AIStudio.Tools;
|
using AIStudio.Tools;
|
||||||
|
|
||||||
@@ -6,12 +9,15 @@ using Changelog = AIStudio.Components.Changelog;
|
|||||||
namespace AIStudio.Tests.Tools.AppAccess;
|
namespace AIStudio.Tests.Tools.AppAccess;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks that the app reads the files below wwwroot which it shows itself.
|
/// Checks that the app reads the files below wwwroot which it shows itself, and that the release
|
||||||
|
/// can serve every file which the page of the app loads.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The changelogs and the ERI specifications come from the files embedded into the app, not from a
|
/// The changelogs and the ERI specifications come from the files embedded into the app, not from a
|
||||||
/// request to its own server. A file which is missing there would leave the changelog or the ERI
|
/// request to its own server. A file which is missing there would leave the changelog or the ERI
|
||||||
/// assistant empty without any error.
|
/// assistant empty without any error. The release serves its static files from the same embedded
|
||||||
|
/// files; one which is missing there leaves the window without styles, or without any interaction
|
||||||
|
/// at all, while a debug build keeps working.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public sealed class WebRootFilesTests
|
public sealed class WebRootFilesTests
|
||||||
@@ -20,6 +26,30 @@ public sealed class WebRootFilesTests
|
|||||||
|
|
||||||
private static IEnumerable<ERIVersion> SpecificationVersions() => Enum.GetValues<ERIVersion>().Where(version => version.WasSpecificationSelected());
|
private static IEnumerable<ERIVersion> SpecificationVersions() => Enum.GetValues<ERIVersion>().Where(version => version.WasSpecificationSelected());
|
||||||
|
|
||||||
|
private static string ReadAppPageSource([CallerFilePath] string sourceFilePath = "") => File.ReadAllText(Path.Combine(Path.GetDirectoryName(sourceFilePath)!, "..", "..", "..", "MindWork AI Studio", "App.razor"));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the scripts and style sheets which App.razor loads from the app itself, so that a new one
|
||||||
|
/// is checked without anybody having to add it to a test.
|
||||||
|
/// </summary>
|
||||||
|
private static IEnumerable<string> FilesOfTheAppPage() => Regex.Matches(ReadAppPageSource(), @"<(?:script|link)\b[^>]*\b(?:src|href)=""(?<path>[^""]+)""")
|
||||||
|
.Select(match => match.Groups["path"].Value)
|
||||||
|
.Where(path => !path.Contains("//", StringComparison.Ordinal));
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TheAppPageLoadsFilesOfTheApp()
|
||||||
|
{
|
||||||
|
Assert.That(FilesOfTheAppPage(), Does.Contain("_framework/blazor.web.js").And.Contain("app.css"), "The test no longer finds the scripts and style sheets in App.razor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCaseSource(nameof(FilesOfTheAppPage))]
|
||||||
|
public void EveryFileOfTheAppPageIsEmbedded(string path)
|
||||||
|
{
|
||||||
|
var file = new WebRootFiles().FileProvider.GetFileInfo(path);
|
||||||
|
Assert.That(file.Exists, Is.True, $"The release would not serve '{path}', since it is not among the embedded files.");
|
||||||
|
Assert.That(file.Length, Is.GreaterThan(0), $"The release would serve '{path}' as an empty file.");
|
||||||
|
}
|
||||||
|
|
||||||
[TestCaseSource(nameof(ChangelogFiles))]
|
[TestCaseSource(nameof(ChangelogFiles))]
|
||||||
public async Task EveryChangelogCanBeRead(string filename)
|
public async Task EveryChangelogCanBeRead(string filename)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
|
namespace AIStudio.Tests.Tools.PluginSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks that the release finds the plugins which ship with AI Studio, such as the language plugins.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A debug build reads these plugins from the source tree, while the release copies them out of the
|
||||||
|
/// files embedded into the app. A plugin which is missing there would leave the release without its
|
||||||
|
/// language, and only an error in the log would tell.
|
||||||
|
/// </remarks>
|
||||||
|
[TestFixture]
|
||||||
|
public sealed class InternalPluginResourcesTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void EveryInternalPluginIsEmbedded([Values] InternalPlugin plugin)
|
||||||
|
{
|
||||||
|
var embeddedPlugins = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "Plugins");
|
||||||
|
var mainFile = embeddedPlugins.GetFileInfo($"{plugin.MetaData().ResourcePath}/plugin.lua");
|
||||||
|
|
||||||
|
Assert.That(mainFile.Exists, Is.True, $"The release would not find the plugin {plugin}, since it is not among the embedded files.");
|
||||||
|
Assert.That(mainFile.Length, Is.GreaterThan(0), $"The release would find the plugin {plugin} empty.");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user