Compare commits
5 Commits
9fe53b344a
...
6167461ad8
| Author | SHA1 | Date | |
|---|---|---|---|
| 6167461ad8 | |||
| 7b41afd790 | |||
| ddfae61fdc | |||
| 5169aede88 | |||
| 700dc715fb |
36
.gitea/workflows/publish.yaml
Normal file
36
.gitea/workflows/publish.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
name: Build and Generate Release Artifact
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Build csSiteGen
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: 10.x
|
||||||
|
-run: |
|
||||||
|
dotnet publish csSiteGen.csproj \
|
||||||
|
-c Release \
|
||||||
|
-r linux-x64 \
|
||||||
|
--self-contained true \
|
||||||
|
/p:PublishSingleFile=true \
|
||||||
|
/p:PublishTrimmed=true \
|
||||||
|
-o ./publish
|
||||||
|
|
||||||
|
- name: Create Gitea Release
|
||||||
|
id: create_release
|
||||||
|
uses: akkuman/gitea-release-action@v1
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: '--experimental-fetch'
|
||||||
|
with:
|
||||||
|
files: |-
|
||||||
|
./publish/csSiteGen
|
||||||
91
Program.cs
91
Program.cs
|
|
@ -17,8 +17,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using System.CommandLine.Builder;
|
|
||||||
using System.CommandLine.Parsing;
|
|
||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
@ -66,70 +64,59 @@ class Program
|
||||||
|
|
||||||
Stopwatch TotalExecutionTime = Stopwatch.StartNew();
|
Stopwatch TotalExecutionTime = Stopwatch.StartNew();
|
||||||
|
|
||||||
/* !! IMPORTANT !!
|
/* WARN:
|
||||||
WARN:
|
This code uses system.commandline
|
||||||
This code uses system.commandline which is still in pre-release
|
|
||||||
the following section of code will contain comments to explain the intent of the programmer
|
the following section of code will contain comments to explain the intent of the programmer
|
||||||
which may be useful if system.commandline has breaking changes
|
which may be useful if system.commandline has breaking changes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// First the option for the project directory is created
|
// First the option for the project directory is created
|
||||||
var ProjectDirectoryOption = new Option<DirectoryInfo>(
|
Option<DirectoryInfo> ProjectDirectoryOption = new("--project","-p")
|
||||||
name: "--project",
|
{
|
||||||
description: "The Directory for the project");
|
Description = "The directory of the project",
|
||||||
ProjectDirectoryOption.IsRequired = false; // it is not required as not providing it infers that the current directory is the project directory
|
Required = false,
|
||||||
// If the option is used then the input is validated before control passes to any of the actual code.
|
DefaultValueFactory = _ =>
|
||||||
ProjectDirectoryOption.AddValidator(result =>
|
|
||||||
{
|
{
|
||||||
if (!result.GetValueForOption(ProjectDirectoryOption)!.Exists)
|
return new DirectoryInfo(Directory.GetCurrentDirectory());
|
||||||
{
|
|
||||||
result.ErrorMessage = $"Project directory {result.GetValueForOption(ProjectDirectoryOption)} does not exist.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
};
|
||||||
|
|
||||||
|
// Add a validator as we want the directory to exist.
|
||||||
|
ProjectDirectoryOption.Validators.Add(result =>
|
||||||
|
{
|
||||||
|
if (! result.GetValue(ProjectDirectoryOption)!.Exists)
|
||||||
|
{
|
||||||
|
result.AddError($"Directory {result.GetValue(ProjectDirectoryOption)} does not exist");
|
||||||
|
Log.Fatal($"Passed directory '{result.GetValue(ProjectDirectoryOption)}' does not exist");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// The root command is the entry point for commandline but otherwise does nothing.
|
// The root command is the entry point for commandline but otherwise does nothing.
|
||||||
var rootCommand = new RootCommand("csSiteGen");
|
RootCommand rootCommand = new("csSiteGen");
|
||||||
|
|
||||||
|
|
||||||
// TODO: Verify if the use of async in these functions is necessary
|
|
||||||
|
|
||||||
// This creates the command for cleaning a projects output directory.
|
// This creates the command for cleaning a projects output directory.
|
||||||
var cleanCommand = new Command("clean", "Clean the projects output directory");
|
var cleanCommand = new Command("clean", "Clean the projects output directory");
|
||||||
cleanCommand.AddOption(ProjectDirectoryOption); // This command can use the project directory option we created earlier
|
cleanCommand.Options.Add(ProjectDirectoryOption); // This command can use the project directory option we created earlier
|
||||||
cleanCommand.SetHandler(async (ProjectDirectory) =>
|
cleanCommand.SetAction(parseResult =>
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
Clean(parseResult.GetValue<DirectoryInfo>("--project")!);
|
||||||
{
|
});
|
||||||
Clean(ProjectDirectory);
|
|
||||||
});
|
|
||||||
},ProjectDirectoryOption);
|
|
||||||
|
|
||||||
// This creates the command for actually converting the project.
|
// This creates the command for actually converting the project.
|
||||||
var convertCommand = new Command("convert", "Convert the projects input directory and place the files in the output directory.");
|
var convertCommand = new Command("convert", "Convert the projects input directory and place the files in the output directory.");
|
||||||
convertCommand.AddOption(ProjectDirectoryOption); // This command can use the project directory option
|
convertCommand.Options.Add(ProjectDirectoryOption); // This command can use the project directory option
|
||||||
convertCommand.SetHandler(async (ProjectDirectory) =>
|
convertCommand.SetAction(parseResult =>
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
Convert(parseResult.GetValue<DirectoryInfo>("--project")!);
|
||||||
{
|
});
|
||||||
Convert(ProjectDirectory);
|
|
||||||
});
|
|
||||||
},ProjectDirectoryOption);
|
|
||||||
|
|
||||||
// Adding the commands to the root command makes them actually callable on the commandline
|
// Adding the commands to the root command makes them actually callable on the commandline
|
||||||
rootCommand.AddCommand(cleanCommand);
|
rootCommand.Subcommands.Add(cleanCommand);
|
||||||
rootCommand.AddCommand(convertCommand);
|
rootCommand.Subcommands.Add(convertCommand);
|
||||||
|
|
||||||
// The parser is what actually handles the arguments and dispatches them to the appropriate commands.
|
|
||||||
// This is used instead of the simpler method of just Invoking the root command as it automatically creates usage statements.
|
|
||||||
// It also makes a user aware that a subcommand needs to be used.
|
|
||||||
var parser = new CommandLineBuilder(rootCommand)
|
|
||||||
.UseDefaults()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
parser.Invoke(args);
|
|
||||||
|
|
||||||
|
// Parse the commandline and immediately execute.
|
||||||
|
rootCommand.Parse(args).Invoke();
|
||||||
|
|
||||||
TotalExecutionTime.Stop();
|
TotalExecutionTime.Stop();
|
||||||
Log.Information("TotalExecutionTime {time:000}ms", TotalExecutionTime.ElapsedMilliseconds);
|
Log.Information("TotalExecutionTime {time:000}ms", TotalExecutionTime.ElapsedMilliseconds);
|
||||||
|
|
@ -139,12 +126,12 @@ class Program
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Convert(DirectoryInfo? ProjectDirectory)
|
static int Convert(DirectoryInfo ProjectDirectory)
|
||||||
{
|
{
|
||||||
Log.Information("Convert command was called, beginning conversion.");
|
Log.Information("Convert command was called, beginning conversion.");
|
||||||
|
|
||||||
// WARN: This is only temporary as Spectre.Console does not recognise some Linux terminals
|
// WARN: This is only temporary as Spectre.Console does not recognise some Linux terminals
|
||||||
// A better solution that checks the terminal value and sets this option should be added in the future.
|
// TODO: A better solution that checks the terminal value and sets this option should be added in the future.
|
||||||
AnsiConsole.Console.Profile.Capabilities.Ansi = true;
|
AnsiConsole.Console.Profile.Capabilities.Ansi = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -211,7 +198,7 @@ class Program
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Clean(DirectoryInfo? ProjectDirectory)
|
static int Clean(DirectoryInfo ProjectDirectory)
|
||||||
{
|
{
|
||||||
Log.Information("Clean command was called, Beginning cleaning");
|
Log.Information("Clean command was called, Beginning cleaning");
|
||||||
|
|
||||||
|
|
@ -283,15 +270,10 @@ class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ProjectSettings GetProjectSettings(DirectoryInfo? ProjectDirectory)
|
static ProjectSettings GetProjectSettings(DirectoryInfo ProjectDirectory)
|
||||||
{
|
{
|
||||||
// TODO: implement proper error handling where file access is performed.
|
// TODO: implement proper error handling where file access is performed.
|
||||||
|
|
||||||
if (ProjectDirectory is null)
|
|
||||||
{
|
|
||||||
// use the current directory if no project directory is passed.
|
|
||||||
ProjectDirectory = new DirectoryInfo(".");
|
|
||||||
}
|
|
||||||
Log.Information("{projectdir} => fullname {pdfn}",ProjectDirectory, ProjectDirectory.FullName);
|
Log.Information("{projectdir} => fullname {pdfn}",ProjectDirectory, ProjectDirectory.FullName);
|
||||||
FileInfo projectFile = new (Path.Combine(ProjectDirectory.FullName,"cssitegen.json"));
|
FileInfo projectFile = new (Path.Combine(ProjectDirectory.FullName,"cssitegen.json"));
|
||||||
|
|
||||||
|
|
@ -299,6 +281,7 @@ class Program
|
||||||
if (!projectFile.Exists)
|
if (!projectFile.Exists)
|
||||||
{
|
{
|
||||||
Log.Fatal("Cannot locate project file {pf} in {dir}",projectFile,ProjectDirectory);
|
Log.Fatal("Cannot locate project file {pf} in {dir}",projectFile,ProjectDirectory);
|
||||||
|
AnsiConsole.MarkupLineInterpolated($"[red]No project file found in [yellow]{ProjectDirectory}[/][/]");
|
||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,42 +3,47 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
|
||||||
<Version Condition="'$(RELEASE_VERSION)' != ''">$(RELEASE_VERSION)</Version>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.3</VersionPrefix>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<VersionSuffix Condition="'$(RELEASE_VERSION)' == ''">$([System.DateTime]::UtcNow.ToString(`yyyyMMdd-HHmm`))</VersionSuffix>
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<PublishSingleFile>True</PublishSingleFile>
|
||||||
|
<SelfContained>True</SelfContained>
|
||||||
|
<PublishTrimmed>True</PublishTrimmed>
|
||||||
|
|
||||||
|
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<Version Condition="'$(RELEASE_VERSION)' != ''">$(RELEASE_VERSION)</Version>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.4</VersionPrefix>
|
||||||
<Nullable>enable</Nullable>
|
<VersionSuffix Condition="'$(RELEASE_VERSION)' == ''">$([System.DateTime]::UtcNow.ToString(`yyyyMMdd-HHmm`))</VersionSuffix>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Serilog" Version="4.0.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
|
||||||
<PackageReference Include="spectre.console" Version="0.49.1" />
|
|
||||||
<PackageReference Include="system.commandline" Version="2.0.0-beta4.22272.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
<!-- Here we define the Debug Build.
|
<!-- Here we define the Debug Build.
|
||||||
-->
|
-->
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<!-- Here we define the release build.
|
|
||||||
The Release Build will be a Single file App
|
|
||||||
The Release Build will also do -Werror as I don't want to release shitty code
|
|
||||||
The Release Build will also be R2R as I don't want it to depend on the framework
|
|
||||||
NOTE: This build requires specifying a platform
|
|
||||||
-->
|
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<PublishAOT>true</PublishAOT>
|
|
||||||
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
|
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
|
||||||
<TrimmerSingleWarn>false</TrimmerSingleWarn>
|
<TrimmerSingleWarn>false</TrimmerSingleWarn>
|
||||||
|
<DebugSymbols>false</DebugSymbols>
|
||||||
|
<DefineDebug>false</DefineDebug>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||||
|
<PackageReference Include="spectre.console" Version="0.54.0" />
|
||||||
|
<PackageReference Include="system.commandline" Version="2.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user