Coder Social home page Coder Social logo

commandline's People

Contributors

alexanderfast avatar andrecarlucci avatar anthonylangsworth avatar b0urb4k1 avatar billbogaiv avatar bolha7 avatar creepygnome avatar danbowker avatar dbaileychess avatar forki avatar fornever avatar gimmemoore avatar gsscoder avatar hugodahl avatar jafin avatar jeremymeng avatar kraptor23 avatar nayanshah avatar nemec avatar peterpitterling avatar pitterling avatar qmfrederik avatar regme avatar rmunn avatar scadorel avatar sgrassie avatar smbecker avatar thilas avatar txdv avatar zii-dmg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

commandline's Issues

[Public API] inconsistent naming

This is a question that is known to me from earlier versions.

Anyway to be honest I've always postponed. It does not affect functionality. But for me naming is a really important point.

Few (AND IMPORTANT!) class are named:
CommandLineParser
CommandLineParserSettings
and others
ParserState
etc...

So seeing that CLR has no real concept of namespace (they exist only at language level), the parser class is named
CommandLine.CommandLineParser

This could be acceptable if also other follow the same rule (but this is not true); and also internal type are subject to this reasoning.

I'm really considering (and probably I'll do) to removing the repeated CommandLine from type name. So we will have:
CommandLine.Parser
CommandLine.ParserSettings

Impact? This class are named in few parts in a client project (I know this, because I also use my library in my open/closed source project...) -> so impact for me is not a big issue.

Result -> Nothing less that consistent naming!

PS: Why now? I'm projecting new extensions of Public API and I do not want keep a naming defect in new types. So when I'll decide to change, I will have to rename more type (than now).

Opinions?

Problems running xunit tests on Windows 7

I haven't used rake before so this is a great excuse to try it. However, simply running rake in the root folder ends with the following lines. Did I do something wrong?

(in C:/dev/commandline)
packages/xunit.runners.1.9.1/tools/xunit.console.clr4.exe C:/dev/commandline/build/out/CommandLine.Tests.dll
rake aborted!
Command failed with status (1): [packages/xunit.runners.1.9.1/tools/xunit.c...]
C:/Ruby192/lib/ruby/1.9.1/rake.rb:993:in `block in sh'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:1008:in `call'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:1008:in `sh'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:1092:in `sh'
C:/dev/commandline/Rakefile.rb:68:in `block in <top (required)>'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:634:in `call'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:634:in `block in execute'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:629:in `each'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:629:in `execute'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:595:in `block in invoke_with_call_chain'
C:/Ruby192/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:588:in `invoke_with_call_chain'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:605:in `block in invoke_prerequisites'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:602:in `each'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:602:in `invoke_prerequisites'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:594:in `block in invoke_with_call_chain'
C:/Ruby192/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:588:in `invoke_with_call_chain'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:581:in `invoke'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:2041:in `invoke_task'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:2019:in `block (2 levels) in top_level'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:2019:in `each'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:2019:in `block in top_level'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:2058:in `standard_exception_handling'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:2013:in `top_level'
C:/Ruby192/lib/ruby/1.9.1/rake.rb:1992:in `run'
C:/Ruby192/bin/rake:31:in `<main>'

Edit:
It stops on Tests complete: 102 of 161.

Edit2:
I can get it to work by running:

git clean -f
git reset --hard

Clean and rebuild in Visual Studio and manually running:

.\packages\xunit.runners.1.9.1\tools\xunit.console.clr4.exe .\build\out\CommandLine.Tests.dll

All tests are run and pass. But if I ever run just rake it starts failing again and I need to redo the above steps.

PropertyName as default long name

Thank you for sharing us this great library.

I was wondering if OptionAttribute accepts PropertyName as default long name (and also UniqueName) when short name and long name are not available.

It's very convenient if we don't have to provide short name and long name, just use property name as command option name.

Thank you

Immediately Scheduled Public API changes

  1. Take a look at #55
  2. All attributes in CommandLine.Text namespace will be moved to root namespace.
  3. CommandLine.Parser::WasVerbOptionInvoked will be replaced by consistent way of performing the same task (evaluating various option at the moment).

Refactor HelpText and move the errors out of CommandLineOptionsBase

Currently to be able to display the list of errors, it is necessary to extend CommandLineOptionsBase.
It seems that the reason is because the parsing state and errors are stored in that parent class.
Why not move the parser state in a static variable in the CommandLineParser?
Or another option, make the error list as an option of the method with the HelpOption attribute.
And last option, make the GetUsage(...) method as an option of ParseArguments
My issue with extending CommandLineOptionsBase is that it requires to propagate the assembly everywhere.

[announcement] source splitting milestone

After spleeping on (and some research) I finally came to conclusion that source inclusion will not be impaired by multiple file splitting (exactly one file per type, java-like).

I'll arrange the project to be included in others using git submodules (or equivalent technologies of other source version control systems).

This will be done today 10 Jan (local time at moment of writing this post 13:47 PM).

So please do not submit pull requests until next commit.

Regards,
Giacomo

Removing main side effects from public interface (Parser type)

As you seen with latest release a lot was done to simplify the library.

Don't get me wrong, I'll not change basic concepts of the API; but I'd like to embrace good design from functional world for make our library strongest.

When you declare the options type:

var options = new Options();

options is in state X (initialized) and after

var result = new Parser().ParseArguments(args, options);

options is in state Y (with parsed values)

So we can say that ParseArguments caused side effects. Another one, is the result (also influenced by the same function... opssss method!).

Incredibly the solution is quite easy:

T Parser.ParseArguments<T>(string[] args, Action onFail)

The method with this new signature constructs the instance and returns it.

  • If parsing succeed, the instance is loaded with parsed values.
  • If parsing fails and ParserStateAttribute is used, the generic errors list will be available as always.

But if parsing fails an appropriate delegate (Action onFail) is called.

Other advantages: convergence of standard methods with strict methods (@nemec suggested feature).

Functional paradigms proves their effectiveness from '70 (and before), please dig into the argument if not convinced. :))

As always, opinions (or flames) are welcome.

PS:
Some side effects for the moment will remain. E.g.: printing out the help. As said, I'm moving to a removing the most evident of these.

[Survey] fluent builder

The CommandLineParser is an instance created used and (hopefully) discarded by Garbage Collector. After first call (except in plugin scenario) there's no reason for call ParseArguments again.

In favor of readability I'm wondering if a fluent builder can live side by side (or replace?) CommandLineParserSettings.

Pseudocode:

var parser = new CommandLineBuilder()
  .WriteHelpTo(Console.Error)
  .IsCaseSensitive()
  .IsMutuallyExclusive()
  .IgnoreUnknownArguments().Build()
parser.ParseArguments(args); // or chaining also this call, if you want

Opinions?

Double-dash to force value-list.

In typical command line parsers, using a double-dash as a token (eg. git add -- -u nothing) forces all tokens after the -- to be read as values (equivalent to what's stored in your ValueList), even though -u is otherwise a valid commandline flag. This allows, for instance, files starting with a dash to be added to a git repository.

Passing 'long' to 'int' options raises unhandled overflow exceptions

Basically, I created an option that accept a integer. When I pass a long to it and I try to parse it, it generates an overflow exception. I'm not sure if I should handle it on my side but the example giving leads me to think that it should be done by the parser.

Here are some sample code.

public class Options : CommandLineOptionsBase
{
[Option("i", "Identification", Required = true, HelpText = "Some Id.")]
public int Identification { get; set; }
}

public static void Main(string[] args)
{
var options = new Options();

// crash here
if (!CommandLineParser.Default.ParseArguments(args, options))
{
Environment.Exit(-1);
}

Get error for unknown options

When calling a program with an option that isn't specified, the general usage information is rendered, but no indication on what went wrong is shown. Also there is no information on the error in the IParserState. It would be very useful to be able to get information on the error.

Also see http://stackoverflow.com/q/15189849/66849

Coordinate PULL REQUESTs

Dear actual or future contributors,
due to deep changes to command line parser kernel, I'm not able to accept PR without previous coordination.

This is true for both master and devel-* branch.

This is a general good rule, but in this case is a key necessity.

PR are always welcome, but when there are such ongoing change -> merging could be difficult (or impossible) and so coordination is required.

Hope this don't stop you from sending PR.

develop-* branch:

  • Even if some good refactoring occured in that branch, my attempt to transform the kernel in something new ended up in over-engineering when solving old code smells created new code smells (there's nothing to hide, this is the truth).
  • I'm drafting the new kernel outside the project repo for explore new possibilities. Expect this work to become master ASAP.

Giacomo Stelluti Scala

PS: this guide helped me, but don't take the title as statement of mine (http://goo.gl/xJFE1) -> read it!

AddPreOptionsLine() incorrectly wrapping when adding multi-line string (like in the wiki example "Handling Parsing Errors")

Using the sample code in https://github.com/gsscoder/commandline/wiki/Display-A-Help-Screen section "Handling Parsing Errors" to print errors:

RenderParsingErrorsText() returns a string with linebreaks if there are multiple errors. When passed to Add<>OptionsLine, it is wrapped every 80 characters regardless of newlines, causing incorrect wrapping.

[ParserState]
public IParserState LastParserState { get; set; }

[Option('a', "qwe", Required = true)]
public string a { get; set; }

[Option('b', "asd", Required = true)]
public double b { get; set; }

[Option('c', "zxc", Required = true)]
public bool c { get; set; }

[HelpOption]
public string GetUsage()
{
    var help = new HelpText();
    // ...
    if (this.LastParserState.Errors.Count > 0)
    {
        var errors = help.RenderParsingErrorsText(this, 2); // indent with two spaces
        if (!string.IsNullOrEmpty(errors))
        {
            help.AddPreOptionsLine(string.Concat("\n", "ERROR(S):"));
            help.AddPreOptionsLine(errors);
        }
    }
    // ...
    return help;

}
>foo.exe

ERROR(S):
  -a/--qwe required option is missing.
  -b/--asd required option is 
missing.
  -c/--zxc required option is missing.

As you can see, the second error line gets incorrectly wrapped.

Possibility to make an "option group" where the user has to use exactly one of the options in the group

When creating an application that has a group of options of which one must be given and only one of them can be given at a time, there is currently no way to do that. MutuallyExclusiveSet and Required can't be used together.

Example: I have an application where the user either can process files using
MyApp --files myfile.txt
or get a list of possible languages to use to process the files
MyApp --list-languages
or get a list of available plugins
MyApp --list-plugins
etc

Using more than one option or none of them would render an error.

A verb based approach could solve it, but seems wrong since the applications only real command is to process files and the rest of the command would just be some sort of help commands.

The Plossum Command Line Parser is using the notion of OptionGroups, where a group can have a setting of:

  • None
    This is the default, and it means that no restrictions are placed on the options in this group (other than those explicitly specified for each option)
  • AtMostOne
    This indicates that at most one of the options contained within this group must be specified. It means that either none of the options in the group, or one of the options in the group may be specified, but no more.
  • AtLeastOne
    This indicates that at least one of the options contained within this group must be specified, i.e. one or more options from this group must be specified.
  • ExactlyOne
    This indicates that exactly one option from this group must be specified, no more and no less.
  • All
    Indicates that all options from this group must be specified on the command line.

This would be a good way to solve it IMO.

Another alternative I can think of - off the top of my head - would be to allow MutuallyExclusiveSet and Required to be combined. An option with Required would then cause it's MutuallyExclusiveSet to be required instead of the option.

A stackoverflow question on this issue is posted here.

Two consecutive Arrays causes second one not to be read

    [Option("s", "source", Required = true, HelpText = "Source Word2007+ document path")]
    public string SourceDocument { get; set; }

    [Option("o", "output", Required = true, HelpText = "Output Excel2007+ spreadsheet path")]
    public string OutputSpreadsheet { get; set; }

    [OptionArray("h", "headers", Required = true, HelpText = "List of coords to cells with headers")]
    public uint[] Headers { get; set; }

    [OptionArray("c", "content", Required = true, HelpText = "List of coords to cells with content")]
    public uint[] Content { get; set; }

    [Option("v", "verbose", Required = false, DefaultValue = false, HelpText = "Print details during execution")]
    public bool Verbose { get; set; }

app.exe --source d:/document.docx --output d:/document.xlsx --headers 0 1 1 1 --content 0 2 1 2 --verbose

.NET 4.0, Windows 7, C# Express 2010

Option with auto long name lacks name with AutoBuild.

While performing some tests about how looks using the current development version of CommandLine with FSharp, I've found an issue that also the current stable has.

If someone is curious the gist is here.

Unfortunately the development branch now diverges too much from the stable and time lacks to work on two different versions.

The good news is that all (and more) tests of the development branch are green, the public API should not change (expect for some refactoring to simplify HelpText); so it will merged as soon to the master branch.

If you can't way, you will know when the issue is fixed in the development branch -> clone it -> compile and use it.

For reference (but remember API is even simplified and still not documented - but I can help if you write me): https://github.com/gsscoder/commandline/tree/develop-1.9.8-beta

Have nice day!

Option to explicitly set a bool to false

to follow up on a twitter conversation with @gsscoder

There are times when it could be useful to have a boolean argument that allows the user to override default behavior by explicitly setting the value to false.

For instance:

[Option('r', "recursive", DefaultValue = true, HelpText = "Recurse through subdirectories.")]
public bool Recursive { get; set; }}}

but this doesn't work:

> myapp -r false

still sets Recursive to true.

(I get this is non-standard now)

I can see this getting closed as 'won't do'.

But I did want to record it in more than 140 characters in case any one else sees the value or logic in allowing for this type of behavior.

Survey for adding an AutoBuild(...) to the Parser

@nemec, strict parsing (suggested by you) led me to think that CoC (convention over configuration) is gaining consensus between developers (see ASP.NET MVC, see Grails in Java World etc).

What about something like this:

bool result = CommandLineParser.AutoParse(); // or CommandLineParser.Default.AutoParse() ???

Inside the method calls Environment.GetArgs() and inspect the assembly for a type marked with an attribute (or by naming convention), say

[ParserTarget] // <- maybe marking also the class is more explicit
class Options {
  // everything as usual here...
  [ParserTarget] // <- maybe the lib could use just this attr to discover the options type
  public static Options Instance {get; set;}
}

When ::AutoParse() returns (and if returns) true product of parsing will be dressed up into Options::Instance static member.

Opinions? (Everyone invited).

CopyrightInfo grows with each call to ToString()

The StringBuilder inside CopyrightInfo is reused and never reset. The reproducing code is very simple:

class Program
{
    static void Main(string[] args)
    {
        var copyrightInfo = new CopyrightInfo("TheAuthor", 2012);
        int len1 = copyrightInfo.ToString().Length; // 28
        int len2 = copyrightInfo.ToString().Length; // 56
    }
}

Split up the project into multiple source files

Due to nemec's off topic vote to split the source files I hereby register the official request. His words are better than mine:

Now that the project has a NuGet package, no one should be adding the .cs file manually to a project. If anything, the .nupkg file is a single file and just as easy to include in a project as a binary while leaving the source easy to navigate in multiple files.

The initial response from gsscoder was:

These day I was reasoning over the question of splitting source in more files. For development is better use a splitted source while for deployment I prefer one or two files.

I'd argue that this GitHub repository is mainly for development, rather than deployment, hence multiple source files should be used.

Verb GetUsage from wiki fails

Currently implementing verb support in my project (great fun), ran across a problem when generating the help text. The GetUsage method is from the wiki, am I missing something?

internal class MyVerbs
{
    internal class FooOptions
    {
        [Option("bar", HelpText = "bar help")]
        string Bar { get; set; }
    }

    [VerbOption("foo", HelpText = "foo help")]
    public FooOptions Foo { get; set; }

    // this code taken from the wiki
    [HelpVerbOption]
    public string GetUsage(string verb)
    {
        bool found;
        var instance = CommandLineParser.GetVerbOptionsInstanceByName(
            verb, this, out found);
        var verbsIndex = verb == null || !found;
        var target = verbsIndex ? this : instance;

        // found is true but instance is null,
        // throws ArgumentNullException
        return HelpText.AutoBuild(
            target,
            current => HelpText.DefaultParsingErrorsHandler(target, current),
            verbsIndex);
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        MyVerbs verbs = new MyVerbs();
        args = "help foo".Split();
        CommandLineParser.Default.ParseArguments(args, verbs);
    }
}

Passing filenames that contain spaces

Hi,

I was wondering what was the best way to pass arguments that may contain spaces (especially filenames).

I think most command line apps will support quoting filenames to work around the space issue. For example, on Windows the following command will create 2 directories, Test and 1:

mkdir Test 1

Whereas the following will create 1 directory named Test 1:

mkdir "Test 1"

This is supported by most commands that deal with files.

I may be missing something but I haven't seen such support in the CommandLine library?
The best I could come up with was using an OptionList or ValueList, joining the parts back together and possibly stripping the quotes, but it can get quite complex when you consider that this should also be supported:

mkdir "Test 1" "Test 2"

What are your thoughts on this? If you were interested in supporting this and wanted to point me in the right direction I might be able to implement it and submit a patch.

Cheers
Xavier

CommandLineParser.cs refactoring & InternalsVisibleTo

As you can see these days I've started some refactoring.

The problem is that verb additions made CommandLineParser grow and I feel that code must be internally reorganized in order to promote an easier extension (and easier contributions too).
Even with verb addition this class is grown too much.

I'm evaluating various options to decoupling internal parts. Opinions as always are wellcome.

Another thing,
I'd like to reference CommandLine.dll rather than including sources in CommandLine.Tests.dll.

I'v generated the public key from snk file. Copied it to InternalsVisibleTo but the framework still not match the assembly. Maybe this is an issue concerning the FullName (culture etc).

If anyone can help on this point, I can proceed with refactoring.

Expose read-only property on attributes derived from MultiLineTextAttribute

Would be great - for those of us making our own usage formats - to expose a read-only property that returns a string of the multi-line text.

I think this impacts AssemblyLicenseAttribute and AssemblyUsageAttribute which are both derived from MultiLineTextAttribute.

My thought was add a virtual property to MultiLineTextAttribute called 'Value'. Could be overriden in derived class if needed. If not, the default behavior simply concatenates all non-blank lines with Environment.NewLine.

Come to think of it, maybe I'll issue a pull request with the desired behavior.

Reducing public surface of CommandLine.IParser

My current level of skill / knowledge disagree that this interface (and main implementation CommandLine.Parser) exposes so much overloads.

I'm thinking to reduce with this philosophy:

  • Prefer constructor (both settings instance / lambda config) to specify preferences.
  • Provide flexible alternatives over redundancy.

Few examples:

You know that if you set an TextWriter for help output in settings, you can override the value with this overload?
bool ParseArguments(string[] args, object options, TextWriter helpWriter)

I'm sorry but mr. overload, I think I'm gonna kill you! :D

And all ParseArgumentStrict(...) can be reduced to:

bool ParseArgumentsStrict(string[] args, object options, Action onFail = null);

I'm quite to near to next RC0, so opinions are welcome. Support me or try to make me change idea...

String or characters?

I got an exception during the parsing step. After some debugging, I finally found that the error was that I used 2-letter strings for the short name of my options. This made me wonder why a string was used for the "ShortName" instead of a char. It seems not consistent with the fact that for the separator character in an OptionList, one really uses a character.

Parser does not display an error when we specify an argument without its value

If I have a option as follow

[Option("z", "zzz")]
public int Test { get; set; }

[HelpOption]
public string GetUsage()
{
return HelpText.AutoBuild(this, current => HelpText.DefaultParsingErrorsHandler(this, current));
}*

And I call my executable as follow (without specifying the value to the argument z)

sample.exe -z

It would correctly detect that something wrong happenned but it does not display any error. It would simply display the help text.

CultureAttribute for interpreting culture specific input

Dear gsscoder,

Command line parser uses the culture setting of the hosting process to interpret input and set property values of option class. The data feed from command line might not match the culture of the process hosting parser. In the worst case, the hosting process doesn't know which culture is used to format the input it is interpreting. It means that the hosting process cannot adapt to input culture by altering Thread.CurrentThread.CurrentCulture before calling CommandLine.CommandLineParser.ParseArguments.

So, I propose a special CultureAttribute to be implemented. The idea is that programmer can decorate one property of the option class with CultureAttribute. The parser should interpret input with culture specified via command line. An example of option class property with a new CultureAttribute attribute:

[Culture('c', "culture", MetaValue = "NAME", DefaultValue = "en-US", HelpText = "Specify which culture NAME is used to interpret command line options.")]
public System.Globalization.CultureInfo Culture { get; set; }

As a result, app.exe can be called with input formatted in multiple ways:

app.exe --culture en-US --value 1023.45
app.exe --culture fi-FI --value "1 234,45"

I suggest that CultureAttribute attribute should understand culture names known by CreateSpecificCulture method of CultureInfo class. For more information, look at:

http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.createspecificculture.aspx

Parser should change Thread.CurrentThread.CurrentCulture if CultureAttribute attribute has Permanent property (defaults to false) switched on. Otherwise, culture setting should affect input parsing only.

This is my weak attempt to describe what CultureAttribute might look like:

/// <summary>
/// Models an culture specification.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class CultureAttribute : BaseOptionAttribute
{
    /// <summary>
    /// Initializes a new instance of the <see cref="CommandLine.CultureAttribute"/> class.
    /// </summary>
    /// <param name="shortName">The short name of the culture option..</param>
    public CultureAttribute(char shortName)
        : base(shortName, null)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="CommandLine.CultureAttribute"/> class.
    /// </summary>
    /// <param name="longName">The long name of the culture option.</param>
    public CultureAttribute(string longName)
        : base(null, longName)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="CommandLine.CultureAttribute"/> class.
    /// </summary>
    /// <param name="shortName">The short name of the culture option.</param>
    /// <param name="longName">The long name of the culture option or null if not used.</param>
    public CultureAttribute(char shortName, string longName)
        : base(shortName, longName)
    {
    }

    /// <summary>
    /// Gets or sets the persistence mode of the culture setting.
    /// </summary>
    public bool Permanent { get; set; }

    /// <summary>
    /// Helper factory method for testing purpose.
    /// </summary>
    internal OptionInfo CreateOptionInfo()
    {
        return new OptionInfo(base.ShortName, base.LongName);
    }
}

Thanks for your devotion to this library. It has helped me a lot!

Kind regards,
Olli-Pekka Isola

How about support for verbs/commands?

Hi.

I like this library a lot! But one thing I'm missing is support for "verbs". Like when the first argument on command line is a verb which then has options specific to that verb. Similar to git commit -m "message".

I put the code below together as a proof of concept. Though, looking at it now I think I would have preferred to have the Option attribute assigned to parameters of the method instead of a dedicated class, but that would require some more intrusive changes. Is this something you would be interested in exploring or is totally out of scope for this library?

using System;
using System.Linq;
using System.Reflection;

using CommandLine;

namespace SampleApp
{
    public class VerbProgram
    {
        private static void Main(string[] args)
        {
            //MyVerbs.FooOptions options = new MyVerbs.FooOptions();
            //if (!CommandLineParser.Default.ParseArguments(
            //    new[] { "--flag" }, options))
            //{
            //    Environment.Exit(1);
            //}

            MyVerbs verbs = new MyVerbs();
            if (!VerbParser.Default.ParseArguments(
                new[] { "foo", "--flag" }, verbs))
            {
                Environment.Exit(1);
            }

            Environment.Exit(0);
        }
    }

    internal class MyVerbs
    {
        internal class FooOptions : CommandLineOptionsBase
        {
            [Option("f", "flag", Required = true)]
            public bool Flag { get; set; }
        }

        [Verb]
        public void Foo(FooOptions options)
        {
            Console.WriteLine(options.Flag);
        }
    }

    public class VerbAttribute : Attribute
    {
        /// <summary>
        /// By default the name of the verb is a lowercase version of the
        /// method name, set this property to override.
        /// </summary>
        public string Name { get; set; }

        public string HelpText { get; set; }
    }

    internal class VerbParser
    {
        public static VerbParser Default = new VerbParser();
        internal ICommandLineParser ArgumentParser = CommandLineParser.Default;

        public bool ParseArguments(string[] args, object verbs)
        {
            // store name of verb and remove it from args
            var verbName = args[0];
            args = args.Skip(1).ToArray();

            // find verb method
            Pair<MethodInfo, VerbAttribute> verb = null;
            foreach (Pair<MethodInfo, VerbAttribute> pair in
                ReflectionUtil.RetrieveMethods<VerbAttribute>(verbs))
            {
                string name = pair.Right.Name;
                if (string.IsNullOrEmpty(name))
                {
                    name = pair.Left.Name.ToLower();
                }
                if (verbName.Equals(name))
                {
                    verb = pair;
                    break;
                }
            }
            if (verb == null)
            {
                return false; // verb not found
            }

            object options = Activator.CreateInstance(
                verb.Left.GetParameters()[0].ParameterType);
            if (!ArgumentParser.ParseArguments(args, options))
            {
                return false; // couldnt parse verb arguments
            }

            verb.Left.Invoke(verbs, new[] {options});
            return true;
        }
    }
}

Negative values for numeric inputs are not supported

It looks like this could be fixed by adding an IsNumeric method in CommandLine.cs and calling it in the following places:

public static ArgumentParser Create(string argument, bool ignoreUnknownArguments = false)
{
if (IsNumeric(argument))
return null;
...

public static bool IsInputValue(string argument)
{
if (IsNumeric(argument))
return true;
...

Probable bug in StringExt.Wrap

Resharper tells me that the 'first' variable is never changed from its default true value therefore the code in the then block in the for/next loop will never be executed.

Actually, looks like the condition should be "if (first)" not "if (!first)"

Cheers
Simon

HelpText.AutoBuild reports the wrong application name/version

When using HelpText.AutoBuild, instead of the application name and version specified in AssemblyInfo.cs, I always get CommandLine 1.9.2.4

Using VS 2010, in C#; Options class subclasses CommandLineOptionsBase. In my Main method I tried either instantiating a CommandLineParser or using CommandLineParser.Default; both doesn't make any difference.

Option to parse option without any switch (position based)

If you look at the (for instance) man page for grep, you'll see something like:

grep [OPTIONS] PATTERN [FILE...]

So, [OPTIONS] are what the library currently parse without a problem, however how to define required or optional parameters without a switch at the beginning or end (like PATTERN or [FILE...] here)? Naturally, one can preprocess the string, splice it and then pass to the library, but why not have it out of the box? :) It would be cool to define them in attributes in a way like "first", "first after options" or something similar. What do you think? Or maybe there is such an option and I missed it.

ReSharper code style

It seems you format your code with ReSharper (which is great!) could you commit the code style to the repository so I don't have to match it by hand?

In Visual Studio: ReSharper -> Options -> Code Style Sharing

announcement: working on next beta started

The next Beta will break some public API compatibility (nothing drastic!), for this reason the version will jump to 1.9.4.9* increasing until will reach first 1.9.5.0 Stable.

But you are not interested in my version naming policies, right?

All new and "unfixed" issues will be taken into account for this new release.

So please don't expect pull-requests made on 1.9.3.* to be merged: I can't keep more branches active on this project. Anyway don't stop posting! Good ideas will be incorporated if possible in 1.9.4.9* Beta.
Please be patient if some good pull request were not merged, but consider also that sometime is more simple to me fix something by description that solve source code conflicts.

Anyway thanks everyone, for interest in this library. Your collaboration made it better!

Regards,
Giacomo Stelluti Scala

empty OptionList doesn't show error

I just started using this library, so forgive me if this is stupid request:

When an empty option list is parsed, shouldn't a format error be added to the PostParsingState? As I'm sure you know, It would be a one line change to add

DefineOptionThatViolatesFormat(option);

to the block that tests whether the option is empty. (OptionGroupParser.cs L54)

e.g.

class Options
{
   [OptionList('d', "date-range", Separator = ':')]
   public List<string> DateRange { get; set; }
}
>foo.exe -d

   -d/--date-range option violates format

>

[Enhancement] Default parser, strict parsing.

I'd like for there to be a method on at least the default parser that, if parsing fails, it automatically displays the help screen (or generate one automatically, if there is no defined help), then quit (eg. Environment.Exit(1)). It's a common enough process that I think it deserves its own method.

HelpText in resources

I would like to be able to specify the HelpText for an Option in a Resources.resx file.

I'm trying to keep my code shorter than 80 characters and reflowing the helptext is cumbersome (but its great that the lib reflows them on output). Also being able to localize the help text is a nice bonus.

Read options from Environment variables

Looks like you might have the best command line parser for .NET.

The one thing I see missing however (and maybe I just overlooked it), is the ability to map command line switches to environment variables.

If you have decoupled build from deployment, with a tool like Capistrano and intend to run with a Procfile on Linux (in our case, exported to Upstart), then it's pretty standard to config the application via environment variables. So rather than pass options through command line or .config files... we export some environment variables during deployment.

Have you given this any thought? It would be very useful to us.

Thanks!

Incorrect behaviour with short and long command name

Good day, developer team!

Using last version of CommandLineParser library I found incorrect library behaviour. When I pass next parameters
-read ReadFileName
your library consider -read argument as -r command with ead parameter.
I am using test project from "demo" folder. Looks like in parsing process CommandLineParser process on first short option name, and than process long option name.

I attached screenshot. You can view parsing result in Watch 1 window.
CommandLineParser

Handling of unknown options when using VerbOptions

Hi, I'm using the latest beta so that I can use VerbOptions. It appears that if I start my command line arguments with the name of a valid VerbOption and then follow that VerbOption with an unknown argument I do not get a parser error (e.g. an extraneous character surrounded by spaces such as in "myapp doit x -y" where x is not a valid option for the "doit" verb but -y is).

It seems that an "else" clause is needed in Parser.cs at line 213 in the DoParseArgumentsCore method. Like so:

// this handles when an unknown entry is present in the command line after a valid verboption
else
{
hadError = true;
}

Thanks

Inconsistent line endings

Downloading master.zip (to rule out that git does something) and checking line endings in Notepad++, it considers CommandLine.cs to have Windows eol and CommandLineText.cs to have Unix eol. It would be nice if they were the same.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.