Skip to content

Commit 7cda8f7

Browse files
committed
Add project files.
1 parent 7d3e433 commit 7cda8f7

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

Compression.cs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.IO.Compression;
2+
3+
namespace PreCompress;
4+
5+
internal static class Compression
6+
{
7+
public static async Task CompressAsync(FileInfo file, bool bratli, bool gzip, DirectoryInfo? destination, CancellationToken token)
8+
{
9+
var tasks = new List<Task>();
10+
11+
var dest = Path.Combine(destination?.FullName ?? Path.GetDirectoryName(file.FullName)!, Path.GetFileName(file.Name));
12+
13+
if (bratli)
14+
{
15+
tasks.Add(CompressFileAsync(file.FullName, dest + ".br", BrotliCompressor, token));
16+
}
17+
18+
if (gzip)
19+
{
20+
tasks.Add(CompressFileAsync(file.FullName, dest + ".gz", GZipCompressor, token));
21+
}
22+
23+
await Task.WhenAll(tasks);
24+
}
25+
26+
private static CompressionLevel GetCompressionLevel()
27+
{
28+
if (Enum.IsDefined(typeof(CompressionLevel), 3)) // NOTE: CompressionLevel.SmallestSize == 3 is not supported in .NET Core 3.1
29+
{
30+
return (CompressionLevel)3;
31+
}
32+
return CompressionLevel.Optimal;
33+
}
34+
35+
private static async Task CompressFileAsync(string originalFileName, string compressedFileName, Func<Stream, Stream, CancellationToken, Task> compressor, CancellationToken cancel = default)
36+
{
37+
using (FileStream originalStream = File.Open(originalFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
38+
{
39+
using (FileStream compressedStream = File.Create(compressedFileName))
40+
{
41+
await compressor(originalStream, compressedStream, cancel);
42+
}
43+
}
44+
}
45+
46+
private static async Task BrotliCompressor(Stream originalStream, Stream compressedStream, CancellationToken cancel = default)
47+
{
48+
using (var compressor = new BrotliStream(compressedStream, GetCompressionLevel()))
49+
{
50+
await originalStream.CopyToAsync(compressor, cancel);
51+
}
52+
}
53+
54+
private static async Task GZipCompressor(Stream originalStream, Stream compressedStream, CancellationToken cancel = default)
55+
{
56+
using (var compressor = new GZipStream(compressedStream, GetCompressionLevel()))
57+
{
58+
await originalStream.CopyToAsync(compressor, cancel);
59+
}
60+
}
61+
}

PreCompress.csproj

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<LangVersion>latest</LangVersion>
9+
<SignAssembly>False</SignAssembly>
10+
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
11+
<Title>Precompressor for ASP.NET Core</Title>
12+
<Authors>zorgoz</Authors>
13+
<Company>zorgoz</Company>
14+
<Description>Tool to be used to created precompressed content to be served by Kestler.
15+
Created to work around wrong compressed content during publish.</Description>
16+
<Copyright>MIT</Copyright>
17+
</PropertyGroup>
18+
19+
<ItemGroup>
20+
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
21+
</ItemGroup>
22+
23+
</Project>

PreCompress.sln

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.10.34607.79
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PreCompress", "PreCompress.csproj", "{A29E9E5B-3996-43E5-B6E6-D44F0A9A12F4}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{A29E9E5B-3996-43E5-B6E6-D44F0A9A12F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{A29E9E5B-3996-43E5-B6E6-D44F0A9A12F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{A29E9E5B-3996-43E5-B6E6-D44F0A9A12F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{A29E9E5B-3996-43E5-B6E6-D44F0A9A12F4}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {9325ECC9-4198-4304-B092-A831B0545AC7}
24+
EndGlobalSection
25+
EndGlobal

Program.cs

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System.CommandLine;
2+
using System.CommandLine.Parsing;
3+
using System.Runtime.CompilerServices;
4+
using System.Xml.Schema;
5+
using PreCompress;
6+
7+
var fileOption = new Option<FileInfo[]?>(
8+
name: "-i",
9+
description: "The file to compress.",
10+
isDefault: true,
11+
parseArgument: result =>
12+
{
13+
if (result.Tokens.Count == 0)
14+
{
15+
result.ErrorMessage = "No input sepcified";
16+
return null;
17+
}
18+
19+
char[] wildcards = [ '*', '?' ] ;
20+
21+
var res = result.Tokens
22+
.Select(x => (pattern: x.Value, dir: EmptyCoalesce(Path.GetDirectoryName(x.Value), Directory.GetCurrentDirectory())!))
23+
.SelectMany(x =>
24+
x switch
25+
{
26+
_ when Directory.Exists(x.pattern) =>
27+
new DirectoryInfo(x.pattern).GetFiles(),
28+
_ when x.pattern.Intersect(wildcards).Any() && Directory.Exists(x.dir) =>
29+
Directory.GetFiles(x.dir, Path.GetFileName(x.pattern)).Select(f => new FileInfo(f)),
30+
_ when File.Exists(x.pattern) =>
31+
[ new FileInfo(x.pattern) ],
32+
_ =>
33+
[]
34+
}
35+
).ToArray();
36+
37+
if(res.Length == 0)
38+
{
39+
result.ErrorMessage = "No files found";
40+
return null;
41+
}
42+
43+
return res;
44+
})
45+
{
46+
AllowMultipleArgumentsPerToken = true,
47+
IsRequired = true,
48+
};
49+
50+
fileOption.AddAlias("--input");
51+
52+
var bratliOption = new Option<bool>(name: "-nb", description: "Omit Bratli compressed version.", getDefaultValue: () => false);
53+
bratliOption.AddAlias("--NoBratli");
54+
55+
var gzipOption = new Option<bool>(name: "-ng", description: "Omit GZip compressed version.", getDefaultValue: () => false);
56+
gzipOption.AddAlias("--NoGzip");
57+
58+
var destinationOption = new Option<DirectoryInfo?>(name: "-d", description: "The output directory.");
59+
destinationOption.AddAlias("--destination");
60+
61+
var rootCommand = new RootCommand("PreCompression tool for ASP.NET Core");
62+
rootCommand.AddOption(fileOption);
63+
rootCommand.AddOption(bratliOption);
64+
rootCommand.AddOption(gzipOption);
65+
rootCommand.AddOption(destinationOption);
66+
rootCommand.SetHandler(ReCompress, fileOption, bratliOption, gzipOption, destinationOption);
67+
68+
return await rootCommand.InvokeAsync(args);
69+
70+
static async Task ReCompress(FileInfo[]? files, bool omitBratli, bool omitGZip, DirectoryInfo? destination)
71+
{
72+
if(files is null) return;
73+
74+
foreach (var file in files)
75+
{
76+
try
77+
{
78+
Console.WriteLine($"Processing {file.FullName}");
79+
await Compression.CompressAsync(file, !omitBratli, !omitGZip, destination, default);
80+
}
81+
catch (Exception ex)
82+
{
83+
Console.Error.WriteLine($"Error processing {file.FullName}: {ex.Message}");
84+
}
85+
86+
}
87+
}
88+
89+
static string? EmptyCoalesce(params string?[] values) => values.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x));

Properties/launchSettings.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"profiles": {
3+
"ReCompress": {
4+
"commandName": "Project",
5+
"commandLineArgs": "-i D:\\Users\\zolta\\source\\repos\\bmw\\WagoDaliControlPanel\\bin\\Debug\\net8.0\\*.dll -i *.json",
6+
"workingDirectory": "C:\\Users\\zolta\\source\\repos\\bmw\\WagoDaliControlPanel\\bin\\Debug\\net8.0"
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)