Files
duplicati/ReleaseBuilder/PackageTarget.cs
T
Kenneth Skovhede ecd22ac264 Added support for building agent packages.
Still lacking support for Windows MSI + MacOS pkg as they are currently tied to the TrayIcon being the base.
2024-09-18 15:29:52 +02:00

254 lines
7.7 KiB
C#

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