diff --git a/.gitignore b/.gitignore
index 8ffca3f..2fe225e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@ riderModule.iml
/.idea
*.DotSettings.user
# Don't care about files created from the build script
-PowershellModule/build/PowershellModule
+output/
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 0000000..1fe7672
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,14 @@
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PowershellModule.slnx b/PowershellModule.slnx
index 4331297..858fae2 100644
--- a/PowershellModule.slnx
+++ b/PowershellModule.slnx
@@ -1,6 +1,17 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PowershellModule/build/build.ps1 b/PowershellModule/build/build.ps1
deleted file mode 100644
index 1097330..0000000
--- a/PowershellModule/build/build.ps1
+++ /dev/null
@@ -1,48 +0,0 @@
-param (
- [switch] $release
-)
-
-$wdir = $PSScriptRoot
-$module = "PowershellModule"
-$output = "$wdir/$module"
-
-if (Test-Path $output)
-{
- Remove-Item $output -Recurse
-}
-
-New-Item $output -ItemType Directory
-
-# copy the built dlls to this directory
-if($release){
- # For release we'll get a bunch of dependencies that we honestly do not need.
- # This module is built to run assuming the dotnet 10 runtime exists, and powershell is 7.6 or higher,
- # because of this we really don't need the system.* dlls that come with the publish, or the random ass
- # newtonsoft.json.dll that comes from ???? publish fucking sucks for libraries even with framework-dependent
- # selected as the publish option
- Copy-Item -Path "$( $wdir )\..\bin\Release\net10.0\publish\$module.dll" -Destination $output
- Copy-Item -Path "$( $wdir )\..\bin\Release\net10.0\publish\ModuleCore.dll" -Destination $output
-} else
-{
- Copy-Item -Path "$( $wdir )\..\bin\Debug\net10.0\*.dll" -Destination $output
-}
-#Copy-Item -Path "$( $wdir )\..\bin\Debug\netstandard2.1\*.dll" -Destination $output
-
-$manifestSplat = @{
- Path = "$output/$module.psd1"
- Author = 'Me'
- # technically we only need the base module here and it'll locate any dlls it needs
- NestedModules = @("$module.dll")#(Get-ChildItem "$output/*.dll" | Select-Object { $_.Name } -ExpandProperty Name)
- RootModule = "$module.psm1"
-# FunctionsToExport = @('Get-Calendar')
- CmdletsToExport = @('Get-Calendar')
- # These should all be empty arrays - otherwise they default to wildcard which the generated psd1 will helpfully
- # tell you not to do for performance reasons, as the fallback if these are left out is to use wildcard...
- FunctionsToExport = @()
- VariablesToExport = @()
- AliasesToExport = @()
-}
-
-New-ModuleManifest @manifestSplat
-# We don't actually need content here, it's just so PowerShell has an entry point
-New-Item "$output/$module.psm1" -ItemType File
diff --git a/build.ps1 b/build.ps1
new file mode 100644
index 0000000..a707719
--- /dev/null
+++ b/build.ps1
@@ -0,0 +1,2 @@
+dotnet run --project build/Build.csproj -- $args
+exit $LASTEXITCODE;
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..dfd6b85
--- /dev/null
+++ b/build.sh
@@ -0,0 +1 @@
+dotnet run --project ./build/Build.csproj -- "$@"
diff --git a/build/Build.csproj b/build/Build.csproj
new file mode 100644
index 0000000..0d0955f
--- /dev/null
+++ b/build/Build.csproj
@@ -0,0 +1,13 @@
+
+
+ Exe
+ net10.0
+ $(MSBuildProjectDirectory)
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/Program.cs b/build/Program.cs
new file mode 100644
index 0000000..ffb3738
--- /dev/null
+++ b/build/Program.cs
@@ -0,0 +1,55 @@
+using Cake.Common;
+using Cake.Common.IO;
+using Cake.Common.IO.Paths;
+using Cake.Core;
+using Cake.Frosting;
+using Cake.Powershell;
+
+public static class Program
+{
+ public static int Main(string[] args)
+ {
+ return new CakeHost()
+ .UseContext()
+ .Run(args);
+ }
+}
+
+public class BuildContext : FrostingContext
+{
+ ///
+ /// Base source directory
+ ///
+ public ConvertableDirectoryPath BaseSourceLocation { get; set; }
+
+ ///
+ /// Powershell module project folder
+ ///
+ public ConvertableDirectoryPath PowershellModuleProjectDirectory { get; set; }
+
+ ///
+ /// Powershell module csproj location
+ ///
+ public ConvertableFilePath PowershellModuleCsproj { get; set; }
+
+ ///
+ /// Output directory for built DLLs and powershell module manifest files
+ ///
+ public ConvertableDirectoryPath PowershellModuleOutputDir { get; set; }
+
+ ///
+ /// Path to powershell script that creates the module manifest files
+ ///
+ public ConvertableFilePath CreateModuleManifestScript { get; set; }
+
+ public BuildContext(ICakeContext context)
+ : base(context)
+ {
+ BaseSourceLocation = context.Directory("../src");
+ PowershellModuleProjectDirectory = BaseSourceLocation + context.Directory("PowershellModule");
+ PowershellModuleCsproj = PowershellModuleProjectDirectory + context.File("PowershellModule.csproj");
+ PowershellModuleOutputDir = context.Directory("../") + context.Directory("output") + context.Directory("PowershellModule");
+ var buildScriptDirectory = context.Directory("./Scripts");
+ CreateModuleManifestScript = buildScriptDirectory + context.File("CreateModuleManifest.ps1");
+ }
+}
\ No newline at end of file
diff --git a/build/Scripts/CreateModuleManifest.ps1 b/build/Scripts/CreateModuleManifest.ps1
new file mode 100644
index 0000000..4e3d920
--- /dev/null
+++ b/build/Scripts/CreateModuleManifest.ps1
@@ -0,0 +1,24 @@
+param (
+ [string]$path,
+ [string]$guid,
+ [string]$author,
+ [string[]]$nestedModules,
+ [string]$rootModule,
+ [string[]]$cmdletsToExport,
+ [string]$manifestFileLocation
+)
+
+$manifestSplat = @{
+ Path = "$path"
+ GUID = "$guid"
+ Author = "$author"
+ NestedModules = @($nestedModules)
+ RootModule = "$rootModule"
+ CmdletsToExport = @($cmdletsToExport)
+ FunctionsToExport = @()
+ VariablesToExport = @()
+ AliasesToExport = @()
+}
+
+New-ModuleManifest @manifestSplat
+New-Item "$manifestFileLocation" -ItemType File
\ No newline at end of file
diff --git a/build/Tasks/BuildTask.cs b/build/Tasks/BuildTask.cs
new file mode 100644
index 0000000..c731bcb
--- /dev/null
+++ b/build/Tasks/BuildTask.cs
@@ -0,0 +1,36 @@
+using Cake.Common.Tools.DotNet;
+using Cake.Common.Tools.DotNet.Build;
+using Cake.Common.Tools.DotNet.MSBuild;
+using Cake.Core.Diagnostics;
+using Cake.Frosting;
+
+namespace Build.Tasks;
+
+[TaskName("Build")]
+[IsDependentOn(typeof(CleanTask))]
+[IsDependeeOf(typeof(CopyOutputTask))]
+public class BuildTask : FrostingTask
+{
+ public override void Run(BuildContext context)
+ {
+ context.Log.Information($"Building: {context.PowershellModuleCsproj}");
+
+ var buildSettings = new DotNetBuildSettings()
+ {
+ MSBuildSettings = new DotNetMSBuildSettings()
+ {
+ VersionSuffix = "cake"
+ },
+ OutputDirectory = context.PowershellModuleOutputDir,
+ DiagnosticOutput = true
+ };
+
+ // /p:DebugSymbols=false
+ buildSettings.MSBuildSettings.Properties.Add("DebugSymbols", ["false"]);
+ // /p:DebugType=None
+ buildSettings.MSBuildSettings.Properties.Add("DebugType", ["None"]);
+
+ context.DotNetBuild(context.PowershellModuleCsproj, buildSettings);
+ base.Run(context);
+ }
+}
\ No newline at end of file
diff --git a/build/Tasks/CleanTask.cs b/build/Tasks/CleanTask.cs
new file mode 100644
index 0000000..36ab859
--- /dev/null
+++ b/build/Tasks/CleanTask.cs
@@ -0,0 +1,23 @@
+using Cake.Common;
+using Cake.Common.Tools.DotNet;
+using Cake.Core.Diagnostics;
+using Cake.Frosting;
+
+namespace Build.Tasks;
+
+[TaskName("Clean")]
+public class CleanTask : FrostingTask
+{
+ public override void Run(BuildContext context)
+ {
+ context.DotNetClean(context.PowershellModuleProjectDirectory);
+
+ var outDir = context.FileSystem.GetDirectory(context.PowershellModuleOutputDir);
+ if (outDir.Exists)
+ {
+ outDir.Delete(true);
+ }
+
+ base.Run(context);
+ }
+}
\ No newline at end of file
diff --git a/build/Tasks/CopyOutputTask.cs b/build/Tasks/CopyOutputTask.cs
new file mode 100644
index 0000000..175f82a
--- /dev/null
+++ b/build/Tasks/CopyOutputTask.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Linq;
+using Cake.Core.Diagnostics;
+using Cake.Core.IO;
+using Cake.Frosting;
+using Cake.Powershell;
+
+namespace Build.Tasks;
+
+[TaskName("CopyOutput")]
+public class CopyOutputTask : FrostingTask
+{
+ public override void Run(BuildContext context)
+ {
+ var powershellModuleName = "PowershellModule";
+ var scriptParams = new
+ {
+ Path = $"{context.PowershellModuleOutputDir}/{powershellModuleName}.psd1",
+ Guid = Guid.Parse("5cdf4635-edb0-428c-8d9b-92d0bcd47443"),
+ Author = "Me",
+ NestedModules = new[] { $"{powershellModuleName}.dll" },
+ RootModule = $"{powershellModuleName}.psm1",
+ CmdletsToExport = new[] { "Get-Calendar" },
+ ManifestFileLocation = $"{context.PowershellModuleOutputDir}/{powershellModuleName}.psm1"
+ };
+
+ var psSettings = new PowershellSettings()
+ {
+ Arguments = new ProcessArgumentBuilder(),
+ };
+
+ // This feels a bit ugly/redundant seeing as I've defined the scriptParams above, but I'm leaving it as is
+ // until I want to come back and clean this up properly
+ psSettings.Arguments.Append("path", ToPowershellSafeString(scriptParams.Path));
+ psSettings.Arguments.Append("guid", ToPowershellSafeString(scriptParams.Guid.ToString()));
+ psSettings.Arguments.Append("author", ToPowershellSafeString(scriptParams.Author));
+ psSettings.Arguments.Append("nestedModules", $"@({string.Join(",", scriptParams.NestedModules.Select(ToPowershellSafeString))})");
+ psSettings.Arguments.Append("rootModule", ToPowershellSafeString(scriptParams.RootModule));
+ psSettings.Arguments.Append("cmdletsToExport", $"@({string.Join(",", scriptParams.CmdletsToExport.Select(ToPowershellSafeString))})");
+ psSettings.Arguments.Append("manifestFileLocation", ToPowershellSafeString(scriptParams.ManifestFileLocation));
+
+ context.StartPowershellFile(context.CreateModuleManifestScript, psSettings);
+ context.Log.Information($"Module output to: {context.PowershellModuleOutputDir.Path.MakeAbsolute(context.Environment)}");
+
+ base.Run(context);
+ }
+
+ private static string ToPowershellSafeString(string unescapedString) => $"'{unescapedString}'";
+}
\ No newline at end of file
diff --git a/build/Tasks/DefaultTask.cs b/build/Tasks/DefaultTask.cs
new file mode 100644
index 0000000..200768c
--- /dev/null
+++ b/build/Tasks/DefaultTask.cs
@@ -0,0 +1,16 @@
+using Cake.Core;
+using Cake.Core.Diagnostics;
+using Cake.Frosting;
+
+namespace Build.Tasks;
+
+// Consider this the "entry" point for builds, task order is defined by a chain of IsDependentOn
+[TaskName("Default")]
+[IsDependentOn(typeof(CopyOutputTask))]
+public class DefaultTask : FrostingTask
+{
+ public override void Run(ICakeContext context)
+ {
+ base.Run(context);
+ }
+}
\ No newline at end of file
diff --git a/ModuleCore/Calendar/Calendar.cs b/src/ModuleCore/Calendar/Calendar.cs
similarity index 99%
rename from ModuleCore/Calendar/Calendar.cs
rename to src/ModuleCore/Calendar/Calendar.cs
index 138f394..019d748 100644
--- a/ModuleCore/Calendar/Calendar.cs
+++ b/src/ModuleCore/Calendar/Calendar.cs
@@ -254,6 +254,6 @@ public sealed class Calendar
public class MonthCalendar
{
- public List Calendar { get; set; }
+ public List Calendar { get; set; } = [];
public int WeeksInMonth { get; set; }
}
\ No newline at end of file
diff --git a/src/ModuleCore/Directory.Build.props b/src/ModuleCore/Directory.Build.props
new file mode 100644
index 0000000..afa6e9c
--- /dev/null
+++ b/src/ModuleCore/Directory.Build.props
@@ -0,0 +1,6 @@
+
+
+ 0.0.0
+ dev
+
+
\ No newline at end of file
diff --git a/ModuleCore/ModuleCore.csproj b/src/ModuleCore/ModuleCore.csproj
similarity index 100%
rename from ModuleCore/ModuleCore.csproj
rename to src/ModuleCore/ModuleCore.csproj
diff --git a/Harness/Harness.csproj b/src/ModuleHarness/ModuleHarness.csproj
similarity index 100%
rename from Harness/Harness.csproj
rename to src/ModuleHarness/ModuleHarness.csproj
diff --git a/Harness/Program.cs b/src/ModuleHarness/Program.cs
similarity index 94%
rename from Harness/Program.cs
rename to src/ModuleHarness/Program.cs
index 59e7805..a01a1db 100644
--- a/Harness/Program.cs
+++ b/src/ModuleHarness/Program.cs
@@ -1,7 +1,7 @@
using System.Text;
using ModuleCore.Calendar;
-namespace Harness;
+namespace ModuleHarness;
class Program
{
diff --git a/PowershellHarness/CustomHost.cs b/src/PowershellHarness/CustomHost.cs
similarity index 100%
rename from PowershellHarness/CustomHost.cs
rename to src/PowershellHarness/CustomHost.cs
diff --git a/PowershellHarness/PowershellHarness.csproj b/src/PowershellHarness/PowershellHarness.csproj
similarity index 75%
rename from PowershellHarness/PowershellHarness.csproj
rename to src/PowershellHarness/PowershellHarness.csproj
index 250d874..80cdb76 100644
--- a/PowershellHarness/PowershellHarness.csproj
+++ b/src/PowershellHarness/PowershellHarness.csproj
@@ -8,7 +8,8 @@
-
+
+
diff --git a/PowershellHarness/Program.cs b/src/PowershellHarness/Program.cs
similarity index 100%
rename from PowershellHarness/Program.cs
rename to src/PowershellHarness/Program.cs
diff --git a/PowershellModule/Calendar/GetCalendarCommand.cs b/src/PowershellModule/Calendar/GetCalendarCommand.cs
similarity index 100%
rename from PowershellModule/Calendar/GetCalendarCommand.cs
rename to src/PowershellModule/Calendar/GetCalendarCommand.cs
diff --git a/src/PowershellModule/Directory.Build.props b/src/PowershellModule/Directory.Build.props
new file mode 100644
index 0000000..afa6e9c
--- /dev/null
+++ b/src/PowershellModule/Directory.Build.props
@@ -0,0 +1,6 @@
+
+
+ 0.0.0
+ dev
+
+
\ No newline at end of file
diff --git a/PowershellModule/PowershellModule.csproj b/src/PowershellModule/PowershellModule.csproj
similarity index 72%
rename from PowershellModule/PowershellModule.csproj
rename to src/PowershellModule/PowershellModule.csproj
index d127d89..c7f5801 100644
--- a/PowershellModule/PowershellModule.csproj
+++ b/src/PowershellModule/PowershellModule.csproj
@@ -8,10 +8,10 @@
-
+
All
-
+
diff --git a/PowershellModule/manifest.json b/src/PowershellModule/manifest.json
similarity index 100%
rename from PowershellModule/manifest.json
rename to src/PowershellModule/manifest.json
diff --git a/PowershellModule/meta/PowershellModule.psd1 b/src/PowershellModule/meta/PowershellModule.psd1
similarity index 100%
rename from PowershellModule/meta/PowershellModule.psd1
rename to src/PowershellModule/meta/PowershellModule.psd1
diff --git a/PowershellModule/meta/PowershellModule.psm1 b/src/PowershellModule/meta/PowershellModule.psm1
similarity index 100%
rename from PowershellModule/meta/PowershellModule.psm1
rename to src/PowershellModule/meta/PowershellModule.psm1