using System.Text.RegularExpressions;
namespace ReleaseBuilder;
///
/// The operating systems we can build for
///
public enum OSType
{
///
/// The Windows OS
///
Windows,
///
/// The MacOS
///
MacOS,
///
/// Linux, any variant
///
Linux
}
///
/// The system architecture
///
public enum ArchType
{
///
/// An x86 64-bit architecture
///
x64,
///
/// An x86 32-bit architecture
///
x86,
///
/// The ARM-64 architecture
///
Arm64,
///
/// The ARM v7 architecture
///
Arm7
}
///
/// The different package types
///
public enum PackageType
{
///
/// The basic zip package
///
Zip,
///
/// The Windows installer format
///
MSI,
///
/// The debian package format
///
Deb,
///
/// The Redhat package manager format
///
RPM,
///
/// Docker build
///
Docker,
///
/// Apple Disk Image
///
DMG,
///
/// The MacOS pkg format
///
MacPkg,
///
/// The synology Spk format
///
SynologySpk
}
///
/// The interface type
///
public enum InterfaceType
{
///
/// The GUI interface
///
GUI,
///
/// The commandline interface
///
Cli
}
///
/// Mapping of a package target
///
/// The operating system
/// The CPU architecture
/// The interface type
/// The installer package
public record PackageTarget(OSType OS, ArchType Arch, InterfaceType Interface, PackageType Package)
{
///
/// Returns a string representation of the OS.
///
/// The operating system
/// The operating system id-string
/// This is using .Net RID: https://learn.microsoft.com/en-us/dotnet/core/rid-catalog
private static string OSToString(OSType os)
=> os switch
{
OSType.Windows => "win",
OSType.Linux => "linux",
OSType.MacOS => "osx",
_ => throw new Exception("Not supported OS")
};
///
/// Returns a string representation of the CPU architecture
///
/// The architecture
/// The CPU architecture id-string
/// This is using .Net RID: https://learn.microsoft.com/en-us/dotnet/core/rid-catalog
private static string ArchToString(ArchType arch)
=> arch switch
{
ArchType.x64 => "x64",
ArchType.x86 => "x86",
ArchType.Arm64 => "arm64",
ArchType.Arm7 => "arm7",
_ => throw new Exception("Not supported arch")
};
///
/// Returns a string representation of the package type
///
/// The package type
/// The package type id-string
private static string PackageToString(PackageType package)
=> package switch
{
PackageType.Zip => "zip",
PackageType.MSI => "msi",
PackageType.Deb => "deb",
PackageType.RPM => "rpm",
PackageType.DMG => "dmg",
PackageType.MacPkg => "pkg",
PackageType.SynologySpk => "spk",
PackageType.Docker => "docker",
_ => throw new Exception("Not supported package type")
};
///
/// Returns a string representation of the interface type
///
/// The interface type
/// The interface type id-string
private static string InterfaceToString(InterfaceType interfaceType)
=> interfaceType switch
{
InterfaceType.GUI => "gui",
InterfaceType.Cli => "cli",
_ => throw new Exception("Not supported interface type")
};
///
/// Gets the RID string for the operating system
///
public string OSString => OSToString(OS);
///
/// Gets the RID string for the CPU architecture
///
public string ArchString => ArchToString(Arch);
///
/// Gets the id string for the interface
///
public string InterfaceString => InterfaceToString(Interface);
///
/// Gets the id string for the package
///
public string PackageString => PackageToString(Package);
///
/// String map of operating system RIDs
///
private static Dictionary OSTypeParse = Enum.GetValues().ToDictionary(OSToString, x => x, StringComparer.OrdinalIgnoreCase);
///
/// String map of architecture RIDs
///
private static Dictionary ArchTypeParse = Enum.GetValues().ToDictionary(ArchToString, x => x, StringComparer.OrdinalIgnoreCase);
///
/// String map of package type ids
///
private static Dictionary PackageTypeParse = Enum.GetValues().ToDictionary(PackageToString, x => x, StringComparer.OrdinalIgnoreCase);
///
/// String map of interface type ids
///
private static Dictionary InterfaceTypeParse = Enum.GetValues().ToDictionary(InterfaceToString, x => x, StringComparer.OrdinalIgnoreCase);
///
/// The RID string for .Net build commands
///
public string BuildArchString => $"{OSString}-{ArchString}";
///
/// The target string for the builds
///
public string BuildTargetString => $"{BuildArchString}-{InterfaceString}";
///
/// The package string for the updater
///
public string PackageTargetString => $"{BuildTargetString}.{PackageString}";
///
/// Parses a string representation of a package target
///
/// The id to parse
/// The matching the string
public static PackageTarget ParsePackageId(string id)
{
var re = Regex.Match(id, @"(?\w+)-(?\w+)-(?\w+)\.(?\w+)");
if (!re.Success)
throw new Exception($"Invalid package id: {id}");
if (!OSTypeParse.TryGetValue(re.Groups["os"].Value, out var os))
throw new Exception($"Not supported OS type: {re.Groups["os"].Value}");
if (!ArchTypeParse.TryGetValue(re.Groups["arch"].Value, out var arch))
throw new Exception($"Not supported Arch type: {re.Groups["arch"].Value}");
if (!InterfaceTypeParse.TryGetValue(re.Groups["int"].Value, out var interfaceType))
throw new Exception($"Not supported Interface type: {re.Groups["int"].Value}");
if (!PackageTypeParse.TryGetValue(re.Groups["package"].Value, out var package))
throw new Exception($"Not supported Package type: {re.Groups["package"].Value}");
return new PackageTarget(os, arch, interfaceType, package);
}
}