Tools parameters settings from attributes
- Dominant language
- C#
- Stars
- 4.2k
- Forks
- 778
- Avg merge
- 1h 15m
- Merged PRs (30d)
- 19
Description
## Suggestion:
Right now for tool the settings are converted to the command line arguments manually which seems to me a bit awkward.
I had an idea to use attributes on the settings classes properties that will contain metadata on how each property should be handled - similar to how Powershell function work.
*not sure if it would be possible to use the powershell attributes directly*
for example:
````csharp
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public abstract class CakeToolParameterAttribute : Attribute
{
public CakeToolParameterAttribute(string template)
{
Template = template ?? throw new ArgumentNullException(nameof(template));
}
public string Template { get; }
public abstract string Render(object property, PropertyInfo info);
}
````
For properties that are represented as `-X=Y` or similar the template property will be something like `-X={0}`.
for switch parameters:
````csharp
public sealed class SwitchParameterAttribute : CakeToolParameterAttribute
{
public SwitchParameterAttribute(string template) : base(template)
{
}
public override string Render(object property, PropertyInfo info)
{
if (info.GetValue(property) is bool flag && flag)
{
return Template;
}
return string.Empty;
}
}
````
for collection parameters:
````csharp
public sealed class CollectionParameterAttribute : CakeToolParameterAttribute
{
public CollectionParameterAttribute(string template) : base(template)
{
}
public int? Min { get; set; }
public int? Max { get; set; }
public override string Render(object property, PropertyInfo info)
{
var items = (info.GetValue(property) as IEnumerable)?.Cast()?.ToArray();
if (items == null)
{
throw new ArgumentException("property is invalid, must be a collection.");
}
if (Min.HasValue && items.Length < Min)
{
throw new ArgumentOutOfRangeException($"must have at least {Min} items. found {items.Length}");
}
if (Max.HasValue && items.Length > Max)
{
throw new ArgumentOutOfRangeException($"must have at most {Max} items. found {items.Length}");
}
if (!Template.Contains("{0}"))
{
throw new FormatException("The template must contain a placeholder {0}");
}
return string.Join(" ", items.Select(item => string.Format(Template, item.ToString().Quote())));
}
}
````
This will improve the generated docs by listing next to each property it's template
Tested a small POC - https://github.com/Meir017/Playground/blob/master/cake-tool-settings-attributes.cs
any thoughts?
Contributor guide
Research direction
Start by locating Cake's current manual conversion of tool settings into command-line arguments, then compare it with the linked POC. Define the attribute and rendering design, including validation and generated documentation, before implementing and testing the approach.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- cli, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100