/src/DotConsole.Tests/v20/TrunkMonkey.cs
C# | 312 lines | 205 code | 46 blank | 61 comment | 20 complexity | 2525a7294acf29be838eb9169fae944c MD5 | raw file
1using System;
2using System.Collections.Generic;
3using System.ComponentModel.Composition;
4using System.ComponentModel.Composition.Hosting;
5using System.ComponentModel.DataAnnotations;
6using System.Linq;
7using System.Reflection;
8using System.Text;
9using Xunit;
10
11namespace DotConsole.Tests.v20
12{
13 // dnm.exe --ConfigFile "value here" --Environment LOCAL --ResetDatabase --WarnOnHashChange
14 // dnm.exe -rw --ConfigFile "value here" --Environment LOCAL
15 // dnm.exe -rwc "value here" --Environment LOCAL
16 // dnm.exe "value here" DEV -rw
17 // dnm.exe LOCAL
18
19 // ConfigFile - Position: 1
20 // Environment - Position: 2
21 // ResetDatabase
22
23
24 public class RawArgSet : Dictionary<string, List<string>>
25 {
26 public List<string> AnonymousValues { get; private set; }
27
28 public RawArgSet()
29 {
30 AnonymousValues = new List<string>();
31 }
32
33 public static RawArgSet Parse(IEnumerable<string> args)
34 {
35 var set = new RawArgSet();
36 string lastKey = null;
37
38 foreach (var cmdLine in args)
39 {
40 if (cmdLine.StartsWith("--"))
41 {
42 lastKey = cmdLine.Substring(2).ToLowerInvariant();
43 if (!set.ContainsKey(lastKey))
44 set.Add(lastKey, new List<string>());
45 }
46 else if (cmdLine.StartsWith("-"))
47 {
48 foreach (var c in cmdLine.Substring(1))
49 {
50 lastKey = c.ToString();
51 if (!set.ContainsKey(lastKey))
52 set.Add(lastKey, new List<string>());
53 }
54 }
55 else
56 {
57 if (lastKey == null)
58 {
59 set.AnonymousValues.Add(cmdLine);
60 }
61 else
62 {
63 set[lastKey].Add(cmdLine);
64 }
65 }
66 }
67
68 return set;
69 }
70 }
71
72 public class CommandLocator
73 {
74 [ImportMany(typeof(ICommand))]
75 protected List<Lazy<ICommand, ICommandMetadata>> Commands { get; set; }
76
77 public CommandLocator()
78 {
79 var catalog = new AggregateCatalog();
80 //catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
81 catalog.Catalogs.Add(new TypeCatalog(typeof(InvokeCommand)));
82
83 var container = new CompositionContainer(catalog);
84 container.ComposeParts(this);
85 }
86
87 public ICommand GetDefaultCommand()
88 {
89 var found = Commands.FirstOrDefault(x => x.Metadata.Default);
90 if (found != null)
91 {
92 return found.Value;
93 }
94 return null;
95 }
96
97 public ICommand GetCommandByName(string commandName)
98 {
99 // try to match the command name in the metadata first
100 ICommand cmd = Commands
101 .Where(x => x.Metadata.Name == commandName)
102 .Select(x => x.Value)
103 .FirstOrDefault();
104
105 // then try to match based on the command's type name
106 if (cmd == null)
107 cmd = Commands
108 .Select(x => new
109 {
110 x.Value,
111 TypeName = x.Value.GetType().Name
112 })
113 .Where(x => x.TypeName == commandName || x.TypeName == commandName + "Command")
114 .Select(x => x.Value)
115 .FirstOrDefault();
116
117 return cmd;
118 }
119 }
120
121 public class CommandFiller
122 {
123 public void Fill(ICommand cmd, RawArgSet args)
124 {
125
126 }
127 }
128
129 public class CommandValidator
130 {
131 public void Validate(ICommand cmd)
132 {
133
134 }
135 }
136
137 public static class Commander
138 {
139
140
141 public static void Run()
142 {
143 var args = Environment.GetCommandLineArgs().Skip(1);
144 var set = RawArgSet.Parse(args);
145 var cmd = (new CommandLocator()).GetCommandByName(set.AnonymousValues[0]);
146 }
147 }
148
149 public class RawArg
150 {
151
152 [Fact]
153 public void Tests()
154 {
155// string[] line = new string[]
156// {
157// "abcdef",
158// "-rw",
159// "--ConfigFile",
160// "\"value here\"",
161// "--Environment",
162// "LOCAL",
163// "--ConfigFile",
164// "another value"
165// };
166//
167// var results = Parse(line);
168// PrintResults(results);
169//
170// Assert.True(results.ContainsKey("r"), "No 'r' key.");
171// Assert.True(results.ContainsKey("w"), "No 'w' key.");
172// Assert.True(results.ContainsKey("ConfigFile"), "No 'ConfigFile' key.");
173// Assert.True(results.ContainsKey("Environment"), "No 'Environment' key.");
174//
175// Assert.Empty(results["r"]);
176// Assert.Empty(results["w"]);
177// Assert.True(results["ConfigFile"].Count == 2, "No 'ConfigFile' value.");
178// Assert.Equal("\"value here\"", results["ConfigFile"][0]);
179// Assert.Equal("another value", results["ConfigFile"][1]);
180// Assert.True(results["Environment"].Count == 1, "No 'Environment' value.");
181// Assert.Equal("LOCAL", results["Environment"][0]);
182 }
183
184 [Fact]
185 public void Should_find_command_by_name()
186 {
187// var cmd = GetCommand(new Dictionary<string, List<string>>()
188// {
189// {
190// string.Empty, new List<string>()
191// {
192// "Invoke"
193// }
194// }
195// });
196// Assert.IsType<InvokeCommand>(cmd);
197 }
198
199 private void PrintResults(Dictionary<string, List<string>> results)
200 {
201 foreach (var key in results.Keys)
202 {
203 if (key.Length == 0)
204 Console.Write("ANONYMOUS");
205 else if (key.Length == 1)
206 Console.Write("-");
207 else
208 Console.Write("--");
209
210 Console.WriteLine(key);
211
212 foreach (var value in results[key])
213 {
214 Console.WriteLine(" " + value);
215 }
216 }
217 }
218 }
219
220
221 public class ArgumentAttribute : Attribute
222 {
223 public ArgumentAttribute(string desc)
224 {
225 Description = desc;
226 Position = -1;
227 }
228
229 /// <summary>
230 /// Long argument name.
231 /// </summary>
232 public string Name { get; set; }
233
234 /// <summary>
235 /// Abbreviated name that is friendly for the command line.
236 /// </summary>
237 public string ShortName { get; set; }
238
239 /// <summary>
240 /// Used in the syntax help text as the placeholder for the value.
241 /// </summary>
242 public string ValueName { get; set; }
243
244 /// <summary>
245 /// If the argument is not passed in with a name then it will
246 /// be matched based on its position in the array of unnamed arguments.
247 /// </summary>
248 public int Position { get; set; }
249
250 public string Description { get; set; }
251 }
252
253 public interface ICommandMetadata
254 {
255 string Name { get; }
256 bool Default { get; }
257 string Description { get; }
258 }
259
260 [MetadataAttribute]
261 [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
262 public class CommandAttribute : ExportAttribute, ICommandMetadata
263 {
264 public string Name { get; set; }
265 public bool Default { get; set; }
266 public string Description { get; set; }
267
268 public CommandAttribute()
269 : base(typeof(ICommand))
270 { }
271 }
272
273 public interface ICommand
274 {
275 void Run();
276 }
277
278 [Command(Default = true)]
279 public class InvokeCommand : ICommand
280 {
281 [Required()]
282 [Argument("Name of the person running the sample.",
283 Position = 1,
284 ValueName = "persons_name")]
285 public string ConfigFile { get; set; }
286
287 public void Run()
288 {
289
290 }
291 }
292
293 public class TrunkMonkey
294 {
295 [ImportMany(typeof(ICommand))]
296 public IList<Lazy<ICommand, ICommandMetadata>> Commands { get; set; }
297
298 public TrunkMonkey()
299 {
300 var catalog = new AggregateCatalog();
301 catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
302
303 var container = new CompositionContainer(catalog);
304 container.ComposeParts(this);
305 }
306
307 public Type GetCommandType(IEnumerable<string> args)
308 {
309 return null;
310 }
311 }
312}