Commandline: Verbs included in values

Created on 12 Jan 2018  路  3Comments  路  Source: commandlineparser/commandline

I needed the unbound options for a list of files and I noticed it was including my verb in the IEnumerable<string>. Is there a workaround? Is this intentional behavior?

Most helpful comment

Ah, I see the problem. Verbs only 'activate' if there is more than one generic argument to ParseArguments. With a single generic arg, it is parsed as a standard options class where all CLI arguments are caught up in Files. If you add the following class to the parser, it will parse as you expected (or just add more Verbs relevant to your app).

[Verb(".")]
public class Dummy
{
}
Parser.Default.ParseArguments<AttributeOptions, Dummy>(...)

All 3 comments

Can you post an example of the code you're seeing the issue with?

Options class:

    [Verb("attr", HelpText = "Change file attributes")]
    public class AttributeOptions
    {
        private bool HasOp = false;

        [Option('c', "created", HelpText = "Set creation date", Required = false)]
        private string Created
        {
            get { return CreationDate.ToLongDateString(); }
            set { CreationDate = DateTime.Parse(value); HasOp = true; }
        }
        [Option('m', "modified", HelpText = "Set last modified date", Required = false)]
        private string Modified
        {
            get { return LastModified.ToLongDateString(); }
            set { LastModified = DateTime.Parse(value); HasOp = true; }
        }
        [Option('a', "accessed", HelpText = "Set last accessed date", Required = false)]
        private string Accessed
        {
            get { return LastAccessed.ToLongDateString(); }
            set { LastAccessed = DateTime.Parse(value); HasOp = true; }
        }
        // This was an attempt to fix it that didn't work
        [Value(0)]
        private string verb { get; set; }

        [Value(1)]
        public IEnumerable<string> Files { get; set; }

        public bool HasOperation { get { return HasOp; } }
        public DateTime CreationDate { get; set; }
        public DateTime LastModified { get; set; }
        public DateTime LastAccessed { get; set; }
    }

Relevant part of main code:

        static int Main(string[] args)
        {
            AttributeOptions ao = new AttributeOptions();
            Parser.Default.ParseArguments<AttributeOptions>(args).WithParsed(AttrAction);
            Console.WriteLine("PRESS ANY KEY TO CONTINUE...");
            Console.ReadKey(true);
            return 0;
        }

        static Action<AttributeOptions> AttrAction = new Action<AttributeOptions>(Attr);
        static void Attr(AttributeOptions ao)
        {
            foreach (string file in ao.Files)
            {
                // Without these 2 lines, the verb will show up
                if (file == "attr")
                    continue;
                if (!File.Exists(file))
                {
                    Console.WriteLine("File '" + file + "' does not exist or is not a file");
                    continue;
                }

                if (!ao.HasOperation)
                {
                    Console.WriteLine("    File: " + file);

Ah, I see the problem. Verbs only 'activate' if there is more than one generic argument to ParseArguments. With a single generic arg, it is parsed as a standard options class where all CLI arguments are caught up in Files. If you add the following class to the parser, it will parse as you expected (or just add more Verbs relevant to your app).

[Verb(".")]
public class Dummy
{
}
Parser.Default.ParseArguments<AttributeOptions, Dummy>(...)
Was this page helpful?
0 / 5 - 0 ratings