├── .gitignore
├── Beverage
├── Beverage.csproj
├── Commands
│ ├── BlackRussian.cs
│ ├── Martini.cs
│ └── WhiteRussian.cs
└── Program.cs
├── Beverage_old
├── App.config
├── Beverage.csproj
├── Commands
│ ├── BlackRussian.cs
│ ├── Martini.cs
│ └── WhiteRussian.cs
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── CHANGELOG.md
├── GoCommando.Tests
├── GoCommando.Tests.csproj
├── TestArgParser.cs
└── TestCommand.cs
├── GoCommando.Tests_old
├── GoCommando.Tests.csproj
├── Properties
│ └── AssemblyInfo.cs
├── TestArgParser.cs
├── TestCommand.cs
└── packages.config
├── GoCommando.sln
├── GoCommando
├── BannerAttribute.cs
├── CommandAttribute.cs
├── DescriptionAttribute.cs
├── ExampleAttribute.cs
├── ExitCodeException.cs
├── Go.cs
├── GoCommando.csproj
├── GoCommandoException.cs
├── ICommand.cs
├── ICommandFactory.cs
├── Internals
│ ├── Arguments.cs
│ ├── CommandInvoker.cs
│ ├── EnvironmentSettings.cs
│ ├── InternalsVisibleTo.cs
│ ├── Parameter.cs
│ ├── Settings.cs
│ ├── StringExtensions.cs
│ └── Switch.cs
├── ParameterAttribute.cs
└── SupportImpersonationAttribute.cs
├── GoCommando_old
├── BannerAttribute.cs
├── CommandAttribute.cs
├── DescriptionAttribute.cs
├── ExampleAttribute.cs
├── ExitCodeException.cs
├── Go.cs
├── GoCommando.csproj
├── GoCommandoException.cs
├── ICommand.cs
├── ICommandFactory.cs
├── Internals
│ ├── Arguments.cs
│ ├── CommandInvoker.cs
│ ├── EnvironmentSettings.cs
│ ├── Parameter.cs
│ ├── Settings.cs
│ ├── StringExtensions.cs
│ └── Switch.cs
├── ParameterAttribute.cs
├── Properties
│ └── AssemblyInfo.cs
└── SupportImpersonationAttribute.cs
├── Package.nuspec
├── README.md
├── TestApp2_old
├── App.config
├── ElCommandante.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── TestApp2.csproj
├── TestApp_old
├── App.config
├── Commands
│ ├── NewCommand.cs
│ ├── RunCommand.cs
│ ├── StopCommand.cs
│ └── TestAppConfigBinding.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── TestApp.csproj
├── build.cmd
├── nuget
└── NuGet.exe
├── old
├── .gitignore
├── Package.nuspec
├── README.md
├── build.bat
├── lib
│ ├── nunit
│ │ └── nunit.framework.dll
│ └── rhino
│ │ ├── Rhino.Mocks.dll
│ │ └── Rhino.Mocks.xml
├── scripts
│ └── build.proj
├── src
│ ├── GoCommando.ConsoleApplication
│ │ ├── GoCommando.ConsoleApplication.csproj
│ │ ├── Program.cs
│ │ └── Properties
│ │ │ └── AssemblyInfo.cs
│ ├── GoCommando.Tests
│ │ ├── FixtureBase.cs
│ │ ├── GoCommando.Tests.csproj
│ │ ├── Helpers
│ │ │ ├── TestArgParser.cs
│ │ │ ├── TestBinder.cs
│ │ │ └── TestHelper.cs
│ │ ├── Integration
│ │ │ └── ErrorTestCases.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ └── todo.txt
│ ├── GoCommando.sln
│ └── GoCommando
│ │ ├── Api
│ │ └── ICommando.cs
│ │ ├── ArgumentAttribute.cs
│ │ ├── Attributes
│ │ ├── ArgumentAttribute.cs
│ │ ├── BannerAttribute.cs
│ │ ├── DescriptionAttribute.cs
│ │ ├── ExampleAttribute.cs
│ │ ├── NamedArgumentAttribute.cs
│ │ └── PositionalArgumentAttribute.cs
│ │ ├── BannerAttribute.cs
│ │ ├── CommandLineParameter.cs
│ │ ├── Exceptions
│ │ └── CommandoException.cs
│ │ ├── Extensions
│ │ └── AttributeExtensions.cs
│ │ ├── Go.cs
│ │ ├── GoCommando.cs
│ │ ├── GoCommando.csproj
│ │ ├── GoCommando.nuspec
│ │ ├── Helpers
│ │ ├── ArgParser.cs
│ │ ├── Binder.cs
│ │ ├── BindingReport.cs
│ │ ├── Helper.cs
│ │ ├── IHasPositionerCounter.cs
│ │ └── Parameter.cs
│ │ ├── IGoCommando.cs
│ │ ├── NamedArgumentAttribute.cs
│ │ ├── NamedCommandLineParameter.cs
│ │ ├── NamedFlagCommandLineParameter.cs
│ │ ├── Parameters
│ │ ├── CommandLineParameter.cs
│ │ ├── NamedCommandLineParameter.cs
│ │ └── PositionalCommandLineParameter.cs
│ │ ├── PositionalArgumentAttribute.cs
│ │ ├── PositionalCommandLineParameter.cs
│ │ └── Properties
│ │ └── AssemblyInfo.cs
└── tools
│ └── NuGet.exe
├── packages
└── NUnit.2.6.4
│ ├── NUnit.2.6.4.nupkg
│ ├── lib
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
│ └── license.txt
├── scripts
├── build.cmd
├── patch_assemblyinfo.cmd
├── push.cmd
└── release.cmd
└── tools
└── NuGet
└── nuget.exe
/.gitignore:
--------------------------------------------------------------------------------
1 | obj
2 | bin
3 | deploy
4 | deploy/*
5 | _ReSharper.*
6 | *.csproj.user
7 | *.resharper.user
8 | *.ReSharper.user
9 | *.teamcity.user
10 | *.TeamCity.user
11 | *.resharper
12 | *.DotSettings.user
13 | *.dotsettings.user
14 | *.ncrunchproject
15 | *.ncrunchsolution
16 | *.suo
17 | *.cache
18 | ~$*
19 | asb_connection_string.txt
20 | sqs_connectionstring.txt
21 | azure_storage_connection_string.txt
22 | .vs
23 | .vs/*
--------------------------------------------------------------------------------
/Beverage/Beverage.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Beverage/Commands/BlackRussian.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace Beverage.Commands
5 | {
6 | [Command("black-russian", group: "duderino")]
7 | [Description("Mixes a White Russian, pouring in milk till full")]
8 | public class BlackRussian : ICommand
9 | {
10 | [Parameter("vodka")]
11 | [Description("How many cl of vodka?")]
12 | public double Vodka { get; set; }
13 |
14 | [Parameter("kahlua")]
15 | [Description("How many cl of Kahlua?")]
16 | public double Kahlua { get; set; }
17 |
18 | [Parameter("lukewarm", optional: true)]
19 | [Description("Avoid refrigerated ingredients?")]
20 | public bool LukeWarm { get; set; }
21 |
22 | public void Run()
23 | {
24 | Console.WriteLine($"Making a {(LukeWarm ? "luke-warm" : "")} beverage" +
25 | $" with {Vodka:0.#} cl of vodka" +
26 | $" and {Kahlua:0.#} cl of Kahlua");
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Beverage/Commands/Martini.cs:
--------------------------------------------------------------------------------
1 | using GoCommando;
2 |
3 | namespace Beverage.Commands
4 | {
5 | [Command("martini", group: "simple")]
6 | [Description("It's just Martini.")]
7 | public class Martini : ICommand
8 | {
9 | public void Run()
10 | {
11 | throw new System.NotImplementedException();
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/Beverage/Commands/WhiteRussian.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace Beverage.Commands
5 | {
6 | [Command("white-russian", group: "duderino")]
7 | [Description("Mixes a White Russian, pouring in milk till full")]
8 | public class WhiteRussian : ICommand
9 | {
10 | [Parameter("vodka")]
11 | [Description("How many cl of vodka?")]
12 | public double Vodka { get; set; }
13 |
14 | [Parameter("kahlua")]
15 | [Description("How many cl of Kahlua?")]
16 | public double Kahlua { get; set; }
17 |
18 | [Parameter("lukewarm", optional: true)]
19 | [Description("Avoid refrigerated ingredients?")]
20 | public bool LukeWarm { get; set; }
21 |
22 | public void Run()
23 | {
24 | Console.WriteLine($"Making a {(LukeWarm ? "luke-warm" : "")} beverage" +
25 | $" with {Vodka:0.#} cl of vodka" +
26 | $" and {Kahlua:0.#} cl of Kahlua");
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Beverage/Program.cs:
--------------------------------------------------------------------------------
1 | using GoCommando;
2 |
3 | namespace Beverage
4 | {
5 | [Banner(@"------------------------------
6 | Beverage Utility
7 |
8 | Copyright (c) 2015 El Duderino
9 | ------------------------------")]
10 | [SupportImpersonation]
11 | class Program
12 | {
13 | static void Main()
14 | {
15 | Go.Run();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Beverage_old/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Beverage_old/Beverage.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {324FC1A5-749A-44BF-BDB7-EB093F5DD88F}
8 | Exe
9 | Properties
10 | Beverage
11 | Beverage
12 | v4.6
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
63 |
--------------------------------------------------------------------------------
/Beverage_old/Commands/BlackRussian.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace Beverage.Commands
5 | {
6 | [Command("black-russian", group: "duderino")]
7 | [Description("Mixes a White Russian, pouring in milk till full")]
8 | public class BlackRussian : ICommand
9 | {
10 | [Parameter("vodka")]
11 | [Description("How many cl of vodka?")]
12 | public double Vodka { get; set; }
13 |
14 | [Parameter("kahlua")]
15 | [Description("How many cl of Kahlua?")]
16 | public double Kahlua { get; set; }
17 |
18 | [Parameter("lukewarm", optional: true)]
19 | [Description("Avoid refrigerated ingredients?")]
20 | public bool LukeWarm { get; set; }
21 |
22 | public void Run()
23 | {
24 | Console.WriteLine($"Making a {(LukeWarm ? "luke-warm" : "")} beverage" +
25 | $" with {Vodka:0.#} cl of vodka" +
26 | $" and {Kahlua:0.#} cl of Kahlua");
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Beverage_old/Commands/Martini.cs:
--------------------------------------------------------------------------------
1 | using GoCommando;
2 |
3 | namespace Beverage.Commands
4 | {
5 | [Command("martini", group: "simple")]
6 | [Description("It's just Martini.")]
7 | public class Martini : ICommand
8 | {
9 | public void Run()
10 | {
11 | throw new System.NotImplementedException();
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/Beverage_old/Commands/WhiteRussian.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace Beverage.Commands
5 | {
6 | [Command("white-russian", group: "duderino")]
7 | [Description("Mixes a White Russian, pouring in milk till full")]
8 | public class WhiteRussian : ICommand
9 | {
10 | [Parameter("vodka")]
11 | [Description("How many cl of vodka?")]
12 | public double Vodka { get; set; }
13 |
14 | [Parameter("kahlua")]
15 | [Description("How many cl of Kahlua?")]
16 | public double Kahlua { get; set; }
17 |
18 | [Parameter("lukewarm", optional: true)]
19 | [Description("Avoid refrigerated ingredients?")]
20 | public bool LukeWarm { get; set; }
21 |
22 | public void Run()
23 | {
24 | Console.WriteLine($"Making a {(LukeWarm ? "luke-warm" : "")} beverage" +
25 | $" with {Vodka:0.#} cl of vodka" +
26 | $" and {Kahlua:0.#} cl of Kahlua");
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Beverage_old/Program.cs:
--------------------------------------------------------------------------------
1 | using GoCommando;
2 |
3 | namespace Beverage
4 | {
5 | [Banner(@"------------------------------
6 | Beverage Utility
7 |
8 | Copyright (c) 2015 El Duderino
9 | ------------------------------")]
10 | [SupportImpersonation]
11 | class Program
12 | {
13 | static void Main()
14 | {
15 | Go.Run();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Beverage_old/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Beverage")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Beverage")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("324fc1a5-749a-44bf-bdb7-eb093f5dd88f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 0.99.3
4 | * Test release
5 |
6 |
--------------------------------------------------------------------------------
/GoCommando.Tests/GoCommando.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/GoCommando.Tests/TestArgParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using GoCommando.Internals;
5 | using NUnit.Framework;
6 |
7 | namespace GoCommando.Tests
8 | {
9 | [TestFixture]
10 | public class TestArgParser
11 | {
12 | [Test]
13 | public void CanReturnSimpleCommand()
14 | {
15 | var arguments = Parse(new[] { "run" });
16 |
17 | Assert.That(arguments.Command, Is.EqualTo("run"));
18 | }
19 |
20 | [Test]
21 | public void CommandIsNullWhenNoCommandIsGiven()
22 | {
23 | var arguments = Parse(new[] { "-file", @"""C:\temp\file.json""" });
24 |
25 | Assert.That(arguments.Command, Is.Null);
26 | }
27 |
28 | [Test, Ignore("arguments.Command should just be null")]
29 | public void DoesNotAcceptSwitchAsCommand()
30 | {
31 | var ex = Assert.Throws(() =>
32 | {
33 | Parse(new[] { "-file", @"""C:\temp\file.json""" });
34 | });
35 |
36 | Console.WriteLine(ex);
37 | }
38 |
39 | [Test]
40 | public void CanParseOrdinaryArguments()
41 | {
42 | var args = @"run
43 | -path
44 | c:\Program Files
45 | -dir
46 | c:\Windows\Microsoft.NET\Framework
47 | -flag
48 | -moreflag".Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
49 |
50 | var arguments = Parse(args);
51 |
52 | Console.WriteLine(arguments);
53 |
54 | Assert.That(arguments.Command, Is.EqualTo("run"));
55 | Assert.That(arguments.Switches.Count(), Is.EqualTo(4));
56 | Assert.That(arguments.Get("path"), Is.EqualTo(@"c:\Program Files"));
57 | Assert.That(arguments.Get("dir"), Is.EqualTo(@"c:\Windows\Microsoft.NET\Framework"));
58 |
59 | Assert.That(arguments.Get("flag"), Is.True);
60 | Assert.That(arguments.Get("moreflag"), Is.True);
61 | Assert.That(arguments.Get("flag_not_specified_should_default_to_false"), Is.False);
62 | }
63 |
64 | [TestCase(@"-path:""c:\temp""")]
65 | [TestCase(@"-path=""c:\temp""")]
66 | [TestCase(@"-path""c:\temp""")]
67 | public void SupportsVariousSingleTokenAliases(string alias)
68 | {
69 | var arguments = Parse(new[] { alias });
70 |
71 | Assert.That(arguments.Switches.Count(), Is.EqualTo(1));
72 | Assert.That(arguments.Switches.Single().Key, Is.EqualTo("path"));
73 | Assert.That(arguments.Switches.Single().Value, Is.EqualTo(@"c:\temp"));
74 | }
75 |
76 | [TestCase(@"-n23")]
77 | public void SupportsShortFormWithNumber(string alias)
78 | {
79 | var arguments = Parse(new[] { alias });
80 |
81 | Assert.That(arguments.Switches.Count(), Is.EqualTo(1));
82 | Assert.That(arguments.Switches.Single().Key, Is.EqualTo("n"));
83 | Assert.That(arguments.Switches.Single().Value, Is.EqualTo(@"23"));
84 | }
85 |
86 | static Arguments Parse(IEnumerable args)
87 | {
88 | return Go.Parse(args, new Settings());
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/GoCommando.Tests/TestCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using GoCommando.Internals;
5 | using NUnit.Framework;
6 |
7 | namespace GoCommando.Tests
8 | {
9 | [TestFixture]
10 | public class TestCommand
11 | {
12 | [TestCase("-switch:value2")]
13 | [TestCase("-switch=value2")]
14 | [TestCase(@"-switch""value2""")]
15 | public void CanCorrectlyHandleDifferentAlternativeSwitchFormatsFoundInOneSingleTokenOnly(string switchText)
16 | {
17 | var settings = new Settings();
18 | var invoker = new CommandInvoker("bimse", settings, new Bimse());
19 | var arguments = Go.Parse(new[] { switchText }, settings);
20 |
21 | invoker.Invoke(arguments.Switches, EnvironmentSettings.Empty);
22 |
23 | var bimseInstance = (Bimse)invoker.CommandInstance;
24 |
25 | Assert.That(bimseInstance.Switch, Is.EqualTo("value2"));
26 | }
27 |
28 | [TestCase("-s:value2")]
29 | [TestCase("-s=value2")]
30 | [TestCase(@"-s""value2""")]
31 | public void CanCorrectlyHandleDifferentAlternativeSwitchFormatsFoundInOneSingleTokenOnly_Shortname(string switchText)
32 | {
33 | var settings = new Settings();
34 | var invoker = new CommandInvoker("bimse", settings, new Bimse());
35 | var arguments = Go.Parse(new[] { switchText }, settings);
36 |
37 | invoker.Invoke(arguments.Switches, EnvironmentSettings.Empty);
38 |
39 | var bimseInstance = (Bimse)invoker.CommandInstance;
40 |
41 | Assert.That(bimseInstance.Switch, Is.EqualTo("value2"));
42 | }
43 |
44 | [Command("bimse")]
45 | class Bimse : ICommand
46 | {
47 | [Parameter("switch", shortName: "s")]
48 | public string Switch { get; set; }
49 |
50 | public void Run()
51 | {
52 | }
53 | }
54 |
55 | [Test]
56 | public void CanUseSuppliedCommandFactory()
57 | {
58 | var commandFactory = new CustomFactory();
59 |
60 | var commandInvoker = new CommandInvoker("null", typeof(CreatedByFactory), new Settings(), commandFactory: commandFactory);
61 |
62 | commandInvoker.Invoke(Enumerable.Empty(), new EnvironmentSettings());
63 |
64 | Assert.That(commandInvoker.CommandInstance, Is.TypeOf());
65 |
66 | var createdByFactory = (CreatedByFactory)commandInvoker.CommandInstance;
67 | Assert.That(createdByFactory.CtorInjectedValue, Is.EqualTo("ctor!!"));
68 |
69 | Assert.That(commandFactory.WasProperlyReleased, Is.True, "The created command instance was NOT properly released after use!");
70 | }
71 |
72 | class CustomFactory : ICommandFactory
73 | {
74 | CreatedByFactory _instance;
75 |
76 | public bool WasProperlyReleased { get; set; }
77 |
78 | public ICommand Create(Type type)
79 | {
80 | if (type == typeof(CreatedByFactory))
81 | {
82 | _instance = new CreatedByFactory("ctor!!");
83 | return _instance;
84 | }
85 |
86 | throw new ArgumentException($"Unknown command type: {type}");
87 | }
88 |
89 | public void Release(ICommand command)
90 | {
91 | if (_instance == command)
92 | {
93 | WasProperlyReleased = true;
94 | }
95 | }
96 | }
97 |
98 | class CreatedByFactory : ICommand
99 | {
100 | public string CtorInjectedValue { get; }
101 |
102 | public CreatedByFactory(string ctorInjectedValue)
103 | {
104 | CtorInjectedValue = ctorInjectedValue;
105 | }
106 |
107 | public void Run()
108 | {
109 | }
110 | }
111 |
112 | [Test]
113 | public void CanGetParameterFromAppSettingsAndConnectionStrings()
114 | {
115 | var invoker = new CommandInvoker("null", typeof(CanUseAppSetting), new Settings());
116 |
117 | var appSettings = new Dictionary
118 | {
119 | {"my-setting", "my-value"}
120 | };
121 |
122 | var connectionStrings = new Dictionary
123 | {
124 | {"my-conn", "my-value"}
125 | };
126 |
127 | var environmentVariables = new Dictionary
128 | {
129 | {"my-env", "my-value"}
130 | };
131 |
132 | invoker.Invoke(Enumerable.Empty(), new EnvironmentSettings(appSettings, connectionStrings, environmentVariables));
133 |
134 | var instance = (CanUseAppSetting)invoker.CommandInstance;
135 |
136 | Assert.That(instance.AppSetting, Is.EqualTo("my-value"));
137 | Assert.That(instance.ConnectionString, Is.EqualTo("my-value"));
138 | Assert.That(instance.EnvironmentVariable, Is.EqualTo("my-value"));
139 | }
140 |
141 | class CanUseAppSetting : ICommand
142 | {
143 | [Parameter("my-setting", allowAppSetting: true)]
144 | public string AppSetting { get; set; }
145 |
146 | [Parameter("my-conn", allowConnectionString: true)]
147 | public string ConnectionString { get; set; }
148 |
149 | [Parameter("my-env", allowEnvironmentVariable: true)]
150 | public string EnvironmentVariable { get; set; }
151 |
152 | public void Run()
153 | {
154 |
155 | }
156 | }
157 | }
158 | }
--------------------------------------------------------------------------------
/GoCommando.Tests_old/GoCommando.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {5B0BCF64-81B6-4A33-8D00-C673A0EF3551}
8 | Library
9 | Properties
10 | GoCommando.Tests
11 | GoCommando.Tests
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\NUnit.2.6.4\lib\nunit.framework.dll
35 | True
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | {2839AA55-B40A-4BB8-BDA0-C5057E5A683F}
57 | GoCommando
58 |
59 |
60 |
61 |
68 |
--------------------------------------------------------------------------------
/GoCommando.Tests_old/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GoCommando.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GoCommando.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5b0bcf64-81b6-4a33-8d00-c673a0ef3551")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/GoCommando.Tests_old/TestArgParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using GoCommando.Internals;
5 | using NUnit.Framework;
6 |
7 | namespace GoCommando.Tests
8 | {
9 | [TestFixture]
10 | public class TestArgParser
11 | {
12 | [Test]
13 | public void CanReturnSimpleCommand()
14 | {
15 | var arguments = Parse(new[] { "run" });
16 |
17 | Assert.That(arguments.Command, Is.EqualTo("run"));
18 | }
19 |
20 | [Test]
21 | public void CommandIsNullWhenNoCommandIsGiven()
22 | {
23 | var arguments = Parse(new[] { "-file", @"""C:\temp\file.json""" });
24 |
25 | Assert.That(arguments.Command, Is.Null);
26 | }
27 |
28 | [Test, Ignore("arguments.Command should just be null")]
29 | public void DoesNotAcceptSwitchAsCommand()
30 | {
31 | var ex = Assert.Throws(() =>
32 | {
33 | Parse(new[] { "-file", @"""C:\temp\file.json""" });
34 | });
35 |
36 | Console.WriteLine(ex);
37 | }
38 |
39 | [Test]
40 | public void CanParseOrdinaryArguments()
41 | {
42 | var args = @"run
43 | -path
44 | c:\Program Files
45 | -dir
46 | c:\Windows\Microsoft.NET\Framework
47 | -flag
48 | -moreflag".Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
49 |
50 | var arguments = Parse(args);
51 |
52 | Console.WriteLine(arguments);
53 |
54 | Assert.That(arguments.Command, Is.EqualTo("run"));
55 | Assert.That(arguments.Switches.Count(), Is.EqualTo(4));
56 | Assert.That(arguments.Get("path"), Is.EqualTo(@"c:\Program Files"));
57 | Assert.That(arguments.Get("dir"), Is.EqualTo(@"c:\Windows\Microsoft.NET\Framework"));
58 |
59 | Assert.That(arguments.Get("flag"), Is.True);
60 | Assert.That(arguments.Get("moreflag"), Is.True);
61 | Assert.That(arguments.Get("flag_not_specified_should_default_to_false"), Is.False);
62 | }
63 |
64 | [TestCase(@"-path:""c:\temp""")]
65 | [TestCase(@"-path=""c:\temp""")]
66 | [TestCase(@"-path""c:\temp""")]
67 | public void SupportsVariousSingleTokenAliases(string alias)
68 | {
69 | var arguments = Parse(new[] { alias });
70 |
71 | Assert.That(arguments.Switches.Count(), Is.EqualTo(1));
72 | Assert.That(arguments.Switches.Single().Key, Is.EqualTo("path"));
73 | Assert.That(arguments.Switches.Single().Value, Is.EqualTo(@"c:\temp"));
74 | }
75 |
76 | [TestCase(@"-n23")]
77 | public void SupportsShortFormWithNumber(string alias)
78 | {
79 | var arguments = Parse(new[] { alias });
80 |
81 | Assert.That(arguments.Switches.Count(), Is.EqualTo(1));
82 | Assert.That(arguments.Switches.Single().Key, Is.EqualTo("n"));
83 | Assert.That(arguments.Switches.Single().Value, Is.EqualTo(@"23"));
84 | }
85 |
86 | static Arguments Parse(IEnumerable args)
87 | {
88 | return Go.Parse(args, new Settings());
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/GoCommando.Tests_old/TestCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using GoCommando.Internals;
5 | using NUnit.Framework;
6 |
7 | namespace GoCommando.Tests
8 | {
9 | [TestFixture]
10 | public class TestCommand
11 | {
12 | [TestCase("-switch:value2")]
13 | [TestCase("-switch=value2")]
14 | [TestCase(@"-switch""value2""")]
15 | public void CanCorrectlyHandleDifferentAlternativeSwitchFormatsFoundInOneSingleTokenOnly(string switchText)
16 | {
17 | var settings = new Settings();
18 | var invoker = new CommandInvoker("bimse", settings, new Bimse());
19 | var arguments = Go.Parse(new[] { switchText }, settings);
20 |
21 | invoker.Invoke(arguments.Switches, EnvironmentSettings.Empty);
22 |
23 | var bimseInstance = (Bimse)invoker.CommandInstance;
24 |
25 | Assert.That(bimseInstance.Switch, Is.EqualTo("value2"));
26 | }
27 |
28 | [TestCase("-s:value2")]
29 | [TestCase("-s=value2")]
30 | [TestCase(@"-s""value2""")]
31 | public void CanCorrectlyHandleDifferentAlternativeSwitchFormatsFoundInOneSingleTokenOnly_Shortname(string switchText)
32 | {
33 | var settings = new Settings();
34 | var invoker = new CommandInvoker("bimse", settings, new Bimse());
35 | var arguments = Go.Parse(new[] { switchText }, settings);
36 |
37 | invoker.Invoke(arguments.Switches, EnvironmentSettings.Empty);
38 |
39 | var bimseInstance = (Bimse)invoker.CommandInstance;
40 |
41 | Assert.That(bimseInstance.Switch, Is.EqualTo("value2"));
42 | }
43 |
44 | [Command("bimse")]
45 | class Bimse : ICommand
46 | {
47 | [Parameter("switch", shortName: "s")]
48 | public string Switch { get; set; }
49 |
50 | public void Run()
51 | {
52 | }
53 | }
54 |
55 | [Test]
56 | public void CanUseSuppliedCommandFactory()
57 | {
58 | var commandFactory = new CustomFactory();
59 |
60 | var commandInvoker = new CommandInvoker("null", typeof(CreatedByFactory), new Settings(), commandFactory: commandFactory);
61 |
62 | commandInvoker.Invoke(Enumerable.Empty(), new EnvironmentSettings());
63 |
64 | Assert.That(commandInvoker.CommandInstance, Is.TypeOf());
65 |
66 | var createdByFactory = (CreatedByFactory)commandInvoker.CommandInstance;
67 | Assert.That(createdByFactory.CtorInjectedValue, Is.EqualTo("ctor!!"));
68 |
69 | Assert.That(commandFactory.WasProperlyReleased, Is.True, "The created command instance was NOT properly released after use!");
70 | }
71 |
72 | class CustomFactory : ICommandFactory
73 | {
74 | CreatedByFactory _instance;
75 |
76 | public bool WasProperlyReleased { get; set; }
77 |
78 | public ICommand Create(Type type)
79 | {
80 | if (type == typeof(CreatedByFactory))
81 | {
82 | _instance = new CreatedByFactory("ctor!!");
83 | return _instance;
84 | }
85 |
86 | throw new ArgumentException($"Unknown command type: {type}");
87 | }
88 |
89 | public void Release(ICommand command)
90 | {
91 | if (_instance == command)
92 | {
93 | WasProperlyReleased = true;
94 | }
95 | }
96 | }
97 |
98 | class CreatedByFactory : ICommand
99 | {
100 | public string CtorInjectedValue { get; }
101 |
102 | public CreatedByFactory(string ctorInjectedValue)
103 | {
104 | CtorInjectedValue = ctorInjectedValue;
105 | }
106 |
107 | public void Run()
108 | {
109 | }
110 | }
111 |
112 | [Test]
113 | public void CanGetParameterFromAppSettingsAndConnectionStrings()
114 | {
115 | var invoker = new CommandInvoker("null", typeof(CanUseAppSetting), new Settings());
116 |
117 | var appSettings = new Dictionary
118 | {
119 | {"my-setting", "my-value"}
120 | };
121 |
122 | var connectionStrings = new Dictionary
123 | {
124 | {"my-conn", "my-value"}
125 | };
126 |
127 | var environmentVariables = new Dictionary
128 | {
129 | {"my-env", "my-value"}
130 | };
131 |
132 | invoker.Invoke(Enumerable.Empty(), new EnvironmentSettings(appSettings, connectionStrings, environmentVariables));
133 |
134 | var instance = (CanUseAppSetting)invoker.CommandInstance;
135 |
136 | Assert.That(instance.AppSetting, Is.EqualTo("my-value"));
137 | Assert.That(instance.ConnectionString, Is.EqualTo("my-value"));
138 | Assert.That(instance.EnvironmentVariable, Is.EqualTo("my-value"));
139 | }
140 |
141 | class CanUseAppSetting : ICommand
142 | {
143 | [Parameter("my-setting", allowAppSetting: true)]
144 | public string AppSetting { get; set; }
145 |
146 | [Parameter("my-conn", allowConnectionString: true)]
147 | public string ConnectionString { get; set; }
148 |
149 | [Parameter("my-env", allowEnvironmentVariable: true)]
150 | public string EnvironmentVariable { get; set; }
151 |
152 | public void Run()
153 | {
154 |
155 | }
156 | }
157 | }
158 | }
--------------------------------------------------------------------------------
/GoCommando.Tests_old/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/GoCommando.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio Version 16
3 | VisualStudioVersion = 16.0.30330.147
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "stuff", "stuff", "{4777EF91-8FBF-42DC-A31F-2025CC5841F8}"
6 | ProjectSection(SolutionItems) = preProject
7 | CHANGELOG.md = CHANGELOG.md
8 | Package.nuspec = Package.nuspec
9 | README.md = README.md
10 | EndProjectSection
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{94F2785A-49E5-447F-BAFF-BE8F783EC71F}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GoCommando", "GoCommando\GoCommando.csproj", "{91A9A887-0298-4B72-9D24-C2438F469192}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GoCommando.Tests", "GoCommando.Tests\GoCommando.Tests.csproj", "{FBD7AE5E-C842-448B-9A6B-81513E60F357}"
17 | EndProject
18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Beverage", "Beverage\Beverage.csproj", "{D7C8D131-E81A-4846-A9EE-9D42A667CA32}"
19 | EndProject
20 | Global
21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
22 | Debug|Any CPU = Debug|Any CPU
23 | Release|Any CPU = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {91A9A887-0298-4B72-9D24-C2438F469192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {91A9A887-0298-4B72-9D24-C2438F469192}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {91A9A887-0298-4B72-9D24-C2438F469192}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {91A9A887-0298-4B72-9D24-C2438F469192}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {FBD7AE5E-C842-448B-9A6B-81513E60F357}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {FBD7AE5E-C842-448B-9A6B-81513E60F357}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {FBD7AE5E-C842-448B-9A6B-81513E60F357}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {FBD7AE5E-C842-448B-9A6B-81513E60F357}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {D7C8D131-E81A-4846-A9EE-9D42A667CA32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {D7C8D131-E81A-4846-A9EE-9D42A667CA32}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {D7C8D131-E81A-4846-A9EE-9D42A667CA32}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {D7C8D131-E81A-4846-A9EE-9D42A667CA32}.Release|Any CPU.Build.0 = Release|Any CPU
38 | EndGlobalSection
39 | GlobalSection(SolutionProperties) = preSolution
40 | HideSolutionNode = FALSE
41 | EndGlobalSection
42 | GlobalSection(NestedProjects) = preSolution
43 | {D7C8D131-E81A-4846-A9EE-9D42A667CA32} = {94F2785A-49E5-447F-BAFF-BE8F783EC71F}
44 | EndGlobalSection
45 | GlobalSection(ExtensibilityGlobals) = postSolution
46 | SolutionGuid = {F99A8DD1-DE53-43D3-A0E0-BE222C826E90}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/GoCommando/BannerAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to the class that has your Main
method in order to have a nice banner printed out when the program starts
7 | ///
8 | [AttributeUsage(AttributeTargets.Class)]
9 | public class BannerAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the banner text
13 | ///
14 | public string BannerText { get; }
15 |
16 | ///
17 | /// Constructs the attribute
18 | ///
19 | public BannerAttribute(string bannerText)
20 | {
21 | BannerText = bannerText;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/GoCommando/CommandAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Attribute that can be applied to a class that represents a command. The class must implement
7 | ///
8 | [AttributeUsage(AttributeTargets.Class)]
9 | public class CommandAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the name of the command
13 | ///
14 | public string Command { get; }
15 |
16 | ///
17 | /// Gets the name of the command's group (if any). Grouping commands affects how they are presented when printing
18 | /// help texts
19 | ///
20 | public string Group { get; }
21 |
22 | ///
23 | /// Constructs the attribute
24 | ///
25 | public CommandAttribute(string command, string group = null)
26 | {
27 | Command = command;
28 | Group = group ?? "";
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/GoCommando/DescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to a property of a command class (which is also decorated with ) in
7 | /// order to provide a description of the parameter
8 | ///
9 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
10 | public class DescriptionAttribute : Attribute
11 | {
12 | ///
13 | /// Gets the description text
14 | ///
15 | public string DescriptionText { get; }
16 |
17 | ///
18 | /// Constructs the attribute
19 | ///
20 | public DescriptionAttribute(string descriptionText)
21 | {
22 | DescriptionText = descriptionText;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/GoCommando/ExampleAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply one or more of these to a command property to show examples on how this particular parameter can be used
7 | ///
8 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
9 | public class ExampleAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the example text
13 | ///
14 | public string ExampleValue { get; }
15 |
16 | ///
17 | /// Constructs the attribute
18 | ///
19 | public ExampleAttribute(string exampleValue)
20 | {
21 | ExampleValue = exampleValue;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/GoCommando/ExitCodeException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace GoCommando
5 | {
6 | ///
7 | /// Exception that can be used to exit the program with a custom exit code
8 | ///
9 | [Serializable]
10 | public class CustomExitCodeException : Exception
11 | {
12 | ///
13 | /// Constructs the exception
14 | ///
15 | protected CustomExitCodeException(SerializationInfo info, StreamingContext context) : base(info, context)
16 | {
17 | }
18 |
19 | ///
20 | /// Constructs the exception
21 | ///
22 | public CustomExitCodeException(int exitCode, string message) : base(message)
23 | {
24 | ExitCode = exitCode;
25 | }
26 |
27 | ///
28 | /// Gets the exit code that the program must exit with
29 | ///
30 | public int ExitCode { get; }
31 | }
32 | }
--------------------------------------------------------------------------------
/GoCommando/GoCommando.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | MIT
6 | https://github.com/rebus-org/GoCommando/wiki
7 | https://github.com/rebus-org/GoCommando
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GoCommando/GoCommandoException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace GoCommando
5 | {
6 | ///
7 | /// Friendly exception that can be thrown in cases where you want the program to exit with
8 | /// a nice, human-readable message. Only the message will be shown.
9 | ///
10 | [Serializable]
11 | public class GoCommandoException : Exception
12 | {
13 | ///
14 | /// Constructs the exception
15 | ///
16 | protected GoCommandoException(SerializationInfo info, StreamingContext context) : base(info, context)
17 | {
18 | }
19 |
20 | ///
21 | /// Constructs the exception
22 | ///
23 | public GoCommandoException(string message) : base(message)
24 | {
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/GoCommando/ICommand.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | ///
4 | /// Implement this interface on each command
5 | ///
6 | public interface ICommand
7 | {
8 | ///
9 | /// Main run method that is invoked by GoCommando
10 | ///
11 | void Run();
12 | }
13 | }
--------------------------------------------------------------------------------
/GoCommando/ICommandFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Can be implemented to supply a custom command factory that will be given a chance to create command instances
7 | /// and dispose of them after use
8 | ///
9 | public interface ICommandFactory
10 | {
11 | ///
12 | /// Should create a new command instance of the given
13 | ///
14 | ICommand Create(Type commandType);
15 |
16 | ///
17 | /// Should release the command instance - probably by disposing it or delegating the disposal to an IoC container
18 | ///
19 | void Release(ICommand command);
20 | }
21 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/Arguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace GoCommando.Internals
6 | {
7 | class Arguments
8 | {
9 | readonly Settings _settings;
10 |
11 | public Arguments(string command, IEnumerable switches, Settings settings)
12 | {
13 | _settings = settings;
14 | var switchList = switches.ToList();
15 | var duplicateSwitchKeys = switchList.GroupBy(s => s.Key).Where(g => g.Count() > 1).ToList();
16 |
17 | if (duplicateSwitchKeys.Any())
18 | {
19 | var dupes = string.Join(", ", duplicateSwitchKeys.Select(g => $"{settings.SwitchPrefix}{g.Key}"));
20 |
21 | throw new GoCommandoException($"The following switches have been specified more than once: {dupes}");
22 | }
23 |
24 | Command = command;
25 | Switches = switchList;
26 | }
27 |
28 | public string Command { get; }
29 |
30 | public IEnumerable Switches { get; }
31 |
32 | public TValue Get(string key)
33 | {
34 | var desiredType = typeof(TValue);
35 |
36 | try
37 | {
38 | if (desiredType == typeof(bool))
39 | {
40 | return (TValue)Convert.ChangeType(Switches.Any(s => s.Key == key), desiredType);
41 | }
42 |
43 | var relevantSwitch = Switches.FirstOrDefault(s => s.Key == key);
44 |
45 | if (relevantSwitch != null)
46 | {
47 | return (TValue)Convert.ChangeType(relevantSwitch.Value, desiredType);
48 | }
49 |
50 | throw new GoCommandoException($"Could not find switch '{key}'");
51 | }
52 | catch (Exception exception)
53 | {
54 | throw new FormatException($"Could not get switch '{key}' as a {desiredType}", exception);
55 | } }
56 |
57 | public override string ToString()
58 | {
59 | return $@"{Command}
60 |
61 | {string.Join(Environment.NewLine, Switches.Select(s => " " + s))}";
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/CommandInvoker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace GoCommando.Internals
7 | {
8 | class CommandInvoker
9 | {
10 | readonly Settings _settings;
11 | readonly ICommand _commandInstance;
12 | readonly Action _releaser;
13 | readonly List _parameters;
14 |
15 | public CommandInvoker(string command, Type type, Settings settings, string @group = null,
16 | ICommandFactory commandFactory = null)
17 | : this(command, settings, CreateInstance(type, GetFactoryMethod(commandFactory)), group, GetReleaseMethod(commandFactory))
18 | {
19 | }
20 |
21 | public CommandInvoker(string command, Settings settings, ICommand commandInstance, string group = null, Action releaseMethod = null)
22 | {
23 | if (command == null) throw new ArgumentNullException(nameof(command));
24 | if (settings == null) throw new ArgumentNullException(nameof(settings));
25 | if (commandInstance == null) throw new ArgumentNullException(nameof(commandInstance));
26 |
27 | _settings = settings;
28 | _commandInstance = commandInstance;
29 | _releaser = releaseMethod ?? DefaultReleaseMethod;
30 |
31 | Command = command;
32 | Group = group;
33 |
34 | _parameters = GetParameters(Type).ToList();
35 | }
36 |
37 | static void DefaultReleaseMethod(ICommand command)
38 | {
39 | var disposable = command as IDisposable;
40 |
41 | disposable?.Dispose();
42 | }
43 |
44 | static Func GetFactoryMethod(ICommandFactory commandFactory)
45 | {
46 | if (commandFactory == null) return null;
47 |
48 | return commandFactory.Create;
49 | }
50 |
51 | static Action GetReleaseMethod(ICommandFactory commandFactory)
52 | {
53 | if (commandFactory == null) return null;
54 |
55 | return commandFactory.Release;
56 | }
57 |
58 | static ICommand CreateInstance(Type type, Func commandFactory = null)
59 | {
60 | try
61 | {
62 | var instance = commandFactory?.Invoke(type)
63 | ?? Activator.CreateInstance(type);
64 |
65 | if (!(instance is ICommand))
66 | {
67 | throw new ApplicationException($"{instance} does not implement ICommand!");
68 | }
69 |
70 | return (ICommand)instance;
71 | }
72 | catch (Exception exception)
73 | {
74 | throw new ApplicationException($"Could not use type {type} as a GoCommando command", exception);
75 | }
76 | }
77 |
78 | static IEnumerable GetParameters(Type type)
79 | {
80 | return type
81 | .GetProperties()
82 | .Select(p => new
83 | {
84 | Property = p,
85 | ParameterAttribute = GetSingleAttributeOrNull(p),
86 | DescriptionAttribute = GetSingleAttributeOrNull(p),
87 | ExampleAttributes = p.GetCustomAttributes()
88 | })
89 | .Where(a => a.ParameterAttribute != null)
90 | .Select(a => new Parameter(a.Property,
91 | a.ParameterAttribute.Name,
92 | a.ParameterAttribute.ShortName,
93 | a.ParameterAttribute.Optional,
94 | a.DescriptionAttribute?.DescriptionText,
95 | a.ExampleAttributes.Select(e => e.ExampleValue),
96 | a.ParameterAttribute.DefaultValue,
97 | a.ParameterAttribute.AllowAppSetting,
98 | a.ParameterAttribute.AllowConnectionString,
99 | a.ParameterAttribute.AllowEnvironmentVariable))
100 | .ToList();
101 | }
102 |
103 | static TAttribute GetSingleAttributeOrNull(PropertyInfo p) where TAttribute : Attribute
104 | {
105 | return p.GetCustomAttributes(typeof(TAttribute), false)
106 | .Cast()
107 | .FirstOrDefault();
108 | }
109 |
110 | public string Group { get; }
111 |
112 | public string Command { get; }
113 |
114 | public Type Type => _commandInstance.GetType();
115 |
116 | public IEnumerable Parameters => _parameters;
117 |
118 | public string Description => Type.GetCustomAttribute()?.DescriptionText ??
119 | "(no help text for this command)";
120 |
121 | public ICommand CommandInstance => _commandInstance;
122 |
123 | public void Invoke(IEnumerable switches, EnvironmentSettings environmentSettings)
124 | {
125 | try
126 | {
127 | InnerInvoke(switches, environmentSettings);
128 | }
129 | finally
130 | {
131 | _releaser(CommandInstance);
132 | }
133 | }
134 |
135 | void InnerInvoke(IEnumerable switches, EnvironmentSettings environmentSettings)
136 | {
137 | var commandInstance = _commandInstance;
138 |
139 | var requiredParametersMissing = Parameters
140 | .Where(p => !p.Optional
141 | && !p.HasDefaultValue
142 | && !CanBeResolvedFromSwitches(switches, p)
143 | && !CanBeResolvedFromEnvironmentSettings(environmentSettings, p))
144 | .ToList();
145 |
146 | var optionalParamtersNotSpecified = Parameters
147 | .Where(p => p.Optional
148 | && !CanBeResolvedFromSwitches(switches, p)
149 | && !CanBeResolvedFromEnvironmentSettings(environmentSettings, p))
150 | .ToList();
151 |
152 | if (requiredParametersMissing.Any())
153 | {
154 | var requiredParametersMissingString = string.Join(Environment.NewLine,
155 | requiredParametersMissing.Select(p => $" {_settings.SwitchPrefix}{p.Name} - {p.DescriptionText}"));
156 |
157 | var text = $@"The following required parameters are missing:
158 |
159 | {requiredParametersMissingString}";
160 |
161 | if (optionalParamtersNotSpecified.Any())
162 | {
163 | var optionalParamtersNotSpecifiedString = string.Join(Environment.NewLine,
164 | optionalParamtersNotSpecified.Select(p => $" {_settings.SwitchPrefix}{p.Name} - {p.DescriptionText}"));
165 |
166 | var moreText = $@"The following optional parameters are also available:
167 |
168 | {optionalParamtersNotSpecifiedString}";
169 |
170 | throw new GoCommandoException(string.Concat(
171 | text,
172 | Environment.NewLine,
173 | Environment.NewLine,
174 | moreText
175 | ));
176 | }
177 |
178 | throw new GoCommandoException(text);
179 | }
180 |
181 | var switchesWithoutMathingParameter = switches
182 | .Where(s => !Parameters.Any(p => p.MatchesKey(s.Key)))
183 | .ToList();
184 |
185 | if (switchesWithoutMathingParameter.Any())
186 | {
187 | var switchesWithoutMathingParameterString = string.Join(Environment.NewLine,
188 | switchesWithoutMathingParameter.Select(p => p.Value != null
189 | ? $" {_settings.SwitchPrefix}{p.Key} = {p.Value}"
190 | : $" {_settings.SwitchPrefix}{p.Key}"));
191 |
192 | throw new GoCommandoException(
193 | $@"The following switches do not have a corresponding parameter:
194 |
195 | {switchesWithoutMathingParameterString}");
196 | }
197 |
198 | var setParameters = new HashSet();
199 |
200 | ResolveParametersFromSwitches(switches, commandInstance, setParameters);
201 |
202 | ResolveParametersFromEnvironmentSettings(environmentSettings, commandInstance, setParameters, Parameters);
203 |
204 | ResolveParametersWithDefaultValues(setParameters, commandInstance);
205 |
206 | commandInstance.Run();
207 | }
208 |
209 | static void ResolveParametersFromEnvironmentSettings(EnvironmentSettings environmentSettings, ICommand commandInstance, HashSet setParameters, IEnumerable parameters)
210 | {
211 | foreach (var parameter in parameters.Where(p => p.AllowAppSetting && !setParameters.Contains(p)))
212 | {
213 | if (!environmentSettings.HasAppSetting(parameter.Name)) continue;
214 |
215 | var appSettingValue = environmentSettings.GetAppSetting(parameter.Name);
216 |
217 | SetParameter(commandInstance, setParameters, parameter, appSettingValue);
218 | }
219 |
220 | foreach (var parameter in parameters.Where(p => p.AllowConnectionString && !setParameters.Contains(p)))
221 | {
222 | if (!environmentSettings.HasConnectionString(parameter.Name)) continue;
223 |
224 | var appSettingValue = environmentSettings.GetConnectionString(parameter.Name);
225 |
226 | SetParameter(commandInstance, setParameters, parameter, appSettingValue);
227 | }
228 |
229 | foreach (var parameter in parameters.Where(p => p.AllowEnvironmentVariable && !setParameters.Contains(p)))
230 | {
231 | if (!environmentSettings.HasEnvironmentVariable(parameter.Name)) continue;
232 |
233 | var appSettingValue = environmentSettings.GetEnvironmentVariable(parameter.Name);
234 |
235 | SetParameter(commandInstance, setParameters, parameter, appSettingValue);
236 | }
237 | }
238 |
239 | void ResolveParametersWithDefaultValues(IEnumerable setParameters, ICommand commandInstance)
240 | {
241 | foreach (var parameterWithDefaultValue in Parameters.Where(p => p.HasDefaultValue).Except(setParameters))
242 | {
243 | parameterWithDefaultValue.ApplyDefaultValue(commandInstance);
244 | }
245 | }
246 |
247 | void ResolveParametersFromSwitches(IEnumerable switches, ICommand commandInstance, ISet setParameters)
248 | {
249 | foreach (var switchToSet in switches)
250 | {
251 | var correspondingParameter = Parameters.FirstOrDefault(p => p.MatchesKey(switchToSet.Key));
252 |
253 | if (correspondingParameter == null)
254 | {
255 | throw new GoCommandoException(
256 | $"The switch {_settings}{switchToSet.Key} does not correspond to a parameter of the '{Command}' command!");
257 | }
258 |
259 | var value = switchToSet.Value;
260 |
261 | SetParameter(commandInstance, setParameters, correspondingParameter, value);
262 | }
263 | }
264 |
265 | static void SetParameter(ICommand commandInstance, ISet setParameters, Parameter parameter, string value)
266 | {
267 | parameter.SetValue(commandInstance, value);
268 | setParameters.Add(parameter);
269 | }
270 |
271 | static bool CanBeResolvedFromEnvironmentSettings(EnvironmentSettings environmentSettings, Parameter parameter)
272 | {
273 | var name = parameter.Name;
274 |
275 | if (parameter.AllowAppSetting && environmentSettings.HasAppSetting(name))
276 | {
277 | return true;
278 | }
279 |
280 | if (parameter.AllowConnectionString && environmentSettings.HasConnectionString(name))
281 | {
282 | return true;
283 | }
284 |
285 | if (parameter.AllowEnvironmentVariable && environmentSettings.HasEnvironmentVariable(name))
286 | {
287 | return true;
288 | }
289 |
290 | return false;
291 | }
292 |
293 | static bool CanBeResolvedFromSwitches(IEnumerable switches, Parameter p)
294 | {
295 | return switches.Any(s => p.MatchesKey(s.Key));
296 | }
297 | }
298 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/EnvironmentSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace GoCommando.Internals
5 | {
6 | class EnvironmentSettings
7 | {
8 | static readonly IDictionary None = new Dictionary();
9 | public static readonly EnvironmentSettings Empty = new EnvironmentSettings(None, None);
10 |
11 | readonly IDictionary _appSettings;
12 | readonly IDictionary _connectionStrings;
13 | readonly IDictionary _environmentVariables;
14 |
15 | public EnvironmentSettings(IDictionary appSettings = null, IDictionary connectionStrings = null, IDictionary environmentVariables = null)
16 | {
17 | _environmentVariables = environmentVariables ?? None;
18 | _appSettings = appSettings ?? None;
19 | _connectionStrings = connectionStrings ?? None;
20 | }
21 |
22 | public bool HasAppSetting(string name)
23 | {
24 | return _appSettings.ContainsKey(name);
25 | }
26 |
27 | public bool HasConnectionString(string name)
28 | {
29 | return _connectionStrings.ContainsKey(name);
30 | }
31 |
32 | public bool HasEnvironmentVariable(string name)
33 | {
34 | return _environmentVariables.ContainsKey(name);
35 | }
36 |
37 | public string GetAppSetting(string key)
38 | {
39 | try
40 | {
41 | return _appSettings[key];
42 | }
43 | catch (Exception exception)
44 | {
45 | throw new KeyNotFoundException($"Could not find appSetting with key '{key}'", exception);
46 | }
47 | }
48 |
49 | public string GetEnvironmentVariable(string name)
50 | {
51 | try
52 | {
53 | return _environmentVariables[name];
54 | }
55 | catch (Exception exception)
56 | {
57 | throw new KeyNotFoundException($"Could not find environment variable with the name '{name}'", exception);
58 | }
59 | }
60 |
61 | public string GetConnectionString(string name)
62 | {
63 | try
64 | {
65 | return _connectionStrings[name];
66 | }
67 | catch (Exception exception)
68 | {
69 | throw new KeyNotFoundException($"Could not find connectionString with key '{name}'", exception);
70 | }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/InternalsVisibleTo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("GoCommando.Tests")]
--------------------------------------------------------------------------------
/GoCommando/Internals/Parameter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace GoCommando.Internals
7 | {
8 | class Parameter : IEquatable
9 | {
10 | public PropertyInfo PropertyInfo { get; }
11 | public string Name { get; }
12 | public string Shortname { get; }
13 | public bool Optional { get; }
14 | public string DescriptionText { get; }
15 | public string DefaultValue { get; }
16 | public bool AllowAppSetting { get; }
17 | public bool AllowConnectionString { get; }
18 | public bool AllowEnvironmentVariable { get; }
19 | public string[] ExampleValues { get; }
20 |
21 | public bool IsFlag => PropertyInfo.PropertyType == typeof(bool);
22 |
23 | public bool HasDefaultValue => DefaultValue != null;
24 |
25 | public Parameter(PropertyInfo propertyInfo, string name, string shortname, bool optional, string descriptionText, IEnumerable exampleValues, string defaultValue, bool allowAppSetting, bool allowConnectionString, bool allowEnvironmentVariable)
26 | {
27 | PropertyInfo = propertyInfo;
28 | Name = name;
29 | Shortname = shortname;
30 | Optional = optional;
31 | DescriptionText = GetText(descriptionText, allowAppSetting, allowConnectionString, allowEnvironmentVariable);
32 | DefaultValue = defaultValue;
33 | AllowAppSetting = allowAppSetting;
34 | AllowConnectionString = allowConnectionString;
35 | AllowEnvironmentVariable = allowEnvironmentVariable;
36 | ExampleValues = exampleValues.ToArray();
37 | }
38 |
39 | private string GetText(string descriptionText, bool allowAppSetting, bool allowConnectionString, bool allowEnvironmentVariable)
40 | {
41 | if (!allowAppSetting && !allowConnectionString && !allowEnvironmentVariable)
42 | {
43 | return $"{descriptionText ?? ""}";
44 | }
45 |
46 | var autoBindings = new List();
47 |
48 | if (allowEnvironmentVariable)
49 | {
50 | autoBindings.Add("ENV");
51 | }
52 |
53 | if (allowAppSetting)
54 | {
55 | autoBindings.Add("APP");
56 | }
57 |
58 | if (allowConnectionString)
59 | {
60 | autoBindings.Add("CONN");
61 | }
62 |
63 | return $"{descriptionText ?? ""} ({string.Join(", ", autoBindings)})";
64 | }
65 |
66 | public bool MatchesKey(string key)
67 | {
68 | return key == Name
69 | || (Shortname != null && key == Shortname);
70 | }
71 |
72 | public void SetValue(object commandInstance, string value)
73 | {
74 | try
75 | {
76 | var valueInTheRightType = PropertyInfo.PropertyType == typeof(bool)
77 | ? true
78 | : Convert.ChangeType(value, PropertyInfo.PropertyType);
79 |
80 | PropertyInfo.SetValue(commandInstance, valueInTheRightType);
81 | }
82 | catch (Exception exception)
83 | {
84 | throw new FormatException($"Could not set value '{value}' on property named '{PropertyInfo.Name}' on {PropertyInfo.DeclaringType}", exception);
85 | }
86 | }
87 |
88 | public void ApplyDefaultValue(ICommand commandInstance)
89 | {
90 | if (!HasDefaultValue)
91 | {
92 | throw new InvalidOperationException($"Cannot apply default value of '{Name}' parameter because it has no default!");
93 | }
94 |
95 | SetValue(commandInstance, DefaultValue);
96 | }
97 |
98 | public bool Equals(Parameter other)
99 | {
100 | return Name.Equals(other.Name);
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/Settings.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Internals
2 | {
3 | class Settings
4 | {
5 | public Settings()
6 | {
7 | SwitchPrefix = "-";
8 | }
9 |
10 | public string SwitchPrefix { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 |
5 | namespace GoCommando.Internals
6 | {
7 | static class StringExtensions
8 | {
9 | public static string WrappedAt(this string str, int width)
10 | {
11 | var twoLineBreaks = Environment.NewLine + Environment.NewLine;
12 |
13 | var sections = str.Split(new[] { twoLineBreaks },
14 | StringSplitOptions.RemoveEmptyEntries);
15 |
16 | return string.Join(twoLineBreaks, sections.Select(section => WrapSection(section, width)));
17 | }
18 |
19 | static string WrapSection(string section, int width)
20 | {
21 | var oneLongString = string.Join(" ",
22 | section.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries));
23 |
24 | var words = oneLongString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
25 |
26 | var builder = new StringBuilder();
27 |
28 | var currentLineLength = 0;
29 |
30 | for (var index = 0; index < words.Length; index++)
31 | {
32 | var word = words[index];
33 | builder.Append(word);
34 | currentLineLength += word.Length;
35 |
36 | if (index < words.Length - 1)
37 | {
38 | var nextWord = words[index];
39 |
40 | var spaceLeftOnCurrentLine = width - currentLineLength - 1; // -1 to leave room for space...
41 | var nextWordIsTooLong = nextWord.Length > spaceLeftOnCurrentLine;
42 |
43 | if (nextWordIsTooLong)
44 | {
45 | builder.AppendLine();
46 | currentLineLength = 0;
47 | }
48 | else
49 | {
50 | builder.Append(" ");
51 | currentLineLength++;
52 | }
53 | }
54 | }
55 |
56 | return builder.ToString();
57 | }
58 |
59 | public static string Indented(this string str, int indent)
60 | {
61 | var indentedLines = str
62 | .Split(new[] { Environment.NewLine }, StringSplitOptions.None)
63 | .Select(line => string.Concat(new string(' ', indent), line));
64 |
65 | return string.Join(Environment.NewLine, indentedLines);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/GoCommando/Internals/Switch.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable LoopCanBeConvertedToQuery
2 | namespace GoCommando.Internals
3 | {
4 | class Switch
5 | {
6 | static readonly char[] AcceptedQuoteCharacters = { '"', '\'' };
7 |
8 | public static Switch KeyValue(string key, string value)
9 | {
10 | return new Switch(key, value);
11 | }
12 |
13 | public static Switch Flag(string key)
14 | {
15 | return new Switch(key, null);
16 | }
17 |
18 | Switch(string key, string value)
19 | {
20 | Key = key;
21 | Value = Unquote(value);
22 | }
23 |
24 | static string Unquote(string value)
25 | {
26 | if (value == null) return null;
27 |
28 | // can't be quoted
29 | if (value.Length < 2) return value;
30 |
31 | foreach (var quoteChar in AcceptedQuoteCharacters)
32 | {
33 | var quote = quoteChar.ToString();
34 |
35 | if (value.StartsWith(quote)
36 | && value.EndsWith(quote))
37 | {
38 | return value.Substring(1, value.Length - 2);
39 | }
40 | }
41 |
42 | return value;
43 | }
44 |
45 | public string Key { get; }
46 | public string Value { get; }
47 |
48 | public override string ToString()
49 | {
50 | return Value == null
51 | ? Key
52 | : $"{Key} = {Value}";
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/GoCommando/ParameterAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to a property of a command class (i.e. one that implements )
7 | ///
8 | [AttributeUsage(AttributeTargets.Property)]
9 | public class ParameterAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the primary parameter name
13 | ///
14 | public string Name { get; }
15 |
16 | ///
17 | /// Gets a shorthand for the parameter (or null if none has been specified)
18 | ///
19 | public string ShortName { get; }
20 |
21 | ///
22 | /// Gets whether this parameter is optional
23 | ///
24 | public bool Optional { get; }
25 |
26 | ///
27 | /// Gets a default value for the parameter (or null if none has been specified)
28 | ///
29 | public string DefaultValue { get; }
30 |
31 | ///
32 | /// Gets whether this parameter can have its value resolved from the <appSettings>
section of the application configuration file.
33 | /// If the value is provided with a command-line switch, the provided value takes precedence.
34 | ///
35 | public bool AllowAppSetting { get; }
36 |
37 | ///
38 | /// Gets whether this parameter can have its value resolved from the <connectionStrings>
section of the application configuration file.
39 | /// If the value is provided with a command-line switch, the provided value takes precedence.
40 | ///
41 | public bool AllowConnectionString { get; }
42 |
43 | ///
44 | /// Gets whether this parameter can have its value resolved from an environment variable with the same name as specified by
45 | /// If the value is provided with a command-line switch, the provided value takes precedence.
46 | ///
47 | public bool AllowEnvironmentVariable { get; }
48 |
49 | ///
50 | /// Constructs the parameter attribute
51 | ///
52 | /// Primary name of the parameter
53 | /// Optional shorthand of the parameter
54 | /// Indicates whether the parameter MUST be specified or can be omitted
55 | /// Provides a default value to use when other values could not be found
56 | ///
57 | /// Indicates whether parameter value resolution can go and look in the <appSettings>
section of
58 | /// the current application configuration file for a value. Will look for the key specified by
59 | ///
60 | ///
61 | /// Indicates whether parameter value resolution can go and look in the <connectionStrings>
section of
62 | /// the current application configuration file for a value. Will look for the name specified by
63 | ///
64 | ///
65 | /// Indicates whether parameter value resolution can go and look for an environment variable for a value.
66 | /// Will look for the name specified by
67 | ///
68 | public ParameterAttribute(string name, string shortName = null, bool optional = false, string defaultValue = null, bool allowAppSetting = false, bool allowConnectionString = false, bool allowEnvironmentVariable = false)
69 | {
70 | Name = name;
71 | ShortName = shortName;
72 | Optional = optional;
73 | DefaultValue = defaultValue;
74 | AllowAppSetting = allowAppSetting;
75 | AllowConnectionString = allowConnectionString;
76 | AllowEnvironmentVariable = allowEnvironmentVariable;
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/GoCommando/SupportImpersonationAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to the class that has your Main
method in order to support impersonation
7 | ///
8 | [AttributeUsage(AttributeTargets.Class)]
9 | public class SupportImpersonationAttribute : Attribute
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/GoCommando_old/BannerAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to the class that has your Main
method in order to have a nice banner printed out when the program starts
7 | ///
8 | [AttributeUsage(AttributeTargets.Class)]
9 | public class BannerAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the banner text
13 | ///
14 | public string BannerText { get; }
15 |
16 | ///
17 | /// Constructs the attribute
18 | ///
19 | public BannerAttribute(string bannerText)
20 | {
21 | BannerText = bannerText;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/GoCommando_old/CommandAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Attribute that can be applied to a class that represents a command. The class must implement
7 | ///
8 | [AttributeUsage(AttributeTargets.Class)]
9 | public class CommandAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the name of the command
13 | ///
14 | public string Command { get; }
15 |
16 | ///
17 | /// Gets the name of the command's group (if any). Grouping commands affects how they are presented when printing
18 | /// help texts
19 | ///
20 | public string Group { get; }
21 |
22 | ///
23 | /// Constructs the attribute
24 | ///
25 | public CommandAttribute(string command, string group = null)
26 | {
27 | Command = command;
28 | Group = group ?? "";
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/GoCommando_old/DescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to a property of a command class (which is also decorated with ) in
7 | /// order to provide a description of the parameter
8 | ///
9 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
10 | public class DescriptionAttribute : Attribute
11 | {
12 | ///
13 | /// Gets the description text
14 | ///
15 | public string DescriptionText { get; }
16 |
17 | ///
18 | /// Constructs the attribute
19 | ///
20 | public DescriptionAttribute(string descriptionText)
21 | {
22 | DescriptionText = descriptionText;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/GoCommando_old/ExampleAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply one or more of these to a command property to show examples on how this particular parameter can be used
7 | ///
8 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
9 | public class ExampleAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the example text
13 | ///
14 | public string ExampleValue { get; }
15 |
16 | ///
17 | /// Constructs the attribute
18 | ///
19 | public ExampleAttribute(string exampleValue)
20 | {
21 | ExampleValue = exampleValue;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/GoCommando_old/ExitCodeException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace GoCommando
5 | {
6 | ///
7 | /// Exception that can be used to exit the program with a custom exit code
8 | ///
9 | [Serializable]
10 | public class CustomExitCodeException : Exception
11 | {
12 | ///
13 | /// Constructs the exception
14 | ///
15 | protected CustomExitCodeException(SerializationInfo info, StreamingContext context) : base(info, context)
16 | {
17 | }
18 |
19 | ///
20 | /// Constructs the exception
21 | ///
22 | public CustomExitCodeException(int exitCode, string message) : base(message)
23 | {
24 | ExitCode = exitCode;
25 | }
26 |
27 | ///
28 | /// Gets the exit code that the program must exit with
29 | ///
30 | public int ExitCode { get; }
31 | }
32 | }
--------------------------------------------------------------------------------
/GoCommando_old/GoCommando.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {2839AA55-B40A-4BB8-BDA0-C5057E5A683F}
8 | Library
9 | Properties
10 | GoCommando
11 | GoCommando
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | bin\Release\GoCommando.XML
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
76 |
--------------------------------------------------------------------------------
/GoCommando_old/GoCommandoException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace GoCommando
5 | {
6 | ///
7 | /// Friendly exception that can be thrown in cases where you want the program to exit with
8 | /// a nice, human-readable message. Only the message will be shown.
9 | ///
10 | [Serializable]
11 | public class GoCommandoException : Exception
12 | {
13 | ///
14 | /// Constructs the exception
15 | ///
16 | protected GoCommandoException(SerializationInfo info, StreamingContext context) : base(info, context)
17 | {
18 | }
19 |
20 | ///
21 | /// Constructs the exception
22 | ///
23 | public GoCommandoException(string message) : base(message)
24 | {
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/GoCommando_old/ICommand.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | ///
4 | /// Implement this interface on each command
5 | ///
6 | public interface ICommand
7 | {
8 | ///
9 | /// Main run method that is invoked by GoCommando
10 | ///
11 | void Run();
12 | }
13 | }
--------------------------------------------------------------------------------
/GoCommando_old/ICommandFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Can be implemented to supply a custom command factory that will be given a chance to create command instances
7 | /// and dispose of them after use
8 | ///
9 | public interface ICommandFactory
10 | {
11 | ///
12 | /// Should create a new command instance of the given
13 | ///
14 | ICommand Create(Type commandType);
15 |
16 | ///
17 | /// Should release the command instance - probably by disposing it or delegating the disposal to an IoC container
18 | ///
19 | void Release(ICommand command);
20 | }
21 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/Arguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace GoCommando.Internals
6 | {
7 | class Arguments
8 | {
9 | readonly Settings _settings;
10 |
11 | public Arguments(string command, IEnumerable switches, Settings settings)
12 | {
13 | _settings = settings;
14 | var switchList = switches.ToList();
15 | var duplicateSwitchKeys = switchList.GroupBy(s => s.Key).Where(g => g.Count() > 1).ToList();
16 |
17 | if (duplicateSwitchKeys.Any())
18 | {
19 | var dupes = string.Join(", ", duplicateSwitchKeys.Select(g => $"{settings.SwitchPrefix}{g.Key}"));
20 |
21 | throw new GoCommandoException($"The following switches have been specified more than once: {dupes}");
22 | }
23 |
24 | Command = command;
25 | Switches = switchList;
26 | }
27 |
28 | public string Command { get; }
29 |
30 | public IEnumerable Switches { get; }
31 |
32 | public TValue Get(string key)
33 | {
34 | var desiredType = typeof(TValue);
35 |
36 | try
37 | {
38 | if (desiredType == typeof(bool))
39 | {
40 | return (TValue)Convert.ChangeType(Switches.Any(s => s.Key == key), desiredType);
41 | }
42 |
43 | var relevantSwitch = Switches.FirstOrDefault(s => s.Key == key);
44 |
45 | if (relevantSwitch != null)
46 | {
47 | return (TValue)Convert.ChangeType(relevantSwitch.Value, desiredType);
48 | }
49 |
50 | throw new GoCommandoException($"Could not find switch '{key}'");
51 | }
52 | catch (Exception exception)
53 | {
54 | throw new FormatException($"Could not get switch '{key}' as a {desiredType}", exception);
55 | } }
56 |
57 | public override string ToString()
58 | {
59 | return $@"{Command}
60 |
61 | {string.Join(Environment.NewLine, Switches.Select(s => " " + s))}";
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/CommandInvoker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace GoCommando.Internals
7 | {
8 | class CommandInvoker
9 | {
10 | readonly Settings _settings;
11 | readonly ICommand _commandInstance;
12 | readonly Action _releaser;
13 | readonly List _parameters;
14 |
15 | public CommandInvoker(string command, Type type, Settings settings, string @group = null,
16 | ICommandFactory commandFactory = null)
17 | : this(command, settings, CreateInstance(type, GetFactoryMethod(commandFactory)), group, GetReleaseMethod(commandFactory))
18 | {
19 | }
20 |
21 | public CommandInvoker(string command, Settings settings, ICommand commandInstance, string group = null, Action releaseMethod = null)
22 | {
23 | if (command == null) throw new ArgumentNullException(nameof(command));
24 | if (settings == null) throw new ArgumentNullException(nameof(settings));
25 | if (commandInstance == null) throw new ArgumentNullException(nameof(commandInstance));
26 |
27 | _settings = settings;
28 | _commandInstance = commandInstance;
29 | _releaser = releaseMethod ?? DefaultReleaseMethod;
30 |
31 | Command = command;
32 | Group = group;
33 |
34 | _parameters = GetParameters(Type).ToList();
35 | }
36 |
37 | static void DefaultReleaseMethod(ICommand command)
38 | {
39 | var disposable = command as IDisposable;
40 |
41 | disposable?.Dispose();
42 | }
43 |
44 | static Func GetFactoryMethod(ICommandFactory commandFactory)
45 | {
46 | if (commandFactory == null) return null;
47 |
48 | return commandFactory.Create;
49 | }
50 |
51 | static Action GetReleaseMethod(ICommandFactory commandFactory)
52 | {
53 | if (commandFactory == null) return null;
54 |
55 | return commandFactory.Release;
56 | }
57 |
58 | static ICommand CreateInstance(Type type, Func commandFactory = null)
59 | {
60 | try
61 | {
62 | var instance = commandFactory?.Invoke(type)
63 | ?? Activator.CreateInstance(type);
64 |
65 | if (!(instance is ICommand))
66 | {
67 | throw new ApplicationException($"{instance} does not implement ICommand!");
68 | }
69 |
70 | return (ICommand)instance;
71 | }
72 | catch (Exception exception)
73 | {
74 | throw new ApplicationException($"Could not use type {type} as a GoCommando command", exception);
75 | }
76 | }
77 |
78 | static IEnumerable GetParameters(Type type)
79 | {
80 | return type
81 | .GetProperties()
82 | .Select(p => new
83 | {
84 | Property = p,
85 | ParameterAttribute = GetSingleAttributeOrNull(p),
86 | DescriptionAttribute = GetSingleAttributeOrNull(p),
87 | ExampleAttributes = p.GetCustomAttributes()
88 | })
89 | .Where(a => a.ParameterAttribute != null)
90 | .Select(a => new Parameter(a.Property,
91 | a.ParameterAttribute.Name,
92 | a.ParameterAttribute.ShortName,
93 | a.ParameterAttribute.Optional,
94 | a.DescriptionAttribute?.DescriptionText,
95 | a.ExampleAttributes.Select(e => e.ExampleValue),
96 | a.ParameterAttribute.DefaultValue,
97 | a.ParameterAttribute.AllowAppSetting,
98 | a.ParameterAttribute.AllowConnectionString,
99 | a.ParameterAttribute.AllowEnvironmentVariable))
100 | .ToList();
101 | }
102 |
103 | static TAttribute GetSingleAttributeOrNull(PropertyInfo p) where TAttribute : Attribute
104 | {
105 | return p.GetCustomAttributes(typeof(TAttribute), false)
106 | .Cast()
107 | .FirstOrDefault();
108 | }
109 |
110 | public string Group { get; }
111 |
112 | public string Command { get; }
113 |
114 | public Type Type => _commandInstance.GetType();
115 |
116 | public IEnumerable Parameters => _parameters;
117 |
118 | public string Description => Type.GetCustomAttribute()?.DescriptionText ??
119 | "(no help text for this command)";
120 |
121 | public ICommand CommandInstance => _commandInstance;
122 |
123 | public void Invoke(IEnumerable switches, EnvironmentSettings environmentSettings)
124 | {
125 | try
126 | {
127 | InnerInvoke(switches, environmentSettings);
128 | }
129 | finally
130 | {
131 | _releaser(CommandInstance);
132 | }
133 | }
134 |
135 | void InnerInvoke(IEnumerable switches, EnvironmentSettings environmentSettings)
136 | {
137 | var commandInstance = _commandInstance;
138 |
139 | var requiredParametersMissing = Parameters
140 | .Where(p => !p.Optional
141 | && !p.HasDefaultValue
142 | && !CanBeResolvedFromSwitches(switches, p)
143 | && !CanBeResolvedFromEnvironmentSettings(environmentSettings, p))
144 | .ToList();
145 |
146 | var optionalParamtersNotSpecified = Parameters
147 | .Where(p => p.Optional
148 | && !CanBeResolvedFromSwitches(switches, p)
149 | && !CanBeResolvedFromEnvironmentSettings(environmentSettings, p))
150 | .ToList();
151 |
152 | if (requiredParametersMissing.Any())
153 | {
154 | var requiredParametersMissingString = string.Join(Environment.NewLine,
155 | requiredParametersMissing.Select(p => $" {_settings.SwitchPrefix}{p.Name} - {p.DescriptionText}"));
156 |
157 | var text = $@"The following required parameters are missing:
158 |
159 | {requiredParametersMissingString}";
160 |
161 | if (optionalParamtersNotSpecified.Any())
162 | {
163 | var optionalParamtersNotSpecifiedString = string.Join(Environment.NewLine,
164 | optionalParamtersNotSpecified.Select(p => $" {_settings.SwitchPrefix}{p.Name} - {p.DescriptionText}"));
165 |
166 | var moreText = $@"The following optional parameters are also available:
167 |
168 | {optionalParamtersNotSpecifiedString}";
169 |
170 | throw new GoCommandoException(string.Concat(
171 | text,
172 | Environment.NewLine,
173 | Environment.NewLine,
174 | moreText
175 | ));
176 | }
177 |
178 | throw new GoCommandoException(text);
179 | }
180 |
181 | var switchesWithoutMathingParameter = switches
182 | .Where(s => !Parameters.Any(p => p.MatchesKey(s.Key)))
183 | .ToList();
184 |
185 | if (switchesWithoutMathingParameter.Any())
186 | {
187 | var switchesWithoutMathingParameterString = string.Join(Environment.NewLine,
188 | switchesWithoutMathingParameter.Select(p => p.Value != null
189 | ? $" {_settings.SwitchPrefix}{p.Key} = {p.Value}"
190 | : $" {_settings.SwitchPrefix}{p.Key}"));
191 |
192 | throw new GoCommandoException(
193 | $@"The following switches do not have a corresponding parameter:
194 |
195 | {switchesWithoutMathingParameterString}");
196 | }
197 |
198 | var setParameters = new HashSet();
199 |
200 | ResolveParametersFromSwitches(switches, commandInstance, setParameters);
201 |
202 | ResolveParametersFromEnvironmentSettings(environmentSettings, commandInstance, setParameters, Parameters);
203 |
204 | ResolveParametersWithDefaultValues(setParameters, commandInstance);
205 |
206 | commandInstance.Run();
207 | }
208 |
209 | static void ResolveParametersFromEnvironmentSettings(EnvironmentSettings environmentSettings, ICommand commandInstance, HashSet setParameters, IEnumerable parameters)
210 | {
211 | foreach (var parameter in parameters.Where(p => p.AllowAppSetting && !setParameters.Contains(p)))
212 | {
213 | if (!environmentSettings.HasAppSetting(parameter.Name)) continue;
214 |
215 | var appSettingValue = environmentSettings.GetAppSetting(parameter.Name);
216 |
217 | SetParameter(commandInstance, setParameters, parameter, appSettingValue);
218 | }
219 |
220 | foreach (var parameter in parameters.Where(p => p.AllowConnectionString && !setParameters.Contains(p)))
221 | {
222 | if (!environmentSettings.HasConnectionString(parameter.Name)) continue;
223 |
224 | var appSettingValue = environmentSettings.GetConnectionString(parameter.Name);
225 |
226 | SetParameter(commandInstance, setParameters, parameter, appSettingValue);
227 | }
228 |
229 | foreach (var parameter in parameters.Where(p => p.AllowEnvironmentVariable && !setParameters.Contains(p)))
230 | {
231 | if (!environmentSettings.HasEnvironmentVariable(parameter.Name)) continue;
232 |
233 | var appSettingValue = environmentSettings.GetEnvironmentVariable(parameter.Name);
234 |
235 | SetParameter(commandInstance, setParameters, parameter, appSettingValue);
236 | }
237 | }
238 |
239 | void ResolveParametersWithDefaultValues(IEnumerable setParameters, ICommand commandInstance)
240 | {
241 | foreach (var parameterWithDefaultValue in Parameters.Where(p => p.HasDefaultValue).Except(setParameters))
242 | {
243 | parameterWithDefaultValue.ApplyDefaultValue(commandInstance);
244 | }
245 | }
246 |
247 | void ResolveParametersFromSwitches(IEnumerable switches, ICommand commandInstance, ISet setParameters)
248 | {
249 | foreach (var switchToSet in switches)
250 | {
251 | var correspondingParameter = Parameters.FirstOrDefault(p => p.MatchesKey(switchToSet.Key));
252 |
253 | if (correspondingParameter == null)
254 | {
255 | throw new GoCommandoException(
256 | $"The switch {_settings}{switchToSet.Key} does not correspond to a parameter of the '{Command}' command!");
257 | }
258 |
259 | var value = switchToSet.Value;
260 |
261 | SetParameter(commandInstance, setParameters, correspondingParameter, value);
262 | }
263 | }
264 |
265 | static void SetParameter(ICommand commandInstance, ISet setParameters, Parameter parameter, string value)
266 | {
267 | parameter.SetValue(commandInstance, value);
268 | setParameters.Add(parameter);
269 | }
270 |
271 | static bool CanBeResolvedFromEnvironmentSettings(EnvironmentSettings environmentSettings, Parameter parameter)
272 | {
273 | var name = parameter.Name;
274 |
275 | if (parameter.AllowAppSetting && environmentSettings.HasAppSetting(name))
276 | {
277 | return true;
278 | }
279 |
280 | if (parameter.AllowConnectionString && environmentSettings.HasConnectionString(name))
281 | {
282 | return true;
283 | }
284 |
285 | if (parameter.AllowEnvironmentVariable && environmentSettings.HasEnvironmentVariable(name))
286 | {
287 | return true;
288 | }
289 |
290 | return false;
291 | }
292 |
293 | static bool CanBeResolvedFromSwitches(IEnumerable switches, Parameter p)
294 | {
295 | return switches.Any(s => p.MatchesKey(s.Key));
296 | }
297 | }
298 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/EnvironmentSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace GoCommando.Internals
5 | {
6 | class EnvironmentSettings
7 | {
8 | static readonly IDictionary None = new Dictionary();
9 | public static readonly EnvironmentSettings Empty = new EnvironmentSettings(None, None);
10 |
11 | readonly IDictionary _appSettings;
12 | readonly IDictionary _connectionStrings;
13 | readonly IDictionary _environmentVariables;
14 |
15 | public EnvironmentSettings(IDictionary appSettings = null, IDictionary connectionStrings = null, IDictionary environmentVariables = null)
16 | {
17 | _environmentVariables = environmentVariables ?? None;
18 | _appSettings = appSettings ?? None;
19 | _connectionStrings = connectionStrings ?? None;
20 | }
21 |
22 | public bool HasAppSetting(string name)
23 | {
24 | return _appSettings.ContainsKey(name);
25 | }
26 |
27 | public bool HasConnectionString(string name)
28 | {
29 | return _connectionStrings.ContainsKey(name);
30 | }
31 |
32 | public bool HasEnvironmentVariable(string name)
33 | {
34 | return _environmentVariables.ContainsKey(name);
35 | }
36 |
37 | public string GetAppSetting(string key)
38 | {
39 | try
40 | {
41 | return _appSettings[key];
42 | }
43 | catch (Exception exception)
44 | {
45 | throw new KeyNotFoundException($"Could not find appSetting with key '{key}'", exception);
46 | }
47 | }
48 |
49 | public string GetEnvironmentVariable(string name)
50 | {
51 | try
52 | {
53 | return _environmentVariables[name];
54 | }
55 | catch (Exception exception)
56 | {
57 | throw new KeyNotFoundException($"Could not find environment variable with the name '{name}'", exception);
58 | }
59 | }
60 |
61 | public string GetConnectionString(string name)
62 | {
63 | try
64 | {
65 | return _connectionStrings[name];
66 | }
67 | catch (Exception exception)
68 | {
69 | throw new KeyNotFoundException($"Could not find connectionString with key '{name}'", exception);
70 | }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/Parameter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace GoCommando.Internals
7 | {
8 | class Parameter : IEquatable
9 | {
10 | public PropertyInfo PropertyInfo { get; }
11 | public string Name { get; }
12 | public string Shortname { get; }
13 | public bool Optional { get; }
14 | public string DescriptionText { get; }
15 | public string DefaultValue { get; }
16 | public bool AllowAppSetting { get; }
17 | public bool AllowConnectionString { get; }
18 | public bool AllowEnvironmentVariable { get; }
19 | public string[] ExampleValues { get; }
20 |
21 | public bool IsFlag => PropertyInfo.PropertyType == typeof(bool);
22 |
23 | public bool HasDefaultValue => DefaultValue != null;
24 |
25 | public Parameter(PropertyInfo propertyInfo, string name, string shortname, bool optional, string descriptionText, IEnumerable exampleValues, string defaultValue, bool allowAppSetting, bool allowConnectionString, bool allowEnvironmentVariable)
26 | {
27 | PropertyInfo = propertyInfo;
28 | Name = name;
29 | Shortname = shortname;
30 | Optional = optional;
31 | DescriptionText = GetText(descriptionText, allowAppSetting, allowConnectionString, allowEnvironmentVariable);
32 | DefaultValue = defaultValue;
33 | AllowAppSetting = allowAppSetting;
34 | AllowConnectionString = allowConnectionString;
35 | AllowEnvironmentVariable = allowEnvironmentVariable;
36 | ExampleValues = exampleValues.ToArray();
37 | }
38 |
39 | private string GetText(string descriptionText, bool allowAppSetting, bool allowConnectionString, bool allowEnvironmentVariable)
40 | {
41 | if (!allowAppSetting && !allowConnectionString && !allowEnvironmentVariable)
42 | {
43 | return $"{descriptionText ?? ""}";
44 | }
45 |
46 | var autoBindings = new List();
47 |
48 | if (allowEnvironmentVariable)
49 | {
50 | autoBindings.Add("ENV");
51 | }
52 |
53 | if (allowAppSetting)
54 | {
55 | autoBindings.Add("APP");
56 | }
57 |
58 | if (allowConnectionString)
59 | {
60 | autoBindings.Add("CONN");
61 | }
62 |
63 | return $"{descriptionText ?? ""} ({string.Join(", ", autoBindings)})";
64 | }
65 |
66 | public bool MatchesKey(string key)
67 | {
68 | return key == Name
69 | || (Shortname != null && key == Shortname);
70 | }
71 |
72 | public void SetValue(object commandInstance, string value)
73 | {
74 | try
75 | {
76 | var valueInTheRightType = PropertyInfo.PropertyType == typeof(bool)
77 | ? true
78 | : Convert.ChangeType(value, PropertyInfo.PropertyType);
79 |
80 | PropertyInfo.SetValue(commandInstance, valueInTheRightType);
81 | }
82 | catch (Exception exception)
83 | {
84 | throw new FormatException($"Could not set value '{value}' on property named '{PropertyInfo.Name}' on {PropertyInfo.DeclaringType}", exception);
85 | }
86 | }
87 |
88 | public void ApplyDefaultValue(ICommand commandInstance)
89 | {
90 | if (!HasDefaultValue)
91 | {
92 | throw new InvalidOperationException($"Cannot apply default value of '{Name}' parameter because it has no default!");
93 | }
94 |
95 | SetValue(commandInstance, DefaultValue);
96 | }
97 |
98 | public bool Equals(Parameter other)
99 | {
100 | return Name.Equals(other.Name);
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/Settings.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Internals
2 | {
3 | class Settings
4 | {
5 | public Settings()
6 | {
7 | SwitchPrefix = "-";
8 | }
9 |
10 | public string SwitchPrefix { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 |
5 | namespace GoCommando.Internals
6 | {
7 | static class StringExtensions
8 | {
9 | public static string WrappedAt(this string str, int width)
10 | {
11 | var twoLineBreaks = Environment.NewLine + Environment.NewLine;
12 |
13 | var sections = str.Split(new[] { twoLineBreaks },
14 | StringSplitOptions.RemoveEmptyEntries);
15 |
16 | return string.Join(twoLineBreaks, sections.Select(section => WrapSection(section, width)));
17 | }
18 |
19 | static string WrapSection(string section, int width)
20 | {
21 | var oneLongString = string.Join(" ",
22 | section.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries));
23 |
24 | var words = oneLongString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
25 |
26 | var builder = new StringBuilder();
27 |
28 | var currentLineLength = 0;
29 |
30 | for (var index = 0; index < words.Length; index++)
31 | {
32 | var word = words[index];
33 | builder.Append(word);
34 | currentLineLength += word.Length;
35 |
36 | if (index < words.Length - 1)
37 | {
38 | var nextWord = words[index];
39 |
40 | var spaceLeftOnCurrentLine = width - currentLineLength - 1; // -1 to leave room for space...
41 | var nextWordIsTooLong = nextWord.Length > spaceLeftOnCurrentLine;
42 |
43 | if (nextWordIsTooLong)
44 | {
45 | builder.AppendLine();
46 | currentLineLength = 0;
47 | }
48 | else
49 | {
50 | builder.Append(" ");
51 | currentLineLength++;
52 | }
53 | }
54 | }
55 |
56 | return builder.ToString();
57 | }
58 |
59 | public static string Indented(this string str, int indent)
60 | {
61 | var indentedLines = str
62 | .Split(new[] { Environment.NewLine }, StringSplitOptions.None)
63 | .Select(line => string.Concat(new string(' ', indent), line));
64 |
65 | return string.Join(Environment.NewLine, indentedLines);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/GoCommando_old/Internals/Switch.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable LoopCanBeConvertedToQuery
2 | namespace GoCommando.Internals
3 | {
4 | class Switch
5 | {
6 | static readonly char[] AcceptedQuoteCharacters = { '"', '\'' };
7 |
8 | public static Switch KeyValue(string key, string value)
9 | {
10 | return new Switch(key, value);
11 | }
12 |
13 | public static Switch Flag(string key)
14 | {
15 | return new Switch(key, null);
16 | }
17 |
18 | Switch(string key, string value)
19 | {
20 | Key = key;
21 | Value = Unquote(value);
22 | }
23 |
24 | static string Unquote(string value)
25 | {
26 | if (value == null) return null;
27 |
28 | // can't be quoted
29 | if (value.Length < 2) return value;
30 |
31 | foreach (var quoteChar in AcceptedQuoteCharacters)
32 | {
33 | var quote = quoteChar.ToString();
34 |
35 | if (value.StartsWith(quote)
36 | && value.EndsWith(quote))
37 | {
38 | return value.Substring(1, value.Length - 2);
39 | }
40 | }
41 |
42 | return value;
43 | }
44 |
45 | public string Key { get; }
46 | public string Value { get; }
47 |
48 | public override string ToString()
49 | {
50 | return Value == null
51 | ? Key
52 | : $"{Key} = {Value}";
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/GoCommando_old/ParameterAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to a property of a command class (i.e. one that implements )
7 | ///
8 | [AttributeUsage(AttributeTargets.Property)]
9 | public class ParameterAttribute : Attribute
10 | {
11 | ///
12 | /// Gets the primary parameter name
13 | ///
14 | public string Name { get; }
15 |
16 | ///
17 | /// Gets a shorthand for the parameter (or null if none has been specified)
18 | ///
19 | public string ShortName { get; }
20 |
21 | ///
22 | /// Gets whether this parameter is optional
23 | ///
24 | public bool Optional { get; }
25 |
26 | ///
27 | /// Gets a default value for the parameter (or null if none has been specified)
28 | ///
29 | public string DefaultValue { get; }
30 |
31 | ///
32 | /// Gets whether this parameter can have its value resolved from the <appSettings>
section of the application configuration file.
33 | /// If the value is provided with a command-line switch, the provided value takes precedence.
34 | ///
35 | public bool AllowAppSetting { get; }
36 |
37 | ///
38 | /// Gets whether this parameter can have its value resolved from the <connectionStrings>
section of the application configuration file.
39 | /// If the value is provided with a command-line switch, the provided value takes precedence.
40 | ///
41 | public bool AllowConnectionString { get; }
42 |
43 | ///
44 | /// Gets whether this parameter can have its value resolved from an environment variable with the same name as specified by
45 | /// If the value is provided with a command-line switch, the provided value takes precedence.
46 | ///
47 | public bool AllowEnvironmentVariable { get; }
48 |
49 | ///
50 | /// Constructs the parameter attribute
51 | ///
52 | /// Primary name of the parameter
53 | /// Optional shorthand of the parameter
54 | /// Indicates whether the parameter MUST be specified or can be omitted
55 | /// Provides a default value to use when other values could not be found
56 | ///
57 | /// Indicates whether parameter value resolution can go and look in the <appSettings>
section of
58 | /// the current application configuration file for a value. Will look for the key specified by
59 | ///
60 | ///
61 | /// Indicates whether parameter value resolution can go and look in the <connectionStrings>
section of
62 | /// the current application configuration file for a value. Will look for the name specified by
63 | ///
64 | ///
65 | /// Indicates whether parameter value resolution can go and look for an environment variable for a value.
66 | /// Will look for the name specified by
67 | ///
68 | public ParameterAttribute(string name, string shortName = null, bool optional = false, string defaultValue = null, bool allowAppSetting = false, bool allowConnectionString = false, bool allowEnvironmentVariable = false)
69 | {
70 | Name = name;
71 | ShortName = shortName;
72 | Optional = optional;
73 | DefaultValue = defaultValue;
74 | AllowAppSetting = allowAppSetting;
75 | AllowConnectionString = allowConnectionString;
76 | AllowEnvironmentVariable = allowEnvironmentVariable;
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/GoCommando_old/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GoCommando")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GoCommando")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("2839aa55-b40a-4bb8-bda0-c5057e5a683f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 | [assembly: InternalsVisibleTo("GoCommando.Tests")]
--------------------------------------------------------------------------------
/GoCommando_old/SupportImpersonationAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | ///
6 | /// Apply this attribute to the class that has your Main
method in order to support impersonation
7 | ///
8 | [AttributeUsage(AttributeTargets.Class)]
9 | public class SupportImpersonationAttribute : Attribute
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/Package.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | GoCommando
5 | $version$
6 | Mogens Heller Grabe
7 | Mogens Heller Grabe
8 | http://en.wikipedia.org/wiki/Beerware
9 | http://mookid.dk/oncode/gocommando
10 | GoCommando is a small command line utility helper that does the boring work when creating command line utilities in .NET.
11 | Copyright 2015
12 | command-line go-commando
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | What?
2 | ====
3 |
4 | GoCommando is a small command line utility helper that does the boring work when creating command line utilities in .NET.
5 |
6 | More info coming soon at http://mookid.dk/gocommando
7 |
8 | One day, maybe I'll tweet something as well... [@mookid8000][2]
9 |
10 | How?
11 | ====
12 |
13 | Create a new console application. `Install-Package GoCommando` to get the DLL, and then `Go.Run()` in the `Main` method.
14 |
15 | And then you add some classes that implement `ICommand` and you decorate them with `[Command]` and
16 | then you add properties to those classes, and then you decorate those with `[Parameter]`.
17 |
18 | And then you decorate the command class and the parameter properties with `[Description]`.
19 |
20 | And then you add a couple of `[Example]` to some of the parameter properties, just to be nice.
21 |
22 | Example!
23 | ====
24 |
25 | This is the `white-russian` command in a fictive Beverage utility:
26 |
27 |
28 | [Command("white-russian")]
29 | [Description("Mixes a White Russian, pouring in milk till full")]
30 | public class WhiteRussian : ICommand
31 | {
32 | [Parameter("vodka")]
33 | [Description("How many cl of vodka?")]
34 | public double Vodka { get; set; }
35 |
36 | [Parameter("kahlua")]
37 | [Description("How many cl of Kahlua?")]
38 | public double Kahlua { get; set; }
39 |
40 | [Parameter("lukewarm", optional: true)]
41 | [Description("Avoid refrigerated ingredients?")]
42 | public bool LukeWarm { get; set; }
43 |
44 | public void Run()
45 | {
46 | Console.WriteLine($"Making a {(LukeWarm ? "luke-warm" : "")} beverage" +
47 | $" with {Vodka:0.#} cl of vodka" +
48 | $" and {Kahlua:0.#} cl of Kahlua");
49 | }
50 | }
51 |
52 | If you invoke it without its command, it will print out the available commands:
53 |
54 | C:\> beverage.exe
55 |
56 | ------------------------------
57 | Beverage Utility
58 |
59 | Copyright (c) 2015 El Duderino
60 | ------------------------------
61 | Please invoke with a command - the following commands are available:
62 |
63 | white-russian - Mixes a White Russian, pouring in milk till full
64 |
65 | Invoke with -help to get help for each command.
66 |
67 | Exit code: -1
68 |
69 | and then, if you add `-help white-russian` as an argument, you'll get detailed help for that command:
70 |
71 | C:\> beverage.exe -help white-russian
72 |
73 | ------------------------------
74 | Beverage Utility
75 |
76 | Copyright (c) 2015 El Duderino
77 | ------------------------------
78 | Mixes a White Russian, pouring in milk till full
79 |
80 | Type
81 |
82 | Beverage.exe white-russian
83 |
84 | where can consist of the following parameters:
85 |
86 | -vodka
87 | How many cl of vodka?
88 |
89 | -kahlua
90 | How many cl of Kahlua?
91 |
92 | -lukewarm (flag/optional)
93 | Avoid refrigerated ingredients?
94 |
95 | If you try to invoke a command, and one or more of the arguments are missing, you'll know:
96 |
97 | C:\> beverage white-russian -vodka 1
98 |
99 | ------------------------------
100 | Beverage Utility
101 |
102 | Copyright (c) 2015 El Duderino
103 | ------------------------------
104 | The following required parameters are missing:
105 |
106 | -kahlua - How many cl of Kahlua?
107 |
108 | Invoke with -help to get help for each command.
109 |
110 | Exit code: -1
111 |
112 | and then, when you finally invoke the command with the right arguments, it'll run as you would probably expect:
113 |
114 | C:\> beverage white-russian -vodka 2 -kahlua 2
115 |
116 | ------------------------------
117 | Beverage Utility
118 |
119 | Copyright (c) 2015 El Duderino
120 | ------------------------------
121 | Making a beverage with 2 cl of vodka and 2 cl of Kahlua
122 |
123 | Neat.
124 |
125 | License
126 | ====
127 |
128 | GoCommando is [Beer-ware][1].
129 |
130 | [1]: http://en.wikipedia.org/wiki/Beerware
131 | [2]: http://twitter.com/mookid8000
132 |
--------------------------------------------------------------------------------
/TestApp2_old/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TestApp2_old/ElCommandante.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace TestApp2
5 | {
6 | [Command("el-commandante")]
7 | public class ElCommandante : ICommand
8 | {
9 | public ElCommandante(string text)
10 | {
11 | Text = text;
12 | }
13 |
14 | public string Text { get; }
15 |
16 | public void Run()
17 | {
18 | Console.WriteLine($"hoy!: {Text}");
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/TestApp2_old/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace TestApp2
5 | {
6 | class Program
7 | {
8 | static void Main()
9 | {
10 | Go.Run();
11 | }
12 | }
13 |
14 | class CustomFactory : ICommandFactory
15 | {
16 | public ICommand Create(Type commandType)
17 | {
18 | if (commandType == typeof(ElCommandante))
19 | {
20 | return new ElCommandante("che!");
21 | }
22 |
23 | throw new ArgumentException($"Unknown command type: {commandType}");
24 | }
25 |
26 | public void Release(ICommand command)
27 | {
28 | Console.WriteLine($"imonna let you go: {command}");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/TestApp2_old/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TestApp2")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestApp2")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("07010b53-b1cb-4696-8bb4-dca2943b6b59")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/TestApp2_old/TestApp2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {07010B53-B1CB-4696-8BB4-DCA2943B6B59}
8 | Exe
9 | Properties
10 | TestApp2
11 | TestApp2
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
60 |
--------------------------------------------------------------------------------
/TestApp_old/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/TestApp_old/Commands/NewCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace TestApp.Commands
5 | {
6 | [Command("new")]
7 | [Description("Does something new")]
8 | public class NewCommand : ICommand
9 | {
10 | [Parameter("qid")]
11 | public string QueryId { get; set; }
12 |
13 | public void Run()
14 | {
15 | Console.WriteLine($"QueryId {QueryId}");
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/TestApp_old/Commands/RunCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace TestApp.Commands
5 | {
6 | [Command("run")]
7 | [Description("Runs the program")]
8 | public class RunCommand : ICommand
9 | {
10 | [Description("Specifies the path with which stuff is to be done")]
11 | [Parameter("path", shortName: "p")]
12 | [Example(@"c:\temp\somefile.json")]
13 | public string Path { get; set; }
14 |
15 | [Parameter("dir")]
16 | [Example(@"C:\temp")]
17 | [Example(@"C:\windows\microsoft.net")]
18 | [Example(@"C:\windows\system32")]
19 | public string Dir { get; set; }
20 |
21 | [Parameter("flag")]
22 | public bool Flag { get; set; }
23 |
24 | [Parameter("moreflag", shortName: "m")]
25 | public bool MoreFlag { get; set; }
26 |
27 | [Parameter("optionalFlag", optional: true)]
28 | public bool OptionalFlag { get; set; }
29 |
30 | public void Run()
31 | {
32 | Console.WriteLine($@"Running!
33 |
34 | Path: {Path}
35 | Dir: {Dir}
36 | Flag: {Flag}
37 | MFlag: {MoreFlag},
38 | OFlag: {OptionalFlag}");
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/TestApp_old/Commands/StopCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace TestApp.Commands
5 | {
6 | [Command("stop")]
7 | public class StopCommand : ICommand
8 | {
9 | [Parameter("bimse", defaultValue: "default_value")]
10 | public string Bimse { get; set; }
11 |
12 | public void Run()
13 | {
14 | Console.WriteLine("BIMSE: {0}", Bimse);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/TestApp_old/Commands/TestAppConfigBinding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GoCommando;
3 |
4 | namespace TestApp.Commands
5 | {
6 | [Command("appconfig")]
7 | public class TestAppConfigBinding : ICommand
8 | {
9 | [Parameter("appSettingsKey", allowAppSetting: true)]
10 | [Description("Demonstrates how an appSetting can be automatically bound")]
11 | public string AppSetting { get; set; }
12 |
13 | [Parameter("connectionStringsName", allowConnectionString: true)]
14 | [Description("Demonstrates how a connectionString can be automatically bound")]
15 | public string ConnectionString { get; set; }
16 |
17 | [Parameter("windir", allowEnvironmentVariable: true)]
18 | [Description("Demonstrates how an environment variable can be automatically bound")]
19 | public string EnvironmentVariable { get; set; }
20 |
21 | public void Run()
22 | {
23 | Console.WriteLine($@"AppSetting: {AppSetting}
24 |
25 | ConnectionString: {ConnectionString}
26 |
27 | EnvironmentVariable: {EnvironmentVariable}");
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/TestApp_old/Program.cs:
--------------------------------------------------------------------------------
1 | using GoCommando;
2 |
3 | namespace TestApp
4 | {
5 | [Banner(@"------------------------
6 | Welcome to GoCommando v2
7 | ------------------------")]
8 | class Program
9 | {
10 | static void Main()
11 | {
12 | Go.Run();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/TestApp_old/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TestApp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestApp")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("1dc7365e-e01d-477a-82f7-2bc5efc51640")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/TestApp_old/TestApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {1DC7365E-E01D-477A-82F7-2BC5EFC51640}
8 | Exe
9 | Properties
10 | TestApp
11 | TestApp
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/build.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | echo GoCommand build thing.
4 | echo.
5 |
6 | set buildVersion=%1
7 |
8 | set outputPath="%~dp0\deploy"
9 |
10 | if exist "%outputPath%" (
11 | rd "%outputPath%" /s/q
12 | )
13 |
14 | mkdir "%outputPath%"
15 |
16 | if "%buildVersion%"=="" (
17 | echo.
18 | echo Please specify which version to build as an argument
19 | echo.
20 | goto exit
21 | )
22 |
23 | echo Building version %buildVersion%...
24 |
25 | msbuild GoCommando\GoCommando.csproj -P:Configuration=Release
26 |
27 | echo Tagging...
28 |
29 | git tag %buildVersion%
30 |
31 | echo Packing...
32 |
33 | nuget\nuget pack Package.nuspec -out %outputPath% -version %buildVersion%
34 |
35 | echo Pushing...
36 |
37 | git push
38 | git push --tags
39 |
40 | :exit
41 |
--------------------------------------------------------------------------------
/nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/nuget/NuGet.exe
--------------------------------------------------------------------------------
/old/.gitignore:
--------------------------------------------------------------------------------
1 | obj
2 | bin
3 | deploy
4 | deploy/*
5 | _ReSharper.*
6 | *.csproj.user
7 | *.resharper.user
8 | *.resharper
9 | *.suo
10 | *.cache
11 | ~$*
--------------------------------------------------------------------------------
/old/Package.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | GoCommando
5 | 0.2
6 | Mogens Heller Grabe
7 | Mogens Heller Grabe
8 | http://en.wikipedia.org/wiki/Beerware
9 | http://mookid.dk/oncode/gocommando
10 | GoCommando is a small command line utility helper that does the boring work when creating command line utilities in .NET.
11 | Copyright 2011
12 | command-line
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/old/README.md:
--------------------------------------------------------------------------------
1 | What?
2 | ====
3 |
4 | GoCommando is a small command line utility helper that does the boring work when creating command line utilities in .NET.
5 |
6 | More info coming soon at http://mookid.dk/oncode/gocommando
7 |
8 | One day, maybe I'll tweet something as well... [@mookid8000][2]
9 |
10 | How?
11 | ====
12 |
13 | Create a new console application. `Install-Package GoCommando` to get the DLL, and then `Go.Run(args)` in the `Main` method.
14 |
15 | License
16 | ====
17 |
18 | GoCommando is [Beer-ware][1].
19 |
20 | [1]: http://en.wikipedia.org/wiki/Beerware
21 | [2]: http://twitter.com/#!/mookid8000
--------------------------------------------------------------------------------
/old/build.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | msbuild scripts\build.proj
--------------------------------------------------------------------------------
/old/lib/nunit/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/old/lib/nunit/nunit.framework.dll
--------------------------------------------------------------------------------
/old/lib/rhino/Rhino.Mocks.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/old/lib/rhino/Rhino.Mocks.dll
--------------------------------------------------------------------------------
/old/scripts/build.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ..\deploy
8 | ..\tools
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/old/src/GoCommando.ConsoleApplication/GoCommando.ConsoleApplication.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {8F0347E7-51AF-42F8-A259-F5DE19C6D858}
9 | Exe
10 | Properties
11 | GoCommando.ConsoleApplication
12 | GoCommando.ConsoleApplication
13 | v3.5
14 | 512
15 |
16 |
17 | 3.5
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 | 3.5
41 |
42 |
43 | 3.5
44 |
45 |
46 | 3.5
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}
58 | GoCommando
59 |
60 |
61 |
62 |
69 |
--------------------------------------------------------------------------------
/old/src/GoCommando.ConsoleApplication/Program.cs:
--------------------------------------------------------------------------------
1 | using GoCommando.Api;
2 | using GoCommando.Attributes;
3 |
4 | namespace GoCommando.ConsoleApplication
5 | {
6 | [Banner(@"This is a sample command line app
7 |
8 | (c) Some Dude 2010")]
9 | class Program : ICommando
10 | {
11 | [PositionalArgument]
12 | [Description("The path to the file you wish to do stuff to")]
13 | [Example("c:\\temp\\somefile.txt")]
14 | [Example("c:\\temp\\anotherfile.txt")]
15 | public string Path { get; set; }
16 |
17 | [PositionalArgument]
18 | [Description("The value of something")]
19 | [Example("59")]
20 | public double Value { get; set; }
21 |
22 | [NamedArgument("someflag", "sf")]
23 | [Description("Extra-special flag")]
24 | public bool SomeFlag { get; set; }
25 |
26 | [NamedArgument("anotherflag", "af")]
27 | [Description("Pretty important flag")]
28 | public bool AnotherFlag { get; set; }
29 |
30 | [NamedArgument("someValue", "sv")]
31 | [Description("An integer value specifying something important")]
32 | [Example("1"), Example("2"), Example("3")]
33 | public int SomeValue { get; set; }
34 |
35 | [NamedArgument("anotherValue", "av")]
36 | public string AnotherValue { get; set; }
37 |
38 | static void Main(string[] args)
39 | {
40 | Go.Run(args);
41 | }
42 |
43 | public void Run()
44 | {
45 | // Console.WriteLine(@"Path: {0} (expected: c:\program files\somepath\somefile.txt)
46 | //Value: {1} (expected 34.67)
47 | //Some flag: {2} (expected True)
48 | //Some value: {3} (expected 23))
49 | //Another value: {4} (expected bim)
50 | //Another flag: {5} (expected False)",
51 | // Path,
52 | // Value,
53 | // SomeFlag,
54 | // SomeValue,
55 | // AnotherValue,
56 | // AnotherFlag);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/old/src/GoCommando.ConsoleApplication/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("GoCommando.ConsoleApplication")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("GoCommando.ConsoleApplication")]
12 | [assembly: AssemblyCopyright("Copyright © 2010")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("298263a2-6fac-4412-a9a8-c4d20d06cc4e")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/FixtureBase.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 |
3 | namespace GoCommando.Tests
4 | {
5 | public abstract class FixtureBase
6 | {
7 | [SetUp]
8 | public void SetUp()
9 | {
10 | DoSetUp();
11 | }
12 |
13 | protected virtual void DoSetUp()
14 | {
15 | }
16 |
17 | [TearDown]
18 | public void TearDown()
19 | {
20 | DoTearDown();
21 | }
22 |
23 | protected virtual void DoTearDown()
24 | {
25 | }
26 |
27 | [TestFixtureSetUp]
28 | public void TestFixtureSetUp()
29 | {
30 | DoTestFixtureSetUp();
31 | }
32 |
33 | protected virtual void DoTestFixtureSetUp()
34 | {
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/GoCommando.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {12BCC57F-5D0B-496E-B47A-BD2A85190D48}
9 | Library
10 | Properties
11 | GoCommando.Tests
12 | GoCommando.Tests
13 | v3.5
14 | 512
15 |
16 |
17 | 3.5
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 | False
40 | ..\..\lib\nunit\nunit.framework.dll
41 |
42 |
43 |
44 | 3.5
45 |
46 |
47 | 3.5
48 |
49 |
50 | 3.5
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}
66 | GoCommando
67 |
68 |
69 |
70 |
71 |
72 |
73 |
80 |
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/Helpers/TestArgParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Timers;
4 | using GoCommando.Helpers;
5 | using GoCommando.Parameters;
6 | using NUnit.Framework;
7 |
8 | namespace GoCommando.Tests.Helpers
9 | {
10 | [TestFixture]
11 | public class TestArgParser : FixtureBase
12 | {
13 | ArgParser parser;
14 |
15 | protected override void DoSetUp()
16 | {
17 | parser = new ArgParser();
18 | }
19 |
20 | [Test]
21 | public void CanParseParameterWithAbsolutePath()
22 | {
23 | var parameter = parser.Parse(new[]{"-path:c:\\temp\\someFile.txt"})
24 | .Cast().Single();
25 |
26 | Assert.AreEqual("path", parameter.Name);
27 | Assert.AreEqual("c:\\temp\\someFile.txt", parameter.Value);
28 | }
29 |
30 | [Test]
31 | public void IndexIsOneBased()
32 | {
33 | var parameters = parser.Parse(new[]{"firstArg", "secondArg"})
34 | .Cast().ToList();
35 |
36 | Assert.AreEqual(1, parameters[0].Index);
37 | Assert.AreEqual(2, parameters[1].Index);
38 | }
39 |
40 | [Test]
41 | public void EmptyArrayYieldsNoArguments()
42 | {
43 | var timer = new Timer();
44 | timer.Elapsed += (_, __) => Console.WriteLine("hej");
45 | timer.Start();
46 |
47 | var args1 = new string[0];
48 | var args2 = new[]{"", " ", ""};
49 | AssertYieldsNoParameters(args1);
50 | AssertYieldsNoParameters(args2);
51 | }
52 |
53 | [Test]
54 | public void DoesNotThrowIfItsAFlag()
55 | {
56 | var parameter = parser.Parse(new[]{"-param"}).Cast().Single();
57 | Assert.AreEqual("param", parameter.Name);
58 | Assert.AreEqual("True", parameter.Value);
59 | }
60 |
61 | [Test]
62 | public void CanParseArrayOfArguments()
63 | {
64 | var args = new []{"some.assembly", "another.assembly", "-param2:bimmelim", "-param1:boom"};
65 | var parameters = parser.Parse(args);
66 |
67 | Assert.AreEqual(4, parameters.Count);
68 |
69 | var p1 = parameters[0];
70 | var p2 = parameters[1];
71 | var p3 = parameters[2];
72 | var p4 = parameters[3];
73 | Assert.AreEqual("some.assembly", p1.Value);
74 | Assert.AreEqual("another.assembly", p2.Value);
75 | Assert.AreEqual("bimmelim", p3.Value);
76 | Assert.AreEqual("boom", p4.Value);
77 | }
78 |
79 | [Test]
80 | public void ThrowsIfPositionalParametersAreMixedWithNamedParameters()
81 | {
82 | Assert.Throws(() => parser.Parse(new[] {"-named:parameter", "positional.parameter"}));
83 | Assert.Throws(() => parser.Parse(new[] {"-named.flag", "positional.parameter"}));
84 | }
85 |
86 | [Test]
87 | public void AcceptsSlashAsPositionalParameter()
88 | {
89 | var args = new []{"/src/somepath", "/src/anotherpath"};
90 | var parameters = parser.Parse(args);
91 |
92 | Assert.AreEqual(2, parameters.Count);
93 | Assert.IsTrue(parameters[0] is PositionalCommandLineParameter);
94 | Assert.IsTrue(parameters[1] is PositionalCommandLineParameter);
95 | }
96 |
97 | void AssertYieldsNoParameters(string[] args)
98 | {
99 | var parameters = parser.Parse(args);
100 | var argsAsString = string.Join(", ", args.Select(s => string.Format(@"""{0}""", s)).ToArray());
101 |
102 | Assert.AreEqual(0, parameters.Count, "Expected 0 parameters yielded from parsing {0}",
103 | argsAsString);
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/Helpers/TestBinder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using GoCommando.Attributes;
4 | using GoCommando.Helpers;
5 | using GoCommando.Parameters;
6 | using NUnit.Framework;
7 |
8 | namespace GoCommando.Tests.Helpers
9 | {
10 | [TestFixture]
11 | public class TestBinder : FixtureBase
12 | {
13 | Binder binder;
14 |
15 | protected override void DoSetUp()
16 | {
17 | binder = new Binder();
18 | }
19 |
20 | [Test]
21 | public void UsesDefaultIfSpecified()
22 | {
23 | var target = new HasDefaultParameters();
24 |
25 | binder.Bind(target, ListWith());
26 |
27 | Assert.AreEqual("hello!", target.Something1);
28 | Assert.IsNull(target.Something2);
29 | }
30 |
31 | class HasDefaultParameters
32 | {
33 | [NamedArgument("something1", "s1", Default = "hello!")]
34 | public string Something1 { get; set; }
35 |
36 | [NamedArgument("something2", "s2")]
37 | public string Something2 { get; set; }
38 | }
39 |
40 | [Test]
41 | public void GeneratesReportOfUnboundParameters()
42 | {
43 | var target = new HasProperties();
44 |
45 | var report = binder.Bind(target, ListWith());
46 |
47 | Assert.AreEqual(4, report.PropertiesNotBound.Count);
48 | Assert.AreEqual(0, report.PropertiesBound.Count);
49 | }
50 |
51 | [Test]
52 | public void GeneratesReportOfBoundParameters()
53 | {
54 | var target = new HasProperties();
55 |
56 | var report = binder.Bind(target, ListWith(PositionalParameter(1, "1"),
57 | PositionalParameter(2, "2"),
58 | NamedParameter("bim1", "3"),
59 | NamedParameter("bim2", "4")));
60 |
61 | Assert.AreEqual(0, report.PropertiesNotBound.Count);
62 | Assert.AreEqual(4, report.PropertiesBound.Count);
63 | }
64 |
65 | [Test]
66 | public void CanBindSimpleIntegerParameter()
67 | {
68 | var target = new HasPrimitiveTypes();
69 |
70 | binder.Bind(target, ListWith(NamedParameter("int", "23")));
71 |
72 | Assert.AreEqual(23, target.IntValue);
73 | }
74 |
75 | [Test]
76 | public void CanBindSimpleStringParameter()
77 | {
78 | var target = new HasPrimitiveTypes();
79 |
80 | binder.Bind(target, ListWith(NamedParameter("string", "yo!")));
81 |
82 | Assert.AreEqual("yo!", target.StringValue);
83 | }
84 |
85 | [Test]
86 | public void CanBindSimpleDoubleParameter()
87 | {
88 | var target = new HasPrimitiveTypes();
89 |
90 | binder.Bind(target, ListWith(NamedParameter("double", "23,5")));
91 |
92 | Assert.AreEqual(23.5, target.DoubleValue);
93 | }
94 |
95 | class HasProperties
96 | {
97 | [PositionalArgument]
98 | public string Arg1 { get; set; }
99 |
100 | [PositionalArgument]
101 | public string Arg2 { get; set; }
102 |
103 | [NamedArgument("bim1", "b1")]
104 | public string Arg3 { get; set; }
105 |
106 | [NamedArgument("bim2", "b2")]
107 | public string Arg4 { get; set; }
108 | }
109 |
110 | class HasPrimitiveTypes
111 | {
112 | [NamedArgument("int", "i")]
113 | public int IntValue { get; set; }
114 |
115 | [NamedArgument("double", "d")]
116 | public double DoubleValue { get; set; }
117 |
118 | [NamedArgument("string", "s")]
119 | public string StringValue { get; set; }
120 | }
121 |
122 | IEnumerable ListWith(params CommandLineParameter[] parameters)
123 | {
124 | return parameters.ToList();
125 | }
126 |
127 | CommandLineParameter NamedParameter(string name, string value)
128 | {
129 | return new NamedCommandLineParameter(name, value);
130 | }
131 |
132 | CommandLineParameter PositionalParameter(int index, string value)
133 | {
134 | return new PositionalCommandLineParameter(index, value);
135 | }
136 | }
137 | }
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/Helpers/TestHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using GoCommando.Attributes;
4 | using GoCommando.Helpers;
5 | using NUnit.Framework;
6 | namespace GoCommando.Tests.Helpers
7 | {
8 | [TestFixture]
9 | public class TestHelper : FixtureBase
10 | {
11 | Helper helper;
12 |
13 | protected override void DoSetUp()
14 | {
15 | helper = new Helper();
16 | }
17 |
18 | [Test]
19 | public void CanRepresentParametersAndDescriptionsAsExpected()
20 | {
21 | var parameters = helper.GetParameters(new SomeClass());
22 |
23 | AssertPositionalParameter(parameters[0], "hello there!", 1, "FirstPositional", "ex1", "ex2");
24 | AssertPositionalParameter(parameters[1], "hello there!", 2, "SecondPositional", "yet another lengthy example");
25 | AssertNamedParameter(parameters[2], "hello again! there!", "AnotherString", "name", "nm");
26 | }
27 |
28 | void AssertPositionalParameter(Parameter parameter, string expectedDescription, int expectedPosition, string expectedPropertyName, params string[] expectedExamples)
29 | {
30 | AssertParameter(expectedDescription, parameter, expectedPropertyName);
31 | Assert.AreEqual(expectedPosition, parameter.Position);
32 | Assert.IsTrue(parameter.ArgumentAttribute is PositionalArgumentAttribute, "Expected PositionalArgumentAttribute, was {0}", parameter.ArgumentAttribute.GetType().Name);
33 | AssertExamples(parameter, expectedExamples);
34 | }
35 |
36 | void AssertNamedParameter(Parameter parameter, string expectedDescription, string expectedPropertyName, string expectedArgumentName, string expectedArgumentShorthand, params string[] expectedExamples)
37 | {
38 | AssertParameter(expectedDescription, parameter, expectedPropertyName);
39 | Assert.IsTrue(parameter.ArgumentAttribute is NamedArgumentAttribute, "Expected NamedArgumentAttribute, was {0}", parameter.ArgumentAttribute.GetType().Name);
40 | Assert.AreEqual(expectedArgumentName, ((NamedArgumentAttribute)parameter.ArgumentAttribute).Name);
41 | Assert.AreEqual(expectedArgumentShorthand, ((NamedArgumentAttribute) parameter.ArgumentAttribute).ShortHand);
42 | AssertExamples(parameter, expectedExamples);
43 | }
44 |
45 | void AssertExamples(Parameter parameter, IEnumerable examples)
46 | {
47 | Assert.IsTrue(parameter.Examples.OrderBy(e => e.Text).Select(e => e.Text).SequenceEqual(examples.OrderBy(s => s)));
48 | }
49 |
50 | void AssertParameter(string expectedDescription, Parameter para, string expectedPropertyName)
51 | {
52 | Assert.AreEqual(expectedDescription, para.Description);
53 | Assert.AreEqual(expectedPropertyName, para.PropertyInfo.Name);
54 | }
55 |
56 | class SomeClass
57 | {
58 | public string ShouldNotBeIncluded { get; set; }
59 |
60 | [PositionalArgument]
61 | [Attributes.Description("hello there!")]
62 | [Example("ex1")]
63 | [Example("ex2")]
64 | public string FirstPositional { get; set; }
65 |
66 | [PositionalArgument]
67 | [Attributes.Description("hello there!")]
68 | [Example("yet another lengthy example")]
69 | public string SecondPositional { get; set; }
70 |
71 | [NamedArgument("name", "nm")]
72 | [Attributes.Description("hello again! there!")]
73 | public string AnotherString { get; set; }
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/Integration/ErrorTestCases.cs:
--------------------------------------------------------------------------------
1 | using GoCommando.Api;
2 | using GoCommando.Attributes;
3 | using NUnit.Framework;
4 | using DescriptionAttribute = NUnit.Framework.DescriptionAttribute;
5 |
6 | namespace GoCommando.Tests.Integration
7 | {
8 | [TestFixture]
9 | public class ErrorTestCases
10 | {
11 | [SetUp]
12 | public void SetUp()
13 | {
14 | CommandoWithTwoArguments.SomePathStatic = null;
15 | CommandoWithTwoArguments.AnotherPathStatic = null;
16 | }
17 |
18 | [Test, Description("This error was due to named argument syntax using slash, thus resulting in arguments with forward slash (e.g. an URL) being interpreted as such")]
19 | public void ReproduceError()
20 | {
21 | var errorCode = Go.Run(new[] {"/src/somepath", "/src/anotherpath"});
22 |
23 | Assert.AreEqual(0, errorCode);
24 | Assert.AreEqual("/src/somepath", CommandoWithTwoArguments.SomePathStatic);
25 | Assert.AreEqual("/src/anotherpath", CommandoWithTwoArguments.AnotherPathStatic);
26 | }
27 |
28 | class CommandoWithTwoArguments : ICommando
29 | {
30 | [PositionalArgument]
31 | public string SomePath { get; set; }
32 |
33 | [PositionalArgument]
34 | public string AnotherPath { get; set; }
35 |
36 | public void Run()
37 | {
38 | SomePathStatic = SomePath;
39 | AnotherPathStatic = AnotherPath;
40 | }
41 |
42 | public static string SomePathStatic { get; set; }
43 | public static string AnotherPathStatic { get; set; }
44 | }
45 |
46 | [Test, Description("This was the actual parameters resulting in an error")]
47 | public void HowAboutThis()
48 | {
49 | var errorCode = Go.Run(new[]
50 | {
51 | @"src\Noder.Test\bin\Debug\Noder.Test.dll",
52 | @"src\Noder.Test\Features\00_basics.feature"
53 | });
54 |
55 | Assert.AreEqual(0, errorCode);
56 | Assert.AreEqual(@"src\Noder.Test\bin\Debug\Noder.Test.dll", CommandoWithThreeArguments.SomePathStatic);
57 | Assert.AreEqual(@"src\Noder.Test\Features\00_basics.feature", CommandoWithThreeArguments.AnotherPathStatic);
58 | Assert.IsFalse(CommandoWithThreeArguments.SomeFlagStatic);
59 | }
60 |
61 | class CommandoWithThreeArguments : ICommando
62 | {
63 | [PositionalArgument]
64 | public string SomePath { get; set; }
65 |
66 | [PositionalArgument]
67 | public string AnotherPath { get; set; }
68 |
69 | [NamedArgument("flag", "f")]
70 | public bool SomeFlag { get; set; }
71 |
72 | public void Run()
73 | {
74 | SomePathStatic = SomePath;
75 | AnotherPathStatic = AnotherPath;
76 | SomeFlagStatic = SomeFlag;
77 | }
78 |
79 | public static string SomePathStatic { get; set; }
80 | public static string AnotherPathStatic { get; set; }
81 | public static bool SomeFlagStatic { get; set; }
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GoCommando.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GoCommando.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("d5030759-2ba3-411f-98c7-e5d85395a2a2")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/old/src/GoCommando.Tests/todo.txt:
--------------------------------------------------------------------------------
1 | * add ability to specify and bind default values for named arguments
2 | * add ability to run user-supplied instance of ICommando
3 |
--------------------------------------------------------------------------------
/old/src/GoCommando.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{3903DEE6-D83F-4328-B15D-129FA4658AA9}"
5 | ProjectSection(SolutionItems) = preProject
6 | ..\build.bat = ..\build.bat
7 | ..\scripts\build.proj = ..\scripts\build.proj
8 | GoCommando\GoCommando.nuspec = GoCommando\GoCommando.nuspec
9 | ..\README = ..\README
10 | EndProjectSection
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoCommando", "GoCommando\GoCommando.csproj", "{83A32DB4-90CF-4707-9463-2E0589F80EFD}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoCommando.Tests", "GoCommando.Tests\GoCommando.Tests.csproj", "{12BCC57F-5D0B-496E-B47A-BD2A85190D48}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoCommando.ConsoleApplication", "GoCommando.ConsoleApplication\GoCommando.ConsoleApplication.csproj", "{8F0347E7-51AF-42F8-A259-F5DE19C6D858}"
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|Any CPU = Debug|Any CPU
21 | Release|Any CPU = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {12BCC57F-5D0B-496E-B47A-BD2A85190D48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {12BCC57F-5D0B-496E-B47A-BD2A85190D48}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {12BCC57F-5D0B-496E-B47A-BD2A85190D48}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {12BCC57F-5D0B-496E-B47A-BD2A85190D48}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {8F0347E7-51AF-42F8-A259-F5DE19C6D858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {8F0347E7-51AF-42F8-A259-F5DE19C6D858}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {8F0347E7-51AF-42F8-A259-F5DE19C6D858}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {8F0347E7-51AF-42F8-A259-F5DE19C6D858}.Release|Any CPU.Build.0 = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | EndGlobal
41 |
--------------------------------------------------------------------------------
/old/src/GoCommando/Api/ICommando.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Api
2 | {
3 | public interface ICommando
4 | {
5 | void Run();
6 | }
7 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/ArgumentAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | public abstract class ArgumentAttribute : Attribute
6 | {
7 | public bool Required { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Attributes/ArgumentAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Attributes
4 | {
5 | public abstract class ArgumentAttribute : Attribute
6 | {
7 | public bool Required { get; protected set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Attributes/BannerAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Class)]
6 | public class BannerAttribute : Attribute
7 | {
8 | public string Text { get; set; }
9 |
10 | public BannerAttribute(string text)
11 | {
12 | Text = text;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Attributes/DescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
6 | public class DescriptionAttribute : Attribute
7 | {
8 | readonly string text;
9 |
10 | public DescriptionAttribute(string text)
11 | {
12 | this.text = text;
13 | }
14 |
15 | public string Text
16 | {
17 | get { return text; }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Attributes/ExampleAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
6 | public class ExampleAttribute : Attribute
7 | {
8 | readonly string text;
9 |
10 | public ExampleAttribute(string text)
11 | {
12 | this.text = text;
13 | }
14 |
15 | public string Text
16 | {
17 | get { return text; }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Attributes/NamedArgumentAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
6 | public class NamedArgumentAttribute : ArgumentAttribute
7 | {
8 | public string Name { get; private set; }
9 | public string ShortHand { get; private set; }
10 | public string Default { get; set; }
11 |
12 | public NamedArgumentAttribute(string name, string shortHand)
13 | {
14 | Name = name;
15 | ShortHand = shortHand;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Attributes/PositionalArgumentAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
6 | public class PositionalArgumentAttribute : ArgumentAttribute
7 | {
8 | }
9 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/BannerAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | [AttributeUsage(AttributeTargets.Class)]
6 | public class BannerAttribute : Attribute
7 | {
8 | public string Text { get; set; }
9 |
10 | public BannerAttribute(string text)
11 | {
12 | Text = text;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/CommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | public abstract class CommandLineParameter
4 | {
5 | protected CommandLineParameter(string value)
6 | {
7 | Value = value;
8 | }
9 |
10 | public string Value { get; private set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Exceptions/CommandoException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando.Exceptions
4 | {
5 | public class CommandoException : ApplicationException
6 | {
7 | public CommandoException(string message, params object[] objs)
8 | : base(string.Format(message, objs))
9 | {
10 | }
11 |
12 | public CommandoException(Exception innerException, string message, params object[] objs)
13 | : base(string.Format(message, objs), innerException)
14 | {
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Extensions/AttributeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace GoCommando.Extensions
7 | {
8 | public static class AttributeExtensions
9 | {
10 | public static void WithAttributes(this ICustomAttributeProvider customAttributeProvider, Action handleAttribute)
11 | {
12 | GetAttributes(customAttributeProvider)
13 | .ToList()
14 | .ForEach(handleAttribute);
15 | }
16 |
17 | public static IList GetAttributes(this ICustomAttributeProvider customAttributeProvider)
18 | {
19 | return customAttributeProvider.GetCustomAttributes(typeof (TAttribute), false)
20 | .Cast()
21 | .ToList();
22 | }
23 |
24 | public static bool HasAttribute(this ICustomAttributeProvider customAttributeProvider)
25 | {
26 | return GetAttributes(customAttributeProvider).Any();
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Go.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using GoCommando.Api;
6 | using GoCommando.Attributes;
7 | using GoCommando.Exceptions;
8 | using GoCommando.Extensions;
9 | using GoCommando.Helpers;
10 | using GoCommando.Parameters;
11 | using Binder = GoCommando.Helpers.Binder;
12 |
13 | namespace GoCommando
14 | {
15 | public static class Go
16 | {
17 | ///
18 | /// Runs the specified type, GoCommando style. What this means is that:
19 | /// * if type is decorated with [Banner(...)], that banner will be output
20 | /// * args will be bound to public properties decorated with [PositionalArgument] and [NamedArgument]
21 | /// * validation (if any) will be run
22 | /// * help text will be shown where appropriate
23 | ///
24 | /// GoCommando will use the default -powered way of creating
25 | /// the instance when it is needed.
26 | ///
27 | public static int Run(string[] args) where TCommando : ICommando
28 | {
29 | Func defaultCommandoFactoryMethod =
30 | () => (TCommando) Activator.CreateInstance(typeof (TCommando));
31 |
32 | return Run(args, defaultCommandoFactoryMethod);
33 | }
34 |
35 | ///
36 | /// Runs the specified type, GoCommando style. What this means is that:
37 | /// * if type is decorated with [Banner(...)], that banner will be output
38 | /// * args will be bound to public properties decorated with [PositionalArgument] and [NamedArgument]
39 | /// * validation (if any) will be run
40 | /// * help text will be shown where appropriate
41 | ///
42 | /// The specified factory method will be used to obtain the instance
43 | /// when it is needed.
44 | ///
45 | public static int Run(string[] args, Func factoryMethod) where TCommando : ICommando
46 | {
47 | try
48 | {
49 | var instance = factoryMethod();
50 |
51 | PossiblyShowBanner(instance);
52 |
53 | if (ShouldShowHelpText(args))
54 | {
55 | ShowHelpText(instance);
56 | return 0;
57 | }
58 |
59 | var parameters = GetParameters(args);
60 |
61 | var bindingReport = PopulateProperties(parameters, instance);
62 |
63 | if (RequiredParameterMissing(bindingReport))
64 | {
65 | ShowMissingParameters(bindingReport);
66 |
67 | return 1;
68 | }
69 |
70 | Execute(instance);
71 |
72 | return 0;
73 | }
74 | catch (CommandoException e)
75 | {
76 | Write(e.Message);
77 |
78 | WriteHelpInstructions();
79 |
80 | return 2;
81 | }
82 | catch (Exception e)
83 | {
84 | Write(e.ToString());
85 |
86 | return 1;
87 | }
88 | }
89 |
90 | static void ShowMissingParameters(BindingReport report)
91 | {
92 | Write("One or more required arguments are missing!");
93 | Write();
94 |
95 | var context = new BindingContext();
96 |
97 | foreach (var parameter in report.PropertiesNotBound.Select(p => new Parameter(p, context)).Where(p => p.Position > 0))
98 | {
99 | WritePositionalParameter(parameter, ExampleOutputSettings.DontShowExamples);
100 | }
101 |
102 | WriteHelpInstructions();
103 | }
104 |
105 | static void WriteHelpInstructions()
106 | {
107 | Write();
108 | Write("Invoke with -? for detailed help.");
109 | }
110 |
111 | class BindingContext : IHasPositionerCounter
112 | {
113 | public BindingContext()
114 | {
115 | Position = 1;
116 | }
117 |
118 | public int Position { get; set; }
119 | }
120 |
121 | static bool RequiredParameterMissing(BindingReport bindingReport)
122 | {
123 | return bindingReport.RequiredPropertiesNotBound.Any();
124 | }
125 |
126 | static void ShowHelpText(ICommando commando)
127 | {
128 | var helper = new Helper();
129 | var parameters = helper.GetParameters(commando);
130 |
131 | var exeName = Assembly.GetEntryAssembly().GetName().Name + ".exe";
132 | var parameterList = string.Join(" ", parameters.Where(p => p.Position > 0)
133 | .Select(p => string.Format("[{0}]", p.Position))
134 | .ToArray());
135 |
136 | var thereAreRequiredArguments = parameters.Any(p => p.Position > 0);
137 | var thereAreOptionalArguments = parameters.Any(p => p.Position == 0);
138 |
139 | Write("Usage:");
140 | Write();
141 | Write("\t{0} {1}{2}{3}",
142 | exeName,
143 | parameterList,
144 | parameterList.Length > 0 ? " " : "",
145 | thereAreOptionalArguments ? "[args]" : "");
146 |
147 | if (thereAreRequiredArguments)
148 | {
149 | Write();
150 | Write();
151 | Write("Required arguments:");
152 |
153 | foreach (var parameter in parameters.Where(p => p.Position > 0))
154 | {
155 | Write();
156 |
157 | WritePositionalParameter(parameter, ExampleOutputSettings.ShowExamples);
158 | }
159 | }
160 |
161 | if (thereAreOptionalArguments)
162 | {
163 | Write();
164 | Write();
165 | Write("Additional arguments:");
166 |
167 | foreach (var parameter in parameters.Where(p => p.Position == 0))
168 | {
169 | Write();
170 |
171 | Write("\t-{0}\t{1}", parameter.Name, parameter.Description);
172 |
173 | PossibleWriteExamples(parameter);
174 | }
175 | }
176 | }
177 |
178 | enum ExampleOutputSettings
179 | {
180 | ShowExamples,
181 | DontShowExamples,
182 | }
183 |
184 | static void WritePositionalParameter(Parameter parameter, ExampleOutputSettings outputExamples)
185 | {
186 | Write("\t[{0}] {1}", parameter.Position, parameter.Description);
187 |
188 | if (outputExamples == ExampleOutputSettings.ShowExamples)
189 | {
190 | PossibleWriteExamples(parameter);
191 | }
192 | }
193 |
194 | static void PossibleWriteExamples(Parameter parameter)
195 | {
196 | var examples = parameter.Examples;
197 |
198 | if (!examples.Any()) return;
199 |
200 | var headline = examples.Count > 1 ? "Examples" : "Example";
201 | var maxLength = examples.Max(e => e.Text.Length);
202 | var printExamplesOnMultipleLines = maxLength > 7;
203 | var separator = printExamplesOnMultipleLines ? (Environment.NewLine + "\t\t\t") : ", ";
204 |
205 | Write("\t\t{0}: {1}{2}",
206 | headline,
207 | printExamplesOnMultipleLines ? separator : "",
208 | string.Join(separator, examples.Select(e => e.Text).ToArray()));
209 | }
210 |
211 | static bool ShouldShowHelpText(string[] strings)
212 | {
213 | return strings.Length == 1
214 | && new List {"-h", "--h", "/h", "-?", "/?", "?"}.Contains(strings[0].ToLowerInvariant());
215 | }
216 |
217 | static void PossiblyShowBanner(object obj)
218 | {
219 | var type = obj.GetType();
220 | type.WithAttributes(a => ShowBanner(a, type.Assembly));
221 | Write();
222 | }
223 |
224 | static void ShowBanner(BannerAttribute attribute, Assembly assembly)
225 | {
226 | Write(attribute.Text.Replace("{assemblyVersion}", assembly.GetName().Version.ToString()));
227 | }
228 |
229 | static void Write()
230 | {
231 | Console.WriteLine();
232 | }
233 |
234 | static void Write(string text, params object[] objs)
235 | {
236 | Console.WriteLine(text, objs);
237 | }
238 |
239 | static List GetParameters(string[] args)
240 | {
241 | var parser = new ArgParser();
242 | return parser.Parse(args);
243 | }
244 |
245 | static BindingReport PopulateProperties(IEnumerable parameters, ICommando instance)
246 | {
247 | var binder = new Binder();
248 | var report = binder.Bind(instance, parameters);
249 | return report;
250 | }
251 |
252 | static void Execute(ICommando instance)
253 | {
254 | instance.Run();
255 | }
256 | }
257 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/GoCommando.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace GoCommando
6 | {
7 | public static class Go
8 | {
9 | public static int Run(string[] args) where TGoCommando : IGoCommando
10 | {
11 | try
12 | {
13 | PossiblyShowBanner(typeof(TGoCommando));
14 | var instance = (IGoCommando)Activator.CreateInstance(typeof(TGoCommando));
15 | PopulateInstanceParameters(instance, args);
16 | instance.Run();
17 | return 0;
18 | }
19 | catch (CommandoException e)
20 | {
21 | Write(e.Message);
22 |
23 | return 2;
24 | }
25 | catch (Exception e)
26 | {
27 | Write(e.ToString());
28 |
29 | return 1;
30 | }
31 | }
32 |
33 | static void PossiblyShowBanner(Type type)
34 | {
35 | type.WithAttributes(ShowBanner);
36 | }
37 |
38 | static void ShowBanner(BannerAttribute attribute)
39 | {
40 | Write(attribute.Text);
41 | }
42 |
43 | static void PopulateInstanceParameters(IGoCommando commando, string[] args)
44 | {
45 | var parser = new ArgParser();
46 | var parameters = parser.Parse(args);
47 | var matches = Match(parameters, commando.GetType().GetAttributes());
48 |
49 | }
50 |
51 | static List Match(List parameters, IEnumerable attributes)
52 | {
53 | var positionalAttributes = attributes.Where(a => a is PositionalArgumentAttribute).Cast();
54 | var otherAttributes = attributes.Where(a => a is NamedArgumentAttribute).Cast();
55 | var positionalParameters = parameters.Where(p => p is PositionalCommandLineParameter).Cast();
56 | var otherParameters = parameters.Where(p => p is NamedCommandLineParameter).Cast();
57 | var matches = new List();
58 |
59 | //drop alt det med positional args!!
60 |
61 | return matches;
62 | }
63 |
64 | static void Write(string text)
65 | {
66 | Console.WriteLine(text);
67 | }
68 | }
69 |
70 | public class ArgumentMatch
71 | {
72 | }
73 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/GoCommando.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {83A32DB4-90CF-4707-9463-2E0589F80EFD}
9 | Library
10 | Properties
11 | GoCommando
12 | GoCommando
13 | v3.5
14 | 512
15 |
16 |
17 | 3.5
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 | 3.5
41 |
42 |
43 | 3.5
44 |
45 |
46 | 3.5
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
81 |
--------------------------------------------------------------------------------
/old/src/GoCommando/GoCommando.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $author$
8 | $author$
9 | http://en.wikipedia.org/wiki/Beerware
10 | http://mookid.dk/oncode/gocommando
11 | false
12 | $description$
13 | Copyright 2011
14 | command-line
15 |
16 |
--------------------------------------------------------------------------------
/old/src/GoCommando/Helpers/ArgParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using GoCommando.Parameters;
5 |
6 | namespace GoCommando.Helpers
7 | {
8 | public class ArgParser
9 | {
10 | class ParserContext
11 | {
12 | public ParserContext()
13 | {
14 | ParsingPositionalParameters = true;
15 | Index = 1;
16 | }
17 |
18 | public int Index { get; set; }
19 | public bool ParsingPositionalParameters { get; set; }
20 | }
21 |
22 | public List Parse(string[] args)
23 | {
24 | var context = new ParserContext();
25 |
26 | return args
27 | .Where(s => s != null && s.Trim() != "")
28 | .Select(arg => ToCommandLineParameter(arg, context)).ToList();
29 | }
30 |
31 | CommandLineParameter ToCommandLineParameter(string arg, ParserContext context)
32 | {
33 | return
34 | !arg.StartsWith("-")
35 | ? CreatePositionalCommandLineParameter(arg, context)
36 | : CreateNamedCommandLineParameter(arg, context);
37 | }
38 |
39 | PositionalCommandLineParameter CreatePositionalCommandLineParameter(string arg, ParserContext context)
40 | {
41 | if (!context.ParsingPositionalParameters)
42 | {
43 | throw new FormatException(string.Format("Named parameters cannot be followed by positional parameters"));
44 | }
45 |
46 | return new PositionalCommandLineParameter(context.Index++, arg);
47 | }
48 |
49 | CommandLineParameter CreateNamedCommandLineParameter(string arg, ParserContext context)
50 | {
51 | context.ParsingPositionalParameters = false;
52 |
53 | // trim -
54 | arg = arg.Substring(1);
55 |
56 | var separatorIndex = arg.IndexOf(':');
57 |
58 | return separatorIndex == -1
59 | ? new NamedCommandLineParameter(arg, "True")
60 | : new NamedCommandLineParameter(arg.Substring(0, separatorIndex), arg.Substring(separatorIndex + 1));
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Helpers/Binder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using GoCommando.Attributes;
6 | using GoCommando.Exceptions;
7 | using GoCommando.Parameters;
8 |
9 | namespace GoCommando.Helpers
10 | {
11 | public class Binder
12 | {
13 | public BindingReport Bind(object targetObjectWithAttributes, IEnumerable parametersToBind)
14 | {
15 | var context = new BindingContext();
16 | var helper = new Helper();
17 | var parameters = helper.GetParameters(targetObjectWithAttributes);
18 |
19 | foreach (var parameter in parameters)
20 | {
21 | Bind(targetObjectWithAttributes, parameter.PropertyInfo, parametersToBind.ToList(),
22 | parameter.ArgumentAttribute,
23 | context);
24 | }
25 |
26 | return context.Report;
27 | }
28 |
29 | class BindingContext
30 | {
31 | public BindingContext()
32 | {
33 | Position = 1;
34 | }
35 |
36 | readonly BindingReport report = new BindingReport();
37 |
38 | public int Position { get; private set; }
39 |
40 | public void IncrementPosition()
41 | {
42 | Position++;
43 | }
44 |
45 | public BindingReport Report
46 | {
47 | get { return report; }
48 | }
49 | }
50 |
51 | void Bind(object commando, PropertyInfo property, List parameters, ArgumentAttribute attribute, BindingContext context)
52 | {
53 | if (attribute is PositionalArgumentAttribute)
54 | {
55 | BindPositional(commando, property, parameters, (PositionalArgumentAttribute) attribute, context);
56 | }
57 | else if (attribute is NamedArgumentAttribute)
58 | {
59 | BindNamed(commando, property, parameters, (NamedArgumentAttribute) attribute, context);
60 | }
61 | else
62 | {
63 | throw Ex("Don't know the attribute type {0}", attribute.GetType().Name);
64 | }
65 | }
66 |
67 | void BindNamed(object commando, PropertyInfo property, List parameters, NamedArgumentAttribute attribute, BindingContext context)
68 | {
69 | var name = attribute.Name;
70 | var shortHand = attribute.ShortHand;
71 | var parameter = parameters.Where(p => p is NamedCommandLineParameter)
72 | .Cast()
73 | .SingleOrDefault(p => p.Name == name || p.Name == shortHand);
74 |
75 | var value = parameter != null
76 | ? Mutate(parameter, property)
77 | : attribute.Default != null
78 | ? Mutate(attribute.Default, property)
79 | : null;
80 |
81 | if (value == null)
82 | {
83 | context.Report.PropertiesNotBound.Add(property);
84 |
85 | if (!attribute.Required) return;
86 |
87 | throw Ex("Could not find parameter matching required parameter named {0}", name);
88 | }
89 |
90 | property.SetValue(commando, value, null);
91 |
92 | context.Report.PropertiesBound.Add(property);
93 | }
94 |
95 | void BindPositional(object commando, PropertyInfo property, List parameters, PositionalArgumentAttribute attribute, BindingContext context)
96 | {
97 | var parameter = parameters
98 | .Where(p => p is PositionalCommandLineParameter)
99 | .Cast()
100 | .SingleOrDefault(p => p.Index == context.Position);
101 |
102 | if (parameter == null)
103 | {
104 | context.Report.PropertiesNotBound.Add(property);
105 | context.Report.RequiredPropertiesNotBound.Add(property);
106 |
107 | if (!attribute.Required) return;
108 |
109 | throw Ex("Could not find parameter matching required positional parameter at index {0}", context.Position);
110 | }
111 |
112 | property.SetValue(commando, Mutate(parameter, property), null);
113 |
114 | context.Report.PropertiesBound.Add(property);
115 | context.IncrementPosition();
116 | }
117 |
118 | object Mutate(CommandLineParameter parameter, PropertyInfo property)
119 | {
120 | return Mutate(parameter.Value, property);
121 | }
122 |
123 | object Mutate(string value, PropertyInfo property)
124 | {
125 | var propertyType = property.PropertyType;
126 |
127 | try
128 | {
129 | return Convert.ChangeType(value, propertyType);
130 | }
131 | catch(Exception)
132 | {
133 | throw Ex("Could not automatically turn '{0}' into a value of type {1}", value,
134 | propertyType.Name);
135 | }
136 | }
137 |
138 | CommandoException Ex(string message, params object[] objs)
139 | {
140 | return new CommandoException(message, objs);
141 | }
142 | }
143 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Helpers/BindingReport.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Reflection;
3 |
4 | namespace GoCommando.Helpers
5 | {
6 | public class BindingReport
7 | {
8 | readonly List requiredPropertiesNotBound = new List();
9 | readonly List propertiesNotBound = new List();
10 | readonly List propertiesBound = new List();
11 |
12 | public List PropertiesNotBound
13 | {
14 | get { return propertiesNotBound; }
15 | }
16 |
17 | public List PropertiesBound
18 | {
19 | get { return propertiesBound; }
20 | }
21 |
22 | public List RequiredPropertiesNotBound
23 | {
24 | get { return requiredPropertiesNotBound; }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Helpers/Helper.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Reflection;
4 | using GoCommando.Attributes;
5 | using GoCommando.Extensions;
6 |
7 | namespace GoCommando.Helpers
8 | {
9 | public class Helper
10 | {
11 | class HelperContext : IHasPositionerCounter
12 | {
13 | public HelperContext()
14 | {
15 | Position = 1;
16 | }
17 |
18 | public int Position { get; set; }
19 | }
20 |
21 | public List GetParameters(object obj)
22 | {
23 | var context = new HelperContext();
24 |
25 | return obj.GetType().GetProperties()
26 | .Where(ShouldBeIncluded)
27 | .Select(p => new Parameter(p, context))
28 | .ToList();
29 | }
30 |
31 | bool ShouldBeIncluded(PropertyInfo info)
32 | {
33 | return info.HasAttribute();
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Helpers/IHasPositionerCounter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Helpers
2 | {
3 | public interface IHasPositionerCounter
4 | {
5 | int Position { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Helpers/Parameter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Reflection;
4 | using GoCommando.Attributes;
5 | using GoCommando.Extensions;
6 |
7 | namespace GoCommando.Helpers
8 | {
9 | public class Parameter
10 | {
11 | public Parameter(PropertyInfo propertyInfo, IHasPositionerCounter context)
12 | {
13 | Examples = new List();
14 |
15 | var attributes = propertyInfo.GetAttributes();
16 |
17 | if (attributes.Count == 1)
18 | {
19 | Description = attributes[0].Text;
20 | }
21 |
22 | var argumentAttribute = propertyInfo.GetAttributes().Single();
23 |
24 | if (argumentAttribute is NamedArgumentAttribute)
25 | {
26 | var namedArgumentAttribute = (NamedArgumentAttribute)argumentAttribute;
27 | Shorthand = namedArgumentAttribute.ShortHand;
28 | Name = namedArgumentAttribute.Name;
29 | }
30 | else if (argumentAttribute is PositionalArgumentAttribute)
31 | {
32 | Position = context.Position++;
33 | }
34 |
35 | PropertyInfo = propertyInfo;
36 | ArgumentAttribute = argumentAttribute;
37 |
38 | foreach (var example in propertyInfo.GetAttributes())
39 | {
40 | Examples.Add(example);
41 | }
42 |
43 | }
44 |
45 | public string Description { get; set; }
46 |
47 | public string Name { get; set; }
48 | public string Shorthand { get; set; }
49 |
50 | public int Position { get; set; }
51 |
52 | public PropertyInfo PropertyInfo { get; set; }
53 | public ArgumentAttribute ArgumentAttribute { get; set; }
54 |
55 | public List Examples { get; set; }
56 | }
57 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/IGoCommando.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | public interface IGoCommando
4 | {
5 | void Run();
6 | }
7 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/NamedArgumentAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
6 | public class NamedArgumentAttribute : ArgumentAttribute
7 | {
8 | public string Name { get; set; }
9 | public string ShortHand { get; set; }
10 |
11 | public NamedArgumentAttribute(string name, string shortHand)
12 | {
13 | Name = name;
14 | ShortHand = shortHand;
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/NamedCommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | public class NamedCommandLineParameter : CommandLineParameter
4 | {
5 | public NamedCommandLineParameter(string name, string value) : base(value)
6 | {
7 | Name = name;
8 | }
9 |
10 | public string Name { get; set; }
11 |
12 | public override string ToString()
13 | {
14 | return string.Format("/{0}:{1}", Name, Value);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/NamedFlagCommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | //public class NamedFlagCommandLineParameter : CommandLineParameter
4 | //{
5 | // public NamedFlagCommandLineParameter(string value) : base(value)
6 | // {
7 | // }
8 |
9 | // public override string ToString()
10 | // {
11 | // return string.Format("/{0}", Value);
12 | // }
13 | //}
14 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Parameters/CommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Parameters
2 | {
3 | public abstract class CommandLineParameter
4 | {
5 | protected CommandLineParameter(string value)
6 | {
7 | Value = value;
8 | }
9 |
10 | public string Value { get; private set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Parameters/NamedCommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Parameters
2 | {
3 | public class NamedCommandLineParameter : CommandLineParameter
4 | {
5 | public NamedCommandLineParameter(string name, string value) : base(value)
6 | {
7 | Name = name;
8 | }
9 |
10 | public string Name { get; set; }
11 |
12 | public override string ToString()
13 | {
14 | return string.Format("/{0}:{1}", Name, Value);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Parameters/PositionalCommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando.Parameters
2 | {
3 | public class PositionalCommandLineParameter : CommandLineParameter
4 | {
5 | public PositionalCommandLineParameter(int index, string value) : base(value)
6 | {
7 | Index = index;
8 | }
9 |
10 | public int Index { get; set; }
11 |
12 | public override string ToString()
13 | {
14 | return string.Format("[{0}]: {1}", Index, Value);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/PositionalArgumentAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GoCommando
4 | {
5 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
6 | public class PositionalArgumentAttribute : ArgumentAttribute
7 | {
8 | public int Index { get; set; }
9 |
10 | public PositionalArgumentAttribute(int index)
11 | {
12 | Index = index;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/PositionalCommandLineParameter.cs:
--------------------------------------------------------------------------------
1 | namespace GoCommando
2 | {
3 | class PositionalCommandLineParameter : CommandLineParameter
4 | {
5 | public PositionalCommandLineParameter(int index, string value) : base(value)
6 | {
7 | Index = index;
8 | }
9 |
10 | public int Index { get; set; }
11 |
12 | public override string ToString()
13 | {
14 | return string.Format("[{0}]: {1}", Index, Value);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/old/src/GoCommando/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("GoCommando")]
5 | [assembly: AssemblyDescription("GoCommando is a small command line utility helper that does the boring work when creating command line utilities in .NET.")]
6 | [assembly: AssemblyCompany("Mogens Heller Grabe")]
7 | [assembly: AssemblyProduct("GoCommando")]
8 | [assembly: AssemblyCopyright("Copyright © 2011")]
9 | [assembly: AssemblyTrademark("")]
10 | [assembly: AssemblyCulture("")]
11 |
12 | #if DEBUG
13 | [assembly: AssemblyConfiguration("Debug")]
14 | #else
15 | [assembly: AssemblyConfiguration("Release")]
16 | #endif
17 |
18 | [assembly: ComVisible(false)]
19 |
20 | [assembly: Guid("a4168feb-47c2-4fcc-93f8-e14172192ec3")]
21 |
22 | [assembly: AssemblyVersion("0.3.0.0")]
23 | [assembly: AssemblyFileVersion("0.3.0.0")]
24 |
--------------------------------------------------------------------------------
/old/tools/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/old/tools/NuGet.exe
--------------------------------------------------------------------------------
/packages/NUnit.2.6.4/NUnit.2.6.4.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/packages/NUnit.2.6.4/NUnit.2.6.4.nupkg
--------------------------------------------------------------------------------
/packages/NUnit.2.6.4/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/packages/NUnit.2.6.4/lib/nunit.framework.dll
--------------------------------------------------------------------------------
/packages/NUnit.2.6.4/license.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/packages/NUnit.2.6.4/license.txt
--------------------------------------------------------------------------------
/scripts/build.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set scriptsdir=%~dp0
4 | set root=%scriptsdir%\..
5 | set project=%1
6 | set version=%2
7 |
8 | if "%project%"=="" (
9 | echo Please invoke the build script with a project name as its first argument.
10 | echo.
11 | goto exit_fail
12 | )
13 |
14 | if "%version%"=="" (
15 | echo Please invoke the build script with a version as its second argument.
16 | echo.
17 | goto exit_fail
18 | )
19 |
20 | set Version=%version%
21 |
22 | pushd %root%
23 |
24 | dotnet restore
25 | if %ERRORLEVEL% neq 0 (
26 | popd
27 | goto exit_fail
28 | )
29 |
30 | dotnet build "%root%\%project%" -c Release
31 | if %ERRORLEVEL% neq 0 (
32 | popd
33 | goto exit_fail
34 | )
35 |
36 | popd
37 |
38 |
39 |
40 |
41 |
42 |
43 | goto exit_success
44 | :exit_fail
45 | exit /b 1
46 | :exit_success
--------------------------------------------------------------------------------
/scripts/patch_assemblyinfo.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set reporoot=%~dp0\..
4 | set aversion=%reporoot%\tools\aversion\aversion
5 | set projectdir=%1
6 |
7 | if "%version%"=="" (
8 | "%aversion%" patch -ver 1.0.0 -in %projectdir%\Properties\AssemblyInfo.cs -out %projectdir%\Properties\AssemblyInfo_Patch.cs -token $version$
9 | ) else (
10 | "%aversion%" patch -ver %version% -in %projectdir%\Properties\AssemblyInfo.cs -out %projectdir%\Properties\AssemblyInfo_Patch.cs -token $version$
11 | )
12 |
13 |
--------------------------------------------------------------------------------
/scripts/push.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set version=%1
4 |
5 | if "%version%"=="" (
6 | echo Please remember to specify which version to push as an argument.
7 | goto exit_fail
8 | )
9 |
10 | set reporoot=%~dp0\..
11 | set destination=%reporoot%\deploy
12 |
13 | if not exist "%destination%" (
14 | echo Could not find %destination%
15 | echo.
16 | echo Did you remember to build the packages before running this script?
17 | )
18 |
19 | set nuget=%reporoot%\tools\NuGet\NuGet.exe
20 |
21 | if not exist "%nuget%" (
22 | echo Could not find NuGet here:
23 | echo.
24 | echo "%nuget%"
25 | echo.
26 | goto exit_fail
27 | )
28 |
29 |
30 | "%nuget%" push "%destination%\*.%version%.nupkg" -Source https://www.nuget.org/api/v2/package
31 | if %ERRORLEVEL% neq 0 (
32 | echo NuGet push failed.
33 | goto exit_fail
34 | )
35 |
36 |
37 |
38 |
39 |
40 |
41 | goto exit_success
42 | :exit_fail
43 | exit /b 1
44 | :exit_success
45 |
--------------------------------------------------------------------------------
/scripts/release.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set scriptsdir=%~dp0
4 | set root=%scriptsdir%\..
5 | set deploydir=%root%\deploy
6 | set project=%1
7 | set version=%2
8 |
9 | if "%project%"=="" (
10 | echo Please invoke the build script with a project name as its first argument.
11 | echo.
12 | goto exit_fail
13 | )
14 |
15 | if "%version%"=="" (
16 | echo Please invoke the build script with a version as its second argument.
17 | echo.
18 | goto exit_fail
19 | )
20 |
21 | set Version=%version%
22 |
23 | if exist "%deploydir%" (
24 | rd "%deploydir%" /s/q
25 | )
26 |
27 | pushd %root%
28 |
29 | dotnet restore
30 | if %ERRORLEVEL% neq 0 (
31 | popd
32 | goto exit_fail
33 | )
34 |
35 | dotnet pack "%root%/%project%" -c Release -o "%deploydir%" /p:PackageVersion=%version%
36 | if %ERRORLEVEL% neq 0 (
37 | popd
38 | goto exit_fail
39 | )
40 |
41 | call scripts\push.cmd "%version%"
42 |
43 | popd
44 |
45 |
46 |
47 |
48 |
49 |
50 | goto exit_success
51 | :exit_fail
52 | exit /b 1
53 | :exit_success
--------------------------------------------------------------------------------
/tools/NuGet/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rebus-org/GoCommando/e56e6f896f0794a6072756d358d7aeea493563d4/tools/NuGet/nuget.exe
--------------------------------------------------------------------------------