Compare commits
No commits in common. "6167461ad884b3863a365cb600cde9e3a80498fb" and "9fe53b344ae49a94cf5433b5cf2f2c250c6cd21c" have entirely different histories.
6167461ad8
...
9fe53b344a
|
|
@ -1,36 +0,0 @@
|
||||||
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
|
|
||||||
83
Program.cs
83
Program.cs
|
|
@ -17,6 +17,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -64,59 +66,70 @@ class Program
|
||||||
|
|
||||||
Stopwatch TotalExecutionTime = Stopwatch.StartNew();
|
Stopwatch TotalExecutionTime = Stopwatch.StartNew();
|
||||||
|
|
||||||
/* WARN:
|
/* !! IMPORTANT !!
|
||||||
This code uses system.commandline
|
WARN:
|
||||||
|
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
|
||||||
Option<DirectoryInfo> ProjectDirectoryOption = new("--project","-p")
|
var ProjectDirectoryOption = new Option<DirectoryInfo>(
|
||||||
|
name: "--project",
|
||||||
|
description: "The Directory for the project");
|
||||||
|
ProjectDirectoryOption.IsRequired = false; // it is not required as not providing it infers that the current directory is the project directory
|
||||||
|
// If the option is used then the input is validated before control passes to any of the actual code.
|
||||||
|
ProjectDirectoryOption.AddValidator(result =>
|
||||||
{
|
{
|
||||||
Description = "The directory of the project",
|
if (!result.GetValueForOption(ProjectDirectoryOption)!.Exists)
|
||||||
Required = false,
|
|
||||||
DefaultValueFactory = _ =>
|
|
||||||
{
|
{
|
||||||
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.
|
||||||
RootCommand rootCommand = new("csSiteGen");
|
var rootCommand = new RootCommand("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.Options.Add(ProjectDirectoryOption); // This command can use the project directory option we created earlier
|
cleanCommand.AddOption(ProjectDirectoryOption); // This command can use the project directory option we created earlier
|
||||||
cleanCommand.SetAction(parseResult =>
|
cleanCommand.SetHandler(async (ProjectDirectory) =>
|
||||||
{
|
{
|
||||||
Clean(parseResult.GetValue<DirectoryInfo>("--project")!);
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
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.Options.Add(ProjectDirectoryOption); // This command can use the project directory option
|
convertCommand.AddOption(ProjectDirectoryOption); // This command can use the project directory option
|
||||||
convertCommand.SetAction(parseResult =>
|
convertCommand.SetHandler(async (ProjectDirectory) =>
|
||||||
{
|
{
|
||||||
Convert(parseResult.GetValue<DirectoryInfo>("--project")!);
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
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.Subcommands.Add(cleanCommand);
|
rootCommand.AddCommand(cleanCommand);
|
||||||
rootCommand.Subcommands.Add(convertCommand);
|
rootCommand.AddCommand(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);
|
||||||
|
|
@ -126,12 +139,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
|
||||||
// TODO: A better solution that checks the terminal value and sets this option should be added in the future.
|
// 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;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -198,7 +211,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");
|
||||||
|
|
||||||
|
|
@ -270,10 +283,15 @@ 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"));
|
||||||
|
|
||||||
|
|
@ -281,7 +299,6 @@ 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,47 +3,42 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<Version Condition="'$(RELEASE_VERSION)' != ''">$(RELEASE_VERSION)</Version>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.3</VersionPrefix>
|
||||||
<Nullable>enable</Nullable>
|
<VersionSuffix Condition="'$(RELEASE_VERSION)' == ''">$([System.DateTime]::UtcNow.ToString(`yyyyMMdd-HHmm`))</VersionSuffix>
|
||||||
|
|
||||||
<PublishSingleFile>True</PublishSingleFile>
|
|
||||||
<SelfContained>True</SelfContained>
|
|
||||||
<PublishTrimmed>True</PublishTrimmed>
|
|
||||||
|
|
||||||
|
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
|
||||||
<Version Condition="'$(RELEASE_VERSION)' != ''">$(RELEASE_VERSION)</Version>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.4</VersionPrefix>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<VersionSuffix Condition="'$(RELEASE_VERSION)' == ''">$([System.DateTime]::UtcNow.ToString(`yyyyMMdd-HHmm`))</VersionSuffix>
|
<Nullable>enable</Nullable>
|
||||||
</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>false</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</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