Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose registered command metadata #1571

Open
rmannibucau opened this issue Jun 19, 2024 · 3 comments
Open

Expose registered command metadata #1571

rmannibucau opened this issue Jun 19, 2024 · 3 comments

Comments

@rmannibucau
Copy link

Is your feature request related to a problem? Please describe.
I'm generating documentation from the CommandApp but it requires reflection which shouldn't be IMHO.

Side note: it can apply to completion implementation/generation (bash script) too.

Describe the solution you'd like
CommandApp should expose ConfiguredCommand somehow.

Describe alternatives you've considered

Reflection (the dynamic usage is really bothering for ex):

               var configuratorField = typeof(CommandApp).GetMember("_configurator", BindingFlags.NonPublic | BindingFlags.Instance)[0]!;
                var configurator = (configuratorField as FieldInfo)!.GetValue(app)!;
                var commands = (configurator.GetType().GetProperty("Commands")!.GetValue(configurator)! as IList)!;
                if (commands.Count == 0)
                {
                    throw new ArgumentException("No command found", nameof(app));
                }
                var commandProps = commands[0]!.GetType().GetProperties()
                    .Where(it => it.Name == "Name" || it.Name == "Description" || it.Name == "IsHidden" || it.Name == "SettingsType")
                    .ToDictionary(it => it.Name, it => it);

                var commandModels = new List<dynamic/* happy to get a better option there */>();
                foreach (var cmd in commands)
                {
                    var item = new // simplified view
                    {
                        Name = commandProps["Name"].GetValue(cmd) as string,
                        Description = commandProps["Description"].GetValue(cmd) as string,
                        IsHidden = commandProps["IsHidden"].GetValue(cmd) as bool?,
                        SettingsType = commandProps["SettingsType"].GetValue(cmd) as Type,
                    };
                    if (item.IsHidden is not true)
                    {
                        commandModels.Add(item);
                    }
                }

Please upvote 👍 this issue if you are interested in it.

@phil-scott-78
Copy link
Contributor

phil-scott-78 commented Jun 19, 2024

Try running your app with the options cli xmldoc. I suspect that'll get you the info you are looking for

@rmannibucau
Copy link
Author

rmannibucau commented Jun 19, 2024

@phil-scott-78 I think I get what you have in mind but my request is to get CommandInfo (or another pivot model) directly from the CommandApp to avoid the dump/parsing round trip when possible and ease consumption.
Ideally a app.Commands (IEnumerable or IList) would be awesome and it is there in the internals.

Hope it makes sense

edit: is it intended it misses DefaultValue - was using it in previous code?

@rmannibucau
Copy link
Author

rmannibucau commented Jun 19, 2024

Created #1572 to fix the missing info, then following model:

    [XmlRoot(ElementName = "Model")]
    public class XmlDocModel
    {
        [XmlElement(ElementName = "Command")] public List<XmlCommand>? Command { get; set; }
    }

    public class XmlOption
    {
        [XmlAttribute("ClrType")] public string? ClrType { get; set; }

        [XmlElement("DefaultValue")] public string? DefaultValue { get; set; }
        [XmlElement("Description")] public string? Description { get; set; }

        [XmlAttribute("Kind")] public string? Kind { get; set; }

        [XmlAttribute("Long")] public string? Long { get; set; }

        [XmlAttribute("Required")] public bool Required { get; set; }

        [XmlAttribute("Short")] public string? Short { get; set; }

        [XmlAttribute("Value")] public string? Value { get; set; }
    }

    public class XmlCommand
    {
        [XmlElement("ClrType")] public string? ClrType { get; set; }

        [XmlElement("Description")] public string? Description { get; set; }
        [XmlElement("IsBranch")] public bool? IsBranch { get; set; }

        [XmlAttribute("Name")] public string? Name { get; set; }

        [XmlArray("Parameters")][XmlArrayItem("Option")] public List<XmlOption>? Parameters { get; set; }

        [XmlElement("Settings")] public string? Settings { get; set; }
    }

should be sufficient to use var model = (XmlDocModel)new XmlSerializer(typeof(XmlDocModel)).Deserialize(reader)!;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo 🕑
Development

No branches or pull requests

2 participants