Prepared tailwind system for plugin builds and exports via nuget. Removed obsolete old css bundling. Added helper scripts for building. Rewritten build scripts
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -429,3 +429,7 @@ core.min.css
|
|||||||
# Build script for nuget packages
|
# Build script for nuget packages
|
||||||
finalPackages/
|
finalPackages/
|
||||||
nupkgs/
|
nupkgs/
|
||||||
|
|
||||||
|
# Scripts
|
||||||
|
**/bin/**
|
||||||
|
**/obj/**
|
||||||
@@ -10,6 +10,5 @@ public class PluginManifest
|
|||||||
public string[] Scripts { get; set; } = [];
|
public string[] Scripts { get; set; } = [];
|
||||||
public string[] Styles { get; set; } = [];
|
public string[] Styles { get; set; } = [];
|
||||||
|
|
||||||
public string[] BundledStyles { get; set; } = [];
|
|
||||||
public Dictionary<string, string[]> Assemblies { get; set; } = new();
|
public Dictionary<string, string[]> Assemblies { get; set; } = new();
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\.dockerignore">
|
<Content Include="..\.dockerignore">
|
||||||
<Link>.dockerignore</Link>
|
<Link>.dockerignore</Link>
|
||||||
|
<Pack>false</Pack>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
using ExCSS;
|
|
||||||
using Microsoft.Extensions.FileProviders;
|
|
||||||
using MoonCore.Helpers;
|
|
||||||
|
|
||||||
namespace Moonlight.ApiServer.Services;
|
|
||||||
|
|
||||||
public class BundleGenerationService : IHostedService
|
|
||||||
{
|
|
||||||
private readonly ILogger<BundleGenerationService> Logger;
|
|
||||||
private readonly IWebHostEnvironment HostEnvironment;
|
|
||||||
private readonly PluginService PluginService;
|
|
||||||
private readonly BundleService BundleService;
|
|
||||||
|
|
||||||
public BundleGenerationService(
|
|
||||||
ILogger<BundleGenerationService> logger,
|
|
||||||
IWebHostEnvironment hostEnvironment,
|
|
||||||
BundleService bundleService,
|
|
||||||
PluginService pluginService
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Logger = logger;
|
|
||||||
HostEnvironment = hostEnvironment;
|
|
||||||
BundleService = bundleService;
|
|
||||||
PluginService = pluginService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Bundle(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
Logger.LogInformation("Bundling css files...");
|
|
||||||
|
|
||||||
// Search the physical path for the defined files
|
|
||||||
var physicalCssFiles = new List<string>();
|
|
||||||
|
|
||||||
foreach (var cssFile in BundleService.GetCssFiles())
|
|
||||||
{
|
|
||||||
var fileInfo = HostEnvironment.WebRootFileProvider.GetFileInfo(cssFile);
|
|
||||||
|
|
||||||
if (fileInfo is NotFoundFileInfo || fileInfo.PhysicalPath == null)
|
|
||||||
{
|
|
||||||
fileInfo = PluginService.WwwRootFileProvider.GetFileInfo(cssFile);
|
|
||||||
|
|
||||||
if (fileInfo is NotFoundFileInfo || fileInfo.PhysicalPath == null)
|
|
||||||
{
|
|
||||||
Logger.LogWarning(
|
|
||||||
"Unable to find physical path for the requested css file '{file}'. Make sure its inside a wwwroot folder",
|
|
||||||
cssFile
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogTrace("Discovered css file '{path}' at '{physicalPath}'", cssFile, fileInfo.PhysicalPath);
|
|
||||||
|
|
||||||
physicalCssFiles.Add(fileInfo.PhysicalPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (physicalCssFiles.Count == 0)
|
|
||||||
Logger.LogWarning(
|
|
||||||
"No physical paths to css files loaded. The generated bundle will be empty. Unless this is intended by you this is a bug");
|
|
||||||
|
|
||||||
// TODO: Implement cache
|
|
||||||
|
|
||||||
// TODO: File system watcher for development
|
|
||||||
|
|
||||||
var bundleContent = await CreateCssBundle(physicalCssFiles);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(PathBuilder.Dir("storage", "tmp"));
|
|
||||||
|
|
||||||
await File.WriteAllTextAsync(PathBuilder.File("storage", "tmp", "bundle.css"), bundleContent,
|
|
||||||
cancellationToken);
|
|
||||||
|
|
||||||
Logger.LogInformation("Successfully built css bundle");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string> CreateCssBundle(List<string> physicalPaths)
|
|
||||||
{
|
|
||||||
if (physicalPaths.Count == 0) // No stylesheets defined => nothing to process
|
|
||||||
return "";
|
|
||||||
|
|
||||||
if (physicalPaths.Count == 1) // Only one stylesheet => nothing to process
|
|
||||||
return await File.ReadAllTextAsync(physicalPaths[0]);
|
|
||||||
|
|
||||||
// Simple bundler just to test
|
|
||||||
var result = "";
|
|
||||||
|
|
||||||
foreach (var path in physicalPaths)
|
|
||||||
{
|
|
||||||
result += await File.ReadAllTextAsync(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Create bundle by stripping out double declared classes and combining all css files into one bundle
|
|
||||||
var parser = new StylesheetParser();
|
|
||||||
string? content = null;
|
|
||||||
Stylesheet? mainStylesheet = null;
|
|
||||||
var additionalStyleSheets = new List<Stylesheet>();
|
|
||||||
|
|
||||||
foreach (var physicalPath in physicalPaths)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var fileContent = await File.ReadAllTextAsync(physicalPath);
|
|
||||||
var stylesheet = await parser.ParseAsync(fileContent);
|
|
||||||
|
|
||||||
// Check if it's the first stylesheet we are loading
|
|
||||||
if (mainStylesheet == null || content == null)
|
|
||||||
{
|
|
||||||
// Delegate the first stylesheet to be the main one
|
|
||||||
content = fileContent + "\n";
|
|
||||||
mainStylesheet = stylesheet;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
additionalStyleSheets.Add(stylesheet); // All other stylesheets are to be processed
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.LogError("An error occured while parsing css file: {e}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle an empty main stylesheet delegation
|
|
||||||
if (mainStylesheet == null || content == null)
|
|
||||||
{
|
|
||||||
Logger.LogError("An unable to delegate main stylesheet. Did every load attempt of an stylesheet fail?");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process stylesheets against the main one
|
|
||||||
foreach (var stylesheet in additionalStyleSheets)
|
|
||||||
{
|
|
||||||
// Style
|
|
||||||
foreach (var styleRule in stylesheet.StyleRules)
|
|
||||||
{
|
|
||||||
if (mainStylesheet.StyleRules.Any(x => x.Selector.Text == styleRule.Selector.Text))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
content += styleRule.StylesheetText.Text + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Container
|
|
||||||
foreach (var containerRule in stylesheet.ContainerRules)
|
|
||||||
{
|
|
||||||
if (mainStylesheet.ContainerRules.Any(x => x.ConditionText == containerRule.ConditionText))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
content += containerRule.StylesheetText.Text + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import Rule
|
|
||||||
foreach (var importRule in stylesheet.ImportRules)
|
|
||||||
{
|
|
||||||
if (mainStylesheet.ImportRules.Any(x => x.Text == importRule.Text))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
content = importRule.StylesheetText.Text + "\n" + content;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Media Rules
|
|
||||||
foreach (var mediaRule in stylesheet.MediaRules)
|
|
||||||
content += mediaRule.StylesheetText.Text + "\n";
|
|
||||||
|
|
||||||
// Page Rules
|
|
||||||
foreach (var pageRule in stylesheet.PageRules)
|
|
||||||
{
|
|
||||||
if (mainStylesheet.PageRules.Any(x => x.SelectorText == pageRule.SelectorText))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
content += pageRule.StylesheetText.Text + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
|
||||||
=> Bundle(cancellationToken);
|
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken)
|
|
||||||
=> Task.CompletedTask;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
namespace Moonlight.ApiServer.Services;
|
|
||||||
|
|
||||||
public class BundleService
|
|
||||||
{
|
|
||||||
private readonly List<string> CssFiles = new();
|
|
||||||
|
|
||||||
public void BundleCss(string path)
|
|
||||||
=> CssFiles.Add(path);
|
|
||||||
|
|
||||||
public void BundleCssRange(string[] paths)
|
|
||||||
=> CssFiles.AddRange(paths);
|
|
||||||
|
|
||||||
public IEnumerable<string> GetCssFiles() => CssFiles;
|
|
||||||
}
|
|
||||||
@@ -54,9 +54,6 @@ public class Startup
|
|||||||
private PluginService PluginService;
|
private PluginService PluginService;
|
||||||
private AssemblyLoadContext PluginLoadContext;
|
private AssemblyLoadContext PluginLoadContext;
|
||||||
|
|
||||||
// Asset bundling
|
|
||||||
private BundleService BundleService = new();
|
|
||||||
|
|
||||||
private IPluginStartup[] PluginStartups;
|
private IPluginStartup[] PluginStartups;
|
||||||
|
|
||||||
public async Task Run(string[] args, Assembly[]? additionalAssemblies = null,
|
public async Task Run(string[] args, Assembly[]? additionalAssemblies = null,
|
||||||
@@ -71,7 +68,6 @@ public class Startup
|
|||||||
await CreateStorage();
|
await CreateStorage();
|
||||||
await SetupAppConfiguration();
|
await SetupAppConfiguration();
|
||||||
await SetupLogging();
|
await SetupLogging();
|
||||||
await SetupBundling();
|
|
||||||
await LoadPlugins();
|
await LoadPlugins();
|
||||||
await InitializePlugins();
|
await InitializePlugins();
|
||||||
|
|
||||||
@@ -132,15 +128,6 @@ public class Startup
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task SetupBundling()
|
|
||||||
{
|
|
||||||
BundleService = new();
|
|
||||||
|
|
||||||
BundleService.BundleCss("css/core.min.css");
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Base
|
#region Base
|
||||||
|
|
||||||
private Task RegisterBase()
|
private Task RegisterBase()
|
||||||
@@ -257,13 +244,6 @@ public class Startup
|
|||||||
// Configure base services for initialisation
|
// Configure base services for initialisation
|
||||||
startupSc.AddSingleton(Configuration);
|
startupSc.AddSingleton(Configuration);
|
||||||
|
|
||||||
// Add bundle service so plugins can do additional bundling if required
|
|
||||||
startupSc.AddSingleton(BundleService);
|
|
||||||
|
|
||||||
// Auto add all files specified in the bundledStyles section to the bundle job
|
|
||||||
foreach (var plugin in PluginService.LoadedPlugins.Keys)
|
|
||||||
BundleService.BundleCssRange(plugin.BundledStyles);
|
|
||||||
|
|
||||||
startupSc.AddLogging(builder =>
|
startupSc.AddLogging(builder =>
|
||||||
{
|
{
|
||||||
builder.ClearProviders();
|
builder.ClearProviders();
|
||||||
@@ -308,10 +288,6 @@ public class Startup
|
|||||||
|
|
||||||
private Task RegisterPluginAssets()
|
private Task RegisterPluginAssets()
|
||||||
{
|
{
|
||||||
WebApplicationBuilder.Services.AddHostedService(sp => sp.GetRequiredService<BundleGenerationService>());
|
|
||||||
WebApplicationBuilder.Services.AddSingleton<BundleGenerationService>();
|
|
||||||
WebApplicationBuilder.Services.AddSingleton(BundleService);
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<DefaultItemExcludes>
|
<DefaultItemExcludes>
|
||||||
**\bin\**;**\obj\**;**\node_modules\**;**\Styles\*.json
|
**\bin\**;**\obj\**;**\node_modules\**;**\Styles\*.json
|
||||||
</DefaultItemExcludes>
|
</DefaultItemExcludes>
|
||||||
|
<StaticWebAssetsEnabled>True</StaticWebAssetsEnabled>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
@@ -40,11 +41,6 @@
|
|||||||
<PackagePath>src</PackagePath>
|
<PackagePath>src</PackagePath>
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="**\*.razor" Exclude="storage\**\*;bin\**\*;obj\**\*">
|
|
||||||
<Pack>true</Pack>
|
|
||||||
<PackagePath>src</PackagePath>
|
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="Styles\**\*" Exclude="storage\**\*;bin\**\*;obj\**\*;Styles\node_modules\**\*">
|
<None Include="Styles\**\*" Exclude="storage\**\*;bin\**\*;obj\**\*;Styles\node_modules\**\*">
|
||||||
<Pack>true</Pack>
|
<Pack>true</Pack>
|
||||||
<PackagePath>styles</PackagePath>
|
<PackagePath>styles</PackagePath>
|
||||||
@@ -72,10 +68,4 @@
|
|||||||
<ProjectReference Include="..\Moonlight.Shared\Moonlight.Shared.csproj"/>
|
<ProjectReference Include="..\Moonlight.Shared\Moonlight.Shared.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Helpers\"/>
|
|
||||||
<Folder Include="Styles\"/>
|
|
||||||
<Folder Include="wwwroot\css\"/>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
npx tailwindcss -i style.css -o ../wwwroot/css/core.min.css --watch
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
npx tailwindcss -i style.css -o ../wwwroot/css/core.min.css --watch
|
|
||||||
26
Moonlight.Client/Styles/exports.css
Normal file
26
Moonlight.Client/Styles/exports.css
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
@import "./additions/fonts.css";
|
||||||
|
@import "./additions/theme.css" layer(theme);
|
||||||
|
|
||||||
|
/* @import "./additions/theme.white.css"; */
|
||||||
|
|
||||||
|
@import "./additions/buttons.css" layer(components);
|
||||||
|
@import "./additions/cards.css" layer(components);
|
||||||
|
@import "./additions/forms.css" layer(utilities);
|
||||||
|
@import "./additions/progress.css" layer(components);
|
||||||
|
@import "./additions/scrollbar.css" layer(components);
|
||||||
|
@import "./additions/loaders.css" layer(components);
|
||||||
|
@import "./additions/tabs.css" layer(components);
|
||||||
|
|
||||||
|
@source "./mappings/*.map";
|
||||||
|
|
||||||
|
#blazor-error-ui {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#blazor-loader-label:after {
|
||||||
|
content: var(--blazor-load-percentage-text, "Loading");
|
||||||
|
}
|
||||||
|
|
||||||
|
#blazor-loader-progress {
|
||||||
|
width: var(--blazor-load-percentage, 0%);
|
||||||
|
}
|
||||||
28
Moonlight.Client/Styles/package-lock.json
generated
28
Moonlight.Client/Styles/package-lock.json
generated
@@ -7,7 +7,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/cli": "^4.1.4",
|
"@tailwindcss/cli": "^4.1.4",
|
||||||
"@tailwindcss/forms": "^0.5.10",
|
"@tailwindcss/forms": "^0.5.10",
|
||||||
"tailwindcss": "^4.1.4"
|
"tailwindcss": "^4.1.4",
|
||||||
|
"xml2js": "^0.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@parcel/watcher": {
|
"node_modules/@parcel/watcher": {
|
||||||
@@ -904,6 +905,11 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sax": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||||
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.5.tgz",
|
||||||
@@ -927,6 +933,26 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xml2js": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
|
||||||
|
"dependencies": {
|
||||||
|
"sax": ">=0.6.0",
|
||||||
|
"xmlbuilder": "~11.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xmlbuilder": {
|
||||||
|
"version": "11.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||||
|
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/cli": "^4.1.4",
|
"@tailwindcss/cli": "^4.1.4",
|
||||||
"@tailwindcss/forms": "^0.5.10",
|
"@tailwindcss/forms": "^0.5.10",
|
||||||
"tailwindcss": "^4.1.4"
|
"tailwindcss": "^4.1.4",
|
||||||
|
"xml2js": "^0.6.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"tailwind": "npx tailwindcss -i style.css -o ../wwwroot/css/style.min.css --watch",
|
||||||
|
"pretailwind": "node resolveNuget.js ../Moonlight.Client.csproj"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
Moonlight.Client/Styles/preTailwind.css
Normal file
1
Moonlight.Client/Styles/preTailwind.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@import "./additions/fonts.css";
|
||||||
80
Moonlight.Client/Styles/resolveNuget.js
Normal file
80
Moonlight.Client/Styles/resolveNuget.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const os = require('os');
|
||||||
|
const xml2js = require('xml2js');
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
function getPackageRefs(csprojPath) {
|
||||||
|
const xml = fs.readFileSync(csprojPath, 'utf8');
|
||||||
|
const parser = new xml2js.Parser();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
parser.parseString(xml, (err, result) => {
|
||||||
|
if (err) return reject(err);
|
||||||
|
|
||||||
|
const itemGroups = result.Project.ItemGroup || [];
|
||||||
|
const refs = [];
|
||||||
|
|
||||||
|
for (const group of itemGroups) {
|
||||||
|
const packages = group.PackageReference || [];
|
||||||
|
for (const pkg of packages) {
|
||||||
|
const name = pkg.$.Include;
|
||||||
|
const version = pkg.$.Version || (pkg.Version && pkg.Version[0]);
|
||||||
|
if (name && version) {
|
||||||
|
refs.push({ name: name.toLowerCase(), version });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(refs);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const csprojPath = process.argv[2];
|
||||||
|
if (!csprojPath || !fs.existsSync(csprojPath)) {
|
||||||
|
console.error('Usage: Missing csproj path');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nugetPath = path.join(os.homedir(), '.nuget', 'packages');
|
||||||
|
const moonlightDir = path.join(__dirname, 'node_modules', 'moonlight');
|
||||||
|
fs.mkdirSync(moonlightDir, { recursive: true });
|
||||||
|
|
||||||
|
const refs = await getPackageRefs(csprojPath);
|
||||||
|
|
||||||
|
var outputCss = "";
|
||||||
|
var preOutputCss = "";
|
||||||
|
|
||||||
|
for (const { name, version } of refs) {
|
||||||
|
const packagePath = path.join(nugetPath, name, version);
|
||||||
|
const exportsFile = path.join(packagePath, 'styles', 'exports.css');
|
||||||
|
const preTailwindFile = path.join(packagePath, 'styles', 'preTailwind.css');
|
||||||
|
const sourceFolder = path.join(packagePath, 'src');
|
||||||
|
|
||||||
|
const rel = (p) => p.replace(/\\/g, '/');
|
||||||
|
|
||||||
|
if (fs.existsSync(exportsFile)) {
|
||||||
|
outputCss += `@import "${rel(exportsFile)}";\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(preTailwindFile)) {
|
||||||
|
preOutputCss += `@import "${rel(preTailwindFile)}";\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(sourceFolder)) {
|
||||||
|
outputCss += `@source "${rel(path.join(sourceFolder, "**", "*.razor"))}";\n`;
|
||||||
|
outputCss += `@source "${rel(path.join(sourceFolder, "**", "*.cs"))}";\n`;
|
||||||
|
outputCss += `@source "${rel(path.join(sourceFolder, "**", "*.html"))}";\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(moonlightDir, 'nuget.css'), outputCss);
|
||||||
|
fs.writeFileSync(path.join(moonlightDir, 'preTailwind.nuget.css'), preOutputCss);
|
||||||
|
console.log(`Generated nuget.css in ${moonlightDir}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -1,16 +1,10 @@
|
|||||||
@import "./additions/fonts.css";
|
@import "./preTailwind.css";
|
||||||
|
@import "moonlight/preTailwind.nuget.css";
|
||||||
|
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "./additions/theme.css" layer(theme);
|
|
||||||
|
|
||||||
/* @import "./additions/theme.white.css"; */
|
@import "./exports.css";
|
||||||
|
@import "moonlight/nuget.css";
|
||||||
@import "./additions/buttons.css" layer(components);
|
|
||||||
@import "./additions/cards.css" layer(components);
|
|
||||||
@import "./additions/forms.css" layer(utilities);
|
|
||||||
@import "./additions/progress.css" layer(components);
|
|
||||||
@import "./additions/scrollbar.css" layer(components);
|
|
||||||
@import "./additions/loaders.css" layer(components);
|
|
||||||
@import "./additions/tabs.css" layer(components);
|
|
||||||
|
|
||||||
@plugin "@tailwindcss/forms";
|
@plugin "@tailwindcss/forms";
|
||||||
|
|
||||||
@@ -18,15 +12,3 @@
|
|||||||
@source "../**/*.cs";
|
@source "../**/*.cs";
|
||||||
@source "../**/*.html";
|
@source "../**/*.html";
|
||||||
@source "./mappings/*.map";
|
@source "./mappings/*.map";
|
||||||
|
|
||||||
#blazor-error-ui {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blazor-loader-label:after {
|
|
||||||
content: var(--blazor-load-percentage-text, "Loading");
|
|
||||||
}
|
|
||||||
|
|
||||||
#blazor-loader-progress {
|
|
||||||
width: var(--blazor-load-percentage, 0%);
|
|
||||||
}
|
|
||||||
@@ -6,10 +6,10 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Moonlight.Client</title>
|
<title>Moonlight.Client</title>
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
<link rel="stylesheet" href="/css/bundle.css" />
|
<link rel="stylesheet" href="/css/style.min.css" />
|
||||||
<link href="manifest.webmanifest" rel="manifest" />
|
<link href="manifest.webmanifest" rel="manifest" />
|
||||||
<link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
|
<link rel="apple-touch-icon" sizes="512x512" href="/img/icon-512.png" />
|
||||||
<link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
|
<link rel="apple-touch-icon" sizes="192x192" href="/img/icon-192.png" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-gray-950 text-white font-inter h-full">
|
<body class="bg-gray-950 text-white font-inter h-full">
|
||||||
|
|||||||
60
Resources/Scripts/Functions/ContentFunctions.cs
Normal file
60
Resources/Scripts/Functions/ContentFunctions.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System.IO.Compression;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Scripts.Functions;
|
||||||
|
|
||||||
|
public static class ContentFunctions
|
||||||
|
{
|
||||||
|
public static async Task Run(string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Please provide the path to a nuget file and at least one regex expression");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nugetPath = args[0];
|
||||||
|
|
||||||
|
var regexs = args
|
||||||
|
.Skip(1)
|
||||||
|
.Select(x => new Regex(x))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
Console.WriteLine(string.Join(", ", args
|
||||||
|
.Skip(1)
|
||||||
|
.Select(x => new Regex(x))));
|
||||||
|
|
||||||
|
if (!File.Exists(nugetPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("The provided file does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Modding nuget package...");
|
||||||
|
using var zipFile = ZipFile.Open(nugetPath, ZipArchiveMode.Update);
|
||||||
|
|
||||||
|
foreach (var zipArchiveEntry in zipFile.Entries)
|
||||||
|
{
|
||||||
|
Console.WriteLine(zipArchiveEntry.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Searching for files to remove");
|
||||||
|
var files = zipFile.Entries
|
||||||
|
.Where(x => x.FullName.Trim('/').StartsWith("content"))
|
||||||
|
.Where(x =>
|
||||||
|
{
|
||||||
|
var name = x.FullName
|
||||||
|
.Replace("contentFiles/", "")
|
||||||
|
.Replace("content/", "");
|
||||||
|
|
||||||
|
Console.WriteLine(name);
|
||||||
|
|
||||||
|
return regexs.Any(y => y.IsMatch(name));
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
Console.WriteLine($"Found {files.Length} file(s) to remove");
|
||||||
|
foreach (var file in files)
|
||||||
|
file.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Resources/Scripts/Functions/SrcFunctions.cs
Normal file
47
Resources/Scripts/Functions/SrcFunctions.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
namespace Scripts.Functions;
|
||||||
|
|
||||||
|
public static class SrcFunctions
|
||||||
|
{
|
||||||
|
public static async Task Run(string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length != 3)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Please provide the path to a nuget file, a search pattern and a path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nugetPath = args[0];
|
||||||
|
var path = args[1];
|
||||||
|
var pattern = args[2];
|
||||||
|
|
||||||
|
if (!File.Exists(nugetPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("The provided file does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Modding nuget package...");
|
||||||
|
using var zipFile = ZipFile.Open(nugetPath, ZipArchiveMode.Update);
|
||||||
|
|
||||||
|
var filesToAdd = Directory.GetFiles(path, pattern, SearchOption.AllDirectories);
|
||||||
|
|
||||||
|
foreach (var file in filesToAdd)
|
||||||
|
{
|
||||||
|
var name = file.Replace(path, "").Replace("\\", "/");
|
||||||
|
|
||||||
|
Console.WriteLine($"{file} => /src/{name}");
|
||||||
|
|
||||||
|
var entry = zipFile.CreateEntry($"src/{name}");
|
||||||
|
await using var entryStream = entry.Open();
|
||||||
|
|
||||||
|
await using var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
|
await fs.CopyToAsync(entryStream);
|
||||||
|
fs.Close();
|
||||||
|
|
||||||
|
await entryStream.FlushAsync();
|
||||||
|
entryStream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
Resources/Scripts/Functions/StaticWebAssetsFunctions.cs
Normal file
93
Resources/Scripts/Functions/StaticWebAssetsFunctions.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System.IO.Compression;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Scripts.Functions;
|
||||||
|
|
||||||
|
public static class StaticWebAssetsFunctions
|
||||||
|
{
|
||||||
|
public static async Task Run(string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Please provide the path to a nuget file and at least one regex expression");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nugetPath = args[0];
|
||||||
|
|
||||||
|
var regexs = args
|
||||||
|
.Skip(1)
|
||||||
|
.Select(x => new Regex(x))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (!File.Exists(nugetPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("The provided file does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Modding nuget package...");
|
||||||
|
using var zipFile = ZipFile.Open(nugetPath, ZipArchiveMode.Update);
|
||||||
|
|
||||||
|
Console.WriteLine("Searching for files to remove");
|
||||||
|
var files = zipFile.Entries
|
||||||
|
.Where(x => x.FullName.Trim('/').StartsWith("staticwebassets"))
|
||||||
|
.Where(x =>
|
||||||
|
{
|
||||||
|
var name = x.FullName.Replace("staticwebassets/", "");
|
||||||
|
|
||||||
|
return regexs.Any(y => y.IsMatch(name));
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
Console.WriteLine($"Found {files.Length} file(s) to remove");
|
||||||
|
foreach (var file in files)
|
||||||
|
file.Delete();
|
||||||
|
|
||||||
|
Console.WriteLine("Modifying static web assets build target");
|
||||||
|
var oldBuildTargetEntry = zipFile
|
||||||
|
.Entries
|
||||||
|
.FirstOrDefault(x => x.FullName == "build/Microsoft.AspNetCore.StaticWebAssets.props");
|
||||||
|
|
||||||
|
if (oldBuildTargetEntry == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Build target file not found in nuget packages");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var oldBuildTargetStream = oldBuildTargetEntry.Open();
|
||||||
|
|
||||||
|
var contentXml = await XDocument.LoadAsync(
|
||||||
|
oldBuildTargetStream,
|
||||||
|
LoadOptions.None,
|
||||||
|
CancellationToken.None
|
||||||
|
);
|
||||||
|
|
||||||
|
oldBuildTargetStream.Close();
|
||||||
|
oldBuildTargetEntry.Delete();
|
||||||
|
|
||||||
|
var assetRefsToRemove = contentXml
|
||||||
|
.Descendants("StaticWebAsset")
|
||||||
|
.Where(asset =>
|
||||||
|
{
|
||||||
|
var element = asset.Element("RelativePath");
|
||||||
|
|
||||||
|
if (element == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return regexs.Any(y => y.IsMatch(element.Value));
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
foreach (var asset in assetRefsToRemove)
|
||||||
|
asset.Remove();
|
||||||
|
|
||||||
|
var newBuildTargetEntry = zipFile.CreateEntry("build/Microsoft.AspNetCore.StaticWebAssets.props");
|
||||||
|
await using var newBuildTargetStream = newBuildTargetEntry.Open();
|
||||||
|
|
||||||
|
await contentXml.SaveAsync(newBuildTargetStream, SaveOptions.None, CancellationToken.None);
|
||||||
|
|
||||||
|
newBuildTargetStream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Resources/Scripts/Program.cs
Normal file
26
Resources/Scripts/Program.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using Scripts.Functions;
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("You need to specify a module to run");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var module = args[0];
|
||||||
|
var moduleArgs = args.Skip(1).ToArray();
|
||||||
|
|
||||||
|
switch (module)
|
||||||
|
{
|
||||||
|
case "staticWebAssets":
|
||||||
|
await StaticWebAssetsFunctions.Run(moduleArgs);
|
||||||
|
break;
|
||||||
|
case "content":
|
||||||
|
await ContentFunctions.Run(moduleArgs);
|
||||||
|
break;
|
||||||
|
case "src":
|
||||||
|
await SrcFunctions.Run(moduleArgs);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.WriteLine($"No module named {module} found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
10
Resources/Scripts/Scripts.csproj
Normal file
10
Resources/Scripts/Scripts.csproj
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
# Set strict mode to stop on errors
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
|
|
||||||
# Ensure the script is running in the main directory
|
|
||||||
Write-Host "Building nuget packages"
|
|
||||||
|
|
||||||
Write-Host "Searching & building project files"
|
|
||||||
# Find all .csproj files recursively
|
|
||||||
$projectFiles = Get-ChildItem -Recurse -Filter "*.csproj"
|
|
||||||
|
|
||||||
foreach ($project in $projectFiles) {
|
|
||||||
# Extract project name (without extension)
|
|
||||||
$projectName = $project.BaseName
|
|
||||||
|
|
||||||
# Extract version from the .csproj file
|
|
||||||
$projectVersion = Select-String -Path $project.FullName -Pattern "<Version>(.*?)</Version>" | ForEach-Object {
|
|
||||||
$_.Matches.Groups[1].Value
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not $projectVersion) {
|
|
||||||
Write-Host "No <Version> tag found in $($project.FullName), skipping."
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build and pack the project
|
|
||||||
$projectPath = $project.DirectoryName
|
|
||||||
$pwd = (Get-Location).Path
|
|
||||||
Push-Location $projectPath
|
|
||||||
dotnet build --configuration Release
|
|
||||||
dotnet pack --configuration Release --output "$pwd\nupkgs"
|
|
||||||
Pop-Location
|
|
||||||
|
|
||||||
# Modifying the NuGet package
|
|
||||||
Write-Host "Modding nuget package"
|
|
||||||
$nugetPackage = Get-ChildItem "$pwd\nupkgs" -Filter "*.nupkg" | Select-Object -First 1
|
|
||||||
|
|
||||||
# Rename .nupkg to .zip
|
|
||||||
$zipPackage = "$($nugetPackage.FullName).zip"
|
|
||||||
Rename-Item -Path $nugetPackage.FullName -NewName $zipPackage
|
|
||||||
|
|
||||||
Expand-Archive -Path $zipPackage -DestinationPath "$pwd\nupkgs\mod" -Force
|
|
||||||
|
|
||||||
if ($projectName -eq "Moonlight.ApiServer") {
|
|
||||||
Remove-Item "$pwd\nupkgs\mod\content" -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
Remove-Item "$pwd\nupkgs\mod\contentFiles" -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
$xmlFilePath = "$pwd\nupkgs\mod\$projectName.nuspec"
|
|
||||||
$xmlContent = Get-Content -Path $xmlFilePath -Raw
|
|
||||||
$regexPattern = '<contentFiles\b[^>]*>[\s\S]*?<\/contentFiles>'
|
|
||||||
|
|
||||||
$updatedContent = [System.Text.RegularExpressions.Regex]::Replace(
|
|
||||||
$xmlContent,
|
|
||||||
$regexPattern,
|
|
||||||
"",
|
|
||||||
[System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
|
||||||
)
|
|
||||||
|
|
||||||
Set-Content -Path $xmlFilePath -Value $updatedContent -Encoding UTF8
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($projectName -eq "Moonlight.Client") {
|
|
||||||
Remove-Item "$pwd\nupkgs\mod\staticwebassets\_framework" -Recurse -Force
|
|
||||||
|
|
||||||
$xmlFilePath = "$pwd\nupkgs\mod\build\Microsoft.AspNetCore.StaticWebAssets.props"
|
|
||||||
$xmlContent = Get-Content -Path $xmlFilePath -Raw
|
|
||||||
|
|
||||||
$regexPattern = '<StaticWebAsset\b[^>]*>(?:(?!<\/StaticWebAsset>).)*?<RelativePath>_framework/blazor\.webassembly\.js(?:\.gz)?<\/RelativePath>.*?<\/StaticWebAsset>'
|
|
||||||
|
|
||||||
$updatedContent = [System.Text.RegularExpressions.Regex]::Replace(
|
|
||||||
$xmlContent,
|
|
||||||
$regexPattern,
|
|
||||||
"",
|
|
||||||
[System.Text.RegularExpressions.RegexOptions]::Singleline
|
|
||||||
)
|
|
||||||
|
|
||||||
Set-Content -Path $xmlFilePath -Value $updatedContent -Encoding UTF8
|
|
||||||
}
|
|
||||||
|
|
||||||
# Repack the modified NuGet package
|
|
||||||
Write-Host "Repacking nuget package"
|
|
||||||
Remove-Item $zipPackage
|
|
||||||
Push-Location "$pwd\nupkgs\mod"
|
|
||||||
Compress-Archive -Path * -DestinationPath $zipPackage -Force
|
|
||||||
Pop-Location
|
|
||||||
|
|
||||||
# Rename .zip back to .nupkg
|
|
||||||
Rename-Item -Path $zipPackage -NewName $nugetPackage.FullName
|
|
||||||
|
|
||||||
# Move the final package to the output directory
|
|
||||||
$finalDir = "$pwd\finalPackages"
|
|
||||||
New-Item -ItemType Directory -Path $finalDir -Force | Out-Null
|
|
||||||
Move-Item -Path $nugetPackage.FullName -Destination $finalDir
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
Write-Host "Cleaning up"
|
|
||||||
Remove-Item "$pwd\nupkgs\mod" -Recurse -Force
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Note: Run in main directory, i.e. where the Moonlight.sln is
|
|
||||||
|
|
||||||
echo "Building nuget packages"
|
|
||||||
|
|
||||||
echo "Searching & building project files"
|
|
||||||
project_files=$(find . -name "*.csproj")
|
|
||||||
|
|
||||||
for project in $project_files; do
|
|
||||||
# Extract project name
|
|
||||||
project_name=$(basename "$project" .csproj)
|
|
||||||
|
|
||||||
# Extract version
|
|
||||||
project_version=$(grep -oPm1 "(?<=<Version>)[^<]+" "$project")
|
|
||||||
if [ -z "$project_version" ]; then
|
|
||||||
echo "No <Version> tag found in $project, skipping."
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Building nuget package
|
|
||||||
pwd=$(pwd)
|
|
||||||
project_path=$(dirname $project)
|
|
||||||
(cd $project_path; dotnet build --configuration Release; dotnet pack --configuration Release --output $pwd/nupkgs)
|
|
||||||
|
|
||||||
# Mod nuget package
|
|
||||||
echo "Modding nuget package"
|
|
||||||
nugetPackage=$(find $pwd/nupkgs -name "*.nupkg")
|
|
||||||
|
|
||||||
unzip -o $nugetPackage -d $pwd/nupkgs/mod
|
|
||||||
|
|
||||||
if [ "$project_name" = "Moonlight.ApiServer" ]; then
|
|
||||||
rm -r $pwd/nupkgs/mod/content
|
|
||||||
rm -r $pwd/nupkgs/mod/contentFiles
|
|
||||||
|
|
||||||
sed -i "/<contentFiles>/,/<\/contentFiles>/d" $pwd/nupkgs/mod/Moonlight.ApiServer.nuspec
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$project_name" = "Moonlight.Client" ]; then
|
|
||||||
rm -r $pwd/nupkgs/mod/staticwebassets/_framework
|
|
||||||
|
|
||||||
sed -i '/<StaticWebAsset Include=.*blazor.webassembly.js.gz.*>/,/<\/StaticWebAsset>/d' $pwd/nupkgs/mod/build/Microsoft.AspNetCore.StaticWebAssets.props
|
|
||||||
sed -i '/<StaticWebAsset Include=.*blazor.webassembly.js.*>/,/<\/StaticWebAsset>/d' $pwd/nupkgs/mod/build/Microsoft.AspNetCore.StaticWebAssets.props
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Repacking nuget package"
|
|
||||||
rm $nugetPackage
|
|
||||||
(cd nupkgs/mod/; zip -r -o $nugetPackage *)
|
|
||||||
|
|
||||||
mkdir -p $pwd/finalPackages/
|
|
||||||
|
|
||||||
mv $nugetPackage $pwd/finalPackages/
|
|
||||||
|
|
||||||
echo "Cleaning up"
|
|
||||||
rm -r $pwd/nupkgs/mod
|
|
||||||
done
|
|
||||||
25
Resources/Scripts/generateNuget.sh
Normal file
25
Resources/Scripts/generateNuget.sh
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# We are building the packages in the debug mode because they are meant for development
|
||||||
|
# purposes only. When build for production, release builds will be used ofc
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Creating nuget packages"
|
||||||
|
mkdir -p finalPackages
|
||||||
|
|
||||||
|
echo "+ ApiServer Server"
|
||||||
|
dotnet build -c Debug Moonlight.ApiServer
|
||||||
|
dotnet pack -c Debug Moonlight.ApiServer --output finalPackages/
|
||||||
|
dotnet run --project Resources/Scripts/Scripts.csproj content finalPackages/Moonlight.ApiServer.2.1.0.nupkg ".*"
|
||||||
|
|
||||||
|
echo "+ Client"
|
||||||
|
dotnet build -c Debug Moonlight.Client
|
||||||
|
dotnet pack -c Debug Moonlight.Client --output finalPackages/
|
||||||
|
dotnet run --project Resources/Scripts/Scripts.csproj staticWebAssets finalPackages/Moonlight.Client.2.1.0.nupkg "_framework\/.*" style.min.css
|
||||||
|
dotnet run --project Resources/Scripts/Scripts.csproj src finalPackages/Moonlight.Client.2.1.0.nupkg Moonlight.Client/ *.razor
|
||||||
|
dotnet run --project Resources/Scripts/Scripts.csproj src finalPackages/Moonlight.Client.2.1.0.nupkg Moonlight.Client/ wwwroot/*.html
|
||||||
|
|
||||||
|
echo "+ Shared library"
|
||||||
|
dotnet build -c Debug Moonlight.Shared
|
||||||
|
dotnet pack -c Debug Moonlight.Shared --output finalPackages/
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
using System.IO.Compression;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
// Handle arguments
|
|
||||||
if (Args.Count != 1)
|
|
||||||
{
|
|
||||||
Console.WriteLine("You need to provide the path to a nuget file as a parameter");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nugetPath = Args[0];
|
|
||||||
|
|
||||||
// Check if file exists
|
|
||||||
if (!File.Exists(nugetPath))
|
|
||||||
{
|
|
||||||
Console.WriteLine("The provided file does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open file to modify
|
|
||||||
Console.WriteLine($"Modding nuget package: {nugetPath}");
|
|
||||||
var zipFile = ZipFile.Open(nugetPath, ZipArchiveMode.Update, Encoding.UTF8);
|
|
||||||
|
|
||||||
// First we want to remove the framework files
|
|
||||||
Console.WriteLine("Removing framework files");
|
|
||||||
|
|
||||||
var frameworkEntries = zipFile.Entries
|
|
||||||
.Where(x => x.FullName.Contains("staticwebassets/_framework"))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var frameworkEntry in frameworkEntries)
|
|
||||||
frameworkEntry.Delete();
|
|
||||||
|
|
||||||
// Then we want to modify the build targets for static web assets
|
|
||||||
var oldBuildTarget = zipFile.Entries
|
|
||||||
.First(x => x.FullName == "build/Microsoft.AspNetCore.StaticWebAssets.props");
|
|
||||||
|
|
||||||
// Load old content
|
|
||||||
var oldContentStream = oldBuildTarget.Open();
|
|
||||||
|
|
||||||
// Parse xml and remove framework references
|
|
||||||
Console.WriteLine("Removing framework web asset references");
|
|
||||||
|
|
||||||
var contentXml = XDocument.Load(oldContentStream);
|
|
||||||
oldContentStream.Close();
|
|
||||||
oldContentStream.Dispose();
|
|
||||||
oldBuildTarget.Delete();
|
|
||||||
|
|
||||||
var assetsToRemove = contentXml
|
|
||||||
.Descendants("StaticWebAsset")
|
|
||||||
.Where(asset =>
|
|
||||||
asset.Element("RelativePath")?.Value.Contains("_framework") == true)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var asset in assetsToRemove)
|
|
||||||
asset.Remove();
|
|
||||||
|
|
||||||
var newBuildTarget = zipFile.CreateEntry("build/Microsoft.AspNetCore.StaticWebAssets.props");
|
|
||||||
var newContentStream = newBuildTarget.Open();
|
|
||||||
contentXml.Save(newContentStream);
|
|
||||||
|
|
||||||
await newContentStream.FlushAsync();
|
|
||||||
newContentStream.Close();
|
|
||||||
|
|
||||||
zipFile.Dispose();
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
# This script requires a NuGet override folder at %userprofile%\NugetOverride
|
|
||||||
|
|
||||||
# Clear old build cache
|
|
||||||
Remove-Item -Recurse -Force nupkgs, finalPackages
|
|
||||||
|
|
||||||
# Build and replace NuGet packages
|
|
||||||
& "Resources\Scripts\buildNuget.ps1"
|
|
||||||
Copy-Item -Path finalPackages\* -Destination $env:userprofile\NugetOverride -Force
|
|
||||||
|
|
||||||
# Clean package cache
|
|
||||||
Remove-Item -Recurse -Force $env:userprofile\.nuget\packages\moonlight.apiserver
|
|
||||||
Remove-Item -Recurse -Force $env:userprofile\.nuget\packages\moonlight.shared
|
|
||||||
Remove-Item -Recurse -Force $env:userprofile\.nuget\packages\moonlight.client
|
|
||||||
|
|
||||||
Write-Output "Done :>"
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# This script required a nuget override folder at ~/NugetOverride
|
|
||||||
|
|
||||||
# Clear old build cache
|
|
||||||
rm -rf nupkgs/ finalPackages/
|
|
||||||
|
|
||||||
# Build and replace nuget packages
|
|
||||||
bash Resources/Scripts/buildNuget.sh
|
|
||||||
cp finalPackages/* ~/NugetOverride/
|
|
||||||
|
|
||||||
# Clean package cache
|
|
||||||
rm -rf ~/.nuget/packages/moonlight.apiserver/
|
|
||||||
rm -rf ~/.nuget/packages/moonlight.shared/
|
|
||||||
rm -rf ~/.nuget/packages/moonlight.client/
|
|
||||||
|
|
||||||
echo "Done :>"
|
|
||||||
7
Resources/Scripts/prepareNugetOverride.sh
Normal file
7
Resources/Scripts/prepareNugetOverride.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
bash Resources/Scripts/generateNuget.sh
|
||||||
|
|
||||||
|
echo "+ Copying to nuget override"
|
||||||
|
cp finalPackages/*.nupkg ~/NugetOverride/
|
||||||
|
rm -r ~/.nuget/packages/moonlight.*
|
||||||
Reference in New Issue
Block a user