diff --git a/src/Antelcat.Parameterization.Demo/Program.cs b/src/Antelcat.Parameterization.Demo/Program.cs index 7261313..710c1f4 100644 --- a/src/Antelcat.Parameterization.Demo/Program.cs +++ b/src/Antelcat.Parameterization.Demo/Program.cs @@ -5,179 +5,191 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using TestNamespace; -namespace Antelcat.Parameterization.Demo; - -[Parameterization(CaseSensitive = true)] -public static partial class Program +namespace Antelcat.Parameterization.Demo { - public static async Task Main(string[] args) + [Parameterization(CaseSensitive = true)] + public static partial class Program { - if (args.Length == 0) + public static async Task Main(string[] args) { - Console.WriteLine("Interactive mode, input 'exit' to exit."); - while (true) + if (args.Length == 0) { - try - { - await ExecuteInputAsync(Console.ReadLine()); - } - catch (Exception e) + Console.WriteLine("Interactive mode, input 'exit' to exit."); + while (true) { - Console.WriteLine(e.Message); + try + { + await ExecuteInputAsync(Console.ReadLine()); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } } } + + try + { + await ExecuteArgumentsAsync(args); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } } - try + private static readonly HashSet DownloadedImages = new(); + private static readonly HashSet Containers = new(); + + [Command(ShortName = "ps", Description = "Display a list of container(s) resources usage statistics")] + private static void Stats( + [Argument(FullName = "all", ShortName = 'a', Description = "Show all containers (default shows just running)", DefaultValue = "true")] + bool showAll = false) { - await ExecuteArgumentsAsync(args); + Console.WriteLine("CONTAINER_ID IMAGE NAME STATUS PORTS"); + foreach (var container in Containers.Where(container => showAll || container.IsRunning)) + { + Console.WriteLine($"{container.Id} {container.Image} {container.Name} {(container.IsRunning ? "running" : "stopped")}"); + } } - catch (Exception e) + + [Command] + private static void Pull(Image image) { - Console.WriteLine(e.Message); - } - } + if (DownloadedImages.Contains(image)) + { + Console.WriteLine($"Image {image} already pulled."); + return; + } - private static readonly HashSet DownloadedImages = new(); - private static readonly HashSet Containers = new(); + Console.WriteLine($"Pulling image {image}..."); + for (var i = 0; i < 10; i++) + { + Console.WriteLine($"{i * 10}%"); + Thread.Sleep(100); + } - [Command(ShortName = "ps", Description = "Display a list of container(s) resources usage statistics")] - private static void Stats( - [Argument(FullName = "all", ShortName = 'a', Description = "Show all containers (default shows just running)", DefaultValue = "true")] - bool showAll = false) - { - Console.WriteLine("CONTAINER_ID IMAGE NAME STATUS PORTS"); - foreach (var container in Containers.Where(container => showAll || container.IsRunning)) - { - Console.WriteLine($"{container.Id} {container.Image} {container.Name} {(container.IsRunning ? "running" : "stopped")}"); + DownloadedImages.Add(image); + Console.WriteLine($"Successfully Pulled image {image}"); } - } - [Command] - private static void Pull(Image image) - { - if (DownloadedImages.Contains(image)) + [Command] + private static void Run( + Image image, + string? name = null, + [Argument(FullName = "map-type")] MapType mapType = MapType.Forward, + [Argument(ShortName = 'p', Converter = typeof(PortMappingConverter))] PortMapping[]? portMappings = null) { - Console.WriteLine($"Image {image} already pulled."); - return; + Pull(image); + name ??= image.Name; + var container = new Container(image, Guid.NewGuid().ToString("N")[..8], name, true, portMappings); + Containers.Add(container); + Console.WriteLine(container); } - Console.WriteLine($"Pulling image {image}..."); - for (var i = 0; i < 10; i++) + [Command] + private static Task Stop(string id) { - Console.WriteLine($"{i * 10}%"); - Thread.Sleep(100); - } + var container = Containers.FirstOrDefault(container => container.Id == id); + if (container == null) + { + Console.WriteLine($"Container {id} not found."); + } + else + { + Console.WriteLine($"Stopping container {id}..."); + container.IsRunning = false; + } - DownloadedImages.Add(image); - Console.WriteLine($"Successfully Pulled image {image}"); - } + return Task.CompletedTask; + } - [Command] - private static void Run( - Image image, - string? name = null, - [Argument(ShortName = 'p', Converter = typeof(PortMappingConverter))] PortMapping[]? portMappings = null) - { - Pull(image); - name ??= image.Name; - var container = new Container(image, Guid.NewGuid().ToString("N")[..8], name, true, portMappings); - Containers.Add(container); - Console.WriteLine(container); + [Command(ShortName = "e")] + private static void Exit() + { + Environment.Exit(0); + } } - [Command] - private static Task Stop(string id) + public class Container(Image image, string id, string name, bool isRunning, PortMapping[]? portMappings) { - var container = Containers.FirstOrDefault(container => container.Id == id); - if (container == null) + public override int GetHashCode() { - Console.WriteLine($"Container {id} not found."); + return Id.GetHashCode(); } - else + + public virtual bool Equals(Container? other) { - Console.WriteLine($"Stopping container {id}..."); - container.IsRunning = false; + return other != null && Id == other.Id; } - return Task.CompletedTask; - } - - [Command(ShortName = "e")] - private static void Exit() - { - Environment.Exit(0); - } -} - -public class Container(Image image, string id, string name, bool isRunning, PortMapping[]? portMappings) -{ - public override int GetHashCode() - { - return Id.GetHashCode(); - } + public override string ToString() + { + return $"{Image} {Name} {(IsRunning ? "running" : "stopped")} {(PortMappings == null ? string.Empty : string.Join(", ", PortMappings))}"; + } - public virtual bool Equals(Container? other) - { - return other != null && Id == other.Id; + public Image Image { get; } = image; + public string Id { get; } = id; + public string Name { get; init; } = name; + public bool IsRunning { get; set; } = isRunning; + public PortMapping[]? PortMappings { get; } = portMappings; } - public override string ToString() + public class ImageConverter : StringConverter { - return $"{Image} {Name} {(IsRunning ? "running" : "stopped")} {(PortMappings == null ? string.Empty : string.Join(", ", PortMappings))}"; + public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value) + { + if (value is not string str) throw new ArgumentException("Invalid image string format"); + var args = str.Split(':'); + return args switch + { + { Length: 1 } => new Image(str, null), + { Length: 2 } => new Image(args[0], Version.Parse(args[1])), + _ => throw new ArgumentException("Invalid image string format") + }; + } } - public Image Image { get; } = image; - public string Id { get; } = id; - public string Name { get; init; } = name; - public bool IsRunning { get; set; } = isRunning; - public PortMapping[]? PortMappings { get; } = portMappings; -} - -public class ImageConverter : StringConverter -{ - public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value) + [TypeConverter(typeof(ImageConverter))] + public record Image(string Name, Version? Version) { - if (value is not string str) throw new ArgumentException("Invalid image string format"); - var args = str.Split(':'); - return args switch + public override string ToString() { - { Length: 1 } => new Image(str, null), - { Length: 2 } => new Image(args[0], Version.Parse(args[1])), - _ => throw new ArgumentException("Invalid image string format") - }; + return $"{Name}:{Version?.ToString() ?? "latest"}"; + } } -} -[TypeConverter(typeof(ImageConverter))] -public record Image(string Name, Version? Version) -{ - public override string ToString() + public class PortMappingConverter : StringConverter { - return $"{Name}:{Version?.ToString() ?? "latest"}"; + public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value) + { + if (value is not string str) throw new ArgumentException("Invalid port mapping string format"); + var args = str.Split(':'); + return args switch + { + { Length: 1 } => new PortMapping(int.Parse(args[0]), int.Parse(args[0])), + { Length: 2 } => new PortMapping(int.Parse(args[0]), int.Parse(args[1])), + _ => throw new ArgumentException("Invalid port mapping string format") + }; + } } -} -public class PortMappingConverter : StringConverter -{ - public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value) + public record PortMapping(int HostPort, int ContainerPort) { - if (value is not string str) throw new ArgumentException("Invalid port mapping string format"); - var args = str.Split(':'); - return args switch + public override string ToString() { - { Length: 1 } => new PortMapping(int.Parse(args[0]), int.Parse(args[0])), - { Length: 2 } => new PortMapping(int.Parse(args[0]), int.Parse(args[1])), - _ => throw new ArgumentException("Invalid port mapping string format") - }; + return $"{HostPort}->{ContainerPort}/tcp"; + } } } -public record PortMapping(int HostPort, int ContainerPort) +namespace TestNamespace { - public override string ToString() + public enum MapType { - return $"{HostPort}->{ContainerPort}/tcp"; + Forward, + Proxy } } \ No newline at end of file diff --git a/src/Antelcat.Parameterization.SourceGenerators/Antelcat.Parameterization.SourceGenerators.csproj b/src/Antelcat.Parameterization.SourceGenerators/Antelcat.Parameterization.SourceGenerators.csproj index 2b1743c..dab90c0 100644 --- a/src/Antelcat.Parameterization.SourceGenerators/Antelcat.Parameterization.SourceGenerators.csproj +++ b/src/Antelcat.Parameterization.SourceGenerators/Antelcat.Parameterization.SourceGenerators.csproj @@ -6,8 +6,8 @@ enable true Antelcat - 1.2.4 - 1.2.4 + 1.2.5 + 1.2.5 Recommended diff --git a/src/Antelcat.Parameterization.SourceGenerators/Extensions/StringExtension.cs b/src/Antelcat.Parameterization.SourceGenerators/Extensions/StringExtension.cs index 3ad7e90..8a5c1fb 100644 --- a/src/Antelcat.Parameterization.SourceGenerators/Extensions/StringExtension.cs +++ b/src/Antelcat.Parameterization.SourceGenerators/Extensions/StringExtension.cs @@ -5,4 +5,6 @@ public static class StringExtension public static string Escape(this string? s) => s == null ? "null" : $"\"{s.Replace("\"", "\\\"")}\""; public static string If(this string s, bool condition) => condition ? s : string.Empty; + + public static string? IfNullOrEmpty(this string? s, string? replacement) => string.IsNullOrEmpty(s) ? replacement : s; } \ No newline at end of file diff --git a/src/Antelcat.Parameterization.SourceGenerators/Generators/ParameterizationGenerator.cs b/src/Antelcat.Parameterization.SourceGenerators/Generators/ParameterizationGenerator.cs index 4a9d05f..59f348a 100644 --- a/src/Antelcat.Parameterization.SourceGenerators/Generators/ParameterizationGenerator.cs +++ b/src/Antelcat.Parameterization.SourceGenerators/Generators/ParameterizationGenerator.cs @@ -249,7 +249,7 @@ symbol is not IMethodSymbol .Select(p => ( typeName: p.Type.NotNull().ToDisplayName(syntaxContext.SemanticModel), - defaultValue: p.Default?.Value.ToString() + defaultValue: p.Default?.Value.ToDisplayName(syntaxContext.SemanticModel).IfNullOrEmpty(p.Default?.Value.ToString()) )) .WithIndex() .Select(x => diff --git a/src/Antelcat.Parameterization/Antelcat.Parameterization.csproj b/src/Antelcat.Parameterization/Antelcat.Parameterization.csproj index 6758b5c..add2b0a 100644 --- a/src/Antelcat.Parameterization/Antelcat.Parameterization.csproj +++ b/src/Antelcat.Parameterization/Antelcat.Parameterization.csproj @@ -6,8 +6,8 @@ enable 1.2.4 Antelcat - 1.2.4 - 1.2.4 + 1.2.5 + 1.2.5 Effortless Command-Line Application Builder A powerful source generator designed to revolutionize the way you create command-line applications. This tool simplifies the process of building CLI applications by automatically generating parsing methods with just attribute marking on classes and methods. https://github.com/Antelcat/Antelcat.Parameterization