From b55794dd0091d4d22f6217350bfd43e32ade648c Mon Sep 17 00:00:00 2001
From: Brant Burnett <bburnett@centeredgesoftware.com>
Date: Sat, 1 Feb 2025 12:36:46 -0500
Subject: [PATCH] Add a framework for flexible options to be passed on the
 command line

Motivation
----------
We want to support backward compat switches and other customizations,
but they'll need to work for extensions as well so it should be
flexible.

Modifications
-------------
Add name/value pair properties which can be passed on the command line,
similar to MSBuild.
---
 src/main/Yardarm.CommandLine/CommonCommand.cs | 20 +++++++++++++------
 src/main/Yardarm.CommandLine/CommonOptions.cs |  3 +++
 .../Yardarm.CommandLine/GenerateCommand.cs    |  2 ++
 .../Yardarm.CommandLine/RestoreCommand.cs     |  2 ++
 src/main/Yardarm/YardarmGenerationSettings.cs |  5 +++++
 5 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/main/Yardarm.CommandLine/CommonCommand.cs b/src/main/Yardarm.CommandLine/CommonCommand.cs
index 93274cd1..c4dc4c67 100644
--- a/src/main/Yardarm.CommandLine/CommonCommand.cs
+++ b/src/main/Yardarm.CommandLine/CommonCommand.cs
@@ -1,14 +1,8 @@
 using System;
-using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.IO;
 using System.Linq;
 using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.OpenApi.Models;
-using Microsoft.OpenApi.Readers;
-using NuGet.Packaging.Core;
 
 namespace Yardarm.CommandLine
 {
@@ -65,5 +59,19 @@ protected virtual void ApplyNuGetSettings(YardarmGenerationSettings settings)
                 settings.TargetFrameworkMonikers = targetFrameworks.ToImmutableArray();
             }
         }
+
+        protected void ApplyProperties(YardarmGenerationSettings settings)
+        {
+            foreach (string property in _options.Properties)
+            {
+                string[] parts = property.Split('=', 2);
+                if (parts.Length != 2)
+                {
+                    throw new ArgumentException($"Invalid property '{property}'. Properties must be in the format 'NAME=VALUE'.");
+                }
+
+                settings.Properties[parts[0]] = parts[1];
+            }
+        }
     }
 }
diff --git a/src/main/Yardarm.CommandLine/CommonOptions.cs b/src/main/Yardarm.CommandLine/CommonOptions.cs
index aea56d52..06e90df7 100644
--- a/src/main/Yardarm.CommandLine/CommonOptions.cs
+++ b/src/main/Yardarm.CommandLine/CommonOptions.cs
@@ -20,5 +20,8 @@ public class CommonOptions
 
         [Option("intermediate-dir", HelpText = "Intermediate output directory")]
         public string IntermediateOutputPath { get; set; }
+
+        [Option('p', "property", Separator = ';', HelpText = "List of property values, separated by semi-colons, in NAME=VALUE format")]
+        public IEnumerable<string> Properties { get; set; }
     }
 }
diff --git a/src/main/Yardarm.CommandLine/GenerateCommand.cs b/src/main/Yardarm.CommandLine/GenerateCommand.cs
index e52e1642..55948856 100644
--- a/src/main/Yardarm.CommandLine/GenerateCommand.cs
+++ b/src/main/Yardarm.CommandLine/GenerateCommand.cs
@@ -62,6 +62,8 @@ public async Task<int> ExecuteAsync(CancellationToken cancellationToken)
 
             ApplyNuGetSettings(settings);
 
+            ApplyProperties(settings);
+
             List<IntermediateStream> streams = await ApplyFileStreamsAsync(settings);
             try
             {
diff --git a/src/main/Yardarm.CommandLine/RestoreCommand.cs b/src/main/Yardarm.CommandLine/RestoreCommand.cs
index f1068d70..35bb60a2 100644
--- a/src/main/Yardarm.CommandLine/RestoreCommand.cs
+++ b/src/main/Yardarm.CommandLine/RestoreCommand.cs
@@ -37,6 +37,8 @@ public async Task<int> ExecuteAsync(CancellationToken cancellationToken)
 
                 ApplyNuGetSettings(settings);
 
+                ApplyProperties(settings);
+
                 settings
                     .AddLogging(builder =>
                     {
diff --git a/src/main/Yardarm/YardarmGenerationSettings.cs b/src/main/Yardarm/YardarmGenerationSettings.cs
index 4f00c9e1..81b55ac9 100644
--- a/src/main/Yardarm/YardarmGenerationSettings.cs
+++ b/src/main/Yardarm/YardarmGenerationSettings.cs
@@ -112,6 +112,11 @@ public Stream XmlDocumentationOutput
         /// </summary>
         public List<string>? ReferencedAssemblies { get; set; }
 
+        /// <summary>
+        /// Properties to alter the behavior of the generation process.
+        /// </summary>
+        public Dictionary<string, string> Properties { get; } = [];
+
         public CSharpCompilationOptions CompilationOptions { get; set; } =
             new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                 .WithDeterministic(true)