A class that represents command line actions that users can specify on the command line. This is useful for programs like git where users first specify an action like 'push' and then the remaining arguments are either global or specific to 'push'.
Ejemplo n.º 1
0
        public bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext)
        {
            // don't even try mark tokens as invalid unless the cursor is on it
            if (readerContext.BufferPosition >= highlighterContext.CurrentToken.StartIndex && readerContext.BufferPosition < highlighterContext.CurrentToken.EndIndex)
            {
                return(false);
            }

            var currentToken  = highlighterContext.CurrentToken.Value;
            var previousToken = PowerArgsRichCommandLineReader.FindPreviousNonWhitespaceToken(readerContext, highlighterContext);
            var firstToken    = readerContext.Tokens[0].Value;

            CommandLineAction   contextualAction   = PowerArgsRichCommandLineReader.FindContextualAction(firstToken, definition);
            CommandLineArgument contextualArgument = PowerArgsRichCommandLineReader.FindContextualArgument(previousToken, contextualAction, definition);

            if (contextualArgument != null)
            {
                if (contextualArgument.TestIsValidAndRevivable(currentToken) == false)
                {
                    // the current token either failed validation or could not be revived
                    return(true);
                }
            }

            bool expectMatchingArg;
            CommandLineArgument currentTokenArgument = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(contextualAction, currentToken, out expectMatchingArg, definition);

            if (currentTokenArgument == null && expectMatchingArg)
            {
                // The current token starts with a - or /, but does not match a global or action specific argument, so we'll highlight the token red
                return(true);
            }

            return(false);
        }
Ejemplo n.º 2
0
        private List <CommandLineAction> FindCommandLineActions(Type t)
        {
            var knownAliases = new List <string>();

            foreach (var argument in Arguments)
            {
                knownAliases.AddRange(argument.Aliases);
            }

            BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public;

            var actions = (from p in t.GetProperties(flags)
                           where  CommandLineAction.IsActionImplementation(p)
                           select CommandLineAction.Create(p, knownAliases)).ToList();

            if (t.HasAttr <ArgActionType>())
            {
                t = t.Attr <ArgActionType>().ActionType;
            }

            foreach (var action in t.GetMethods(flags).Where(m => CommandLineAction.IsActionImplementation(m)).Select(m => CommandLineAction.Create(m, knownAliases.ToList())))
            {
                var matchingPropertyBasedAction = actions.Where(a => a.Aliases.First() == action.Aliases.First()).SingleOrDefault();
                if (matchingPropertyBasedAction != null)
                {
                    continue;
                }
                actions.Add(action);
            }

            return(actions);
        }
Ejemplo n.º 3
0
        private static void ShowUsage(CommandLineAction specifiedAction)
        {
            if (specifiedAction == null)
            {
                ConsoleString.Write("Supported actions: ", ConsoleColor.Cyan);
                Console.WriteLine("Extract");
                Console.WriteLine("");
                return;
            }

            Console.WriteLine("");
            Console.WriteLine("");
            ConsoleString.WriteLine(specifiedAction.DefaultAlias, ConsoleColor.Yellow);
            ConsoleString.WriteLine(new string('-', 80), ConsoleColor.DarkGray);
            Console.WriteLine("");
            Console.WriteLine(specifiedAction.Description);
            Console.WriteLine("");
            ConsoleString.WriteLine(new string('-', 80), ConsoleColor.DarkGray);
            Console.WriteLine("");

            switch (specifiedAction.DefaultAlias)
            {
                case "Extract":
                    ArgUsage.GetStyledUsage<ExtractArgs>("Extract action").WriteLine();
                    break;
            }
        }
Ejemplo n.º 4
0
        private List <CommandLineAction> FindCommandLineActions(Type t)
        {
            var knownAliases = new List <string>();

            foreach (var argument in Arguments)
            {
                knownAliases.AddRange(argument.Aliases);
            }

            BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public;

            var actions = (from p in t.GetProperties(flags)
                           where  CommandLineAction.IsActionImplementation(p)
                           select CommandLineAction.Create(p, knownAliases)).ToList();

            List <Type> typesToSearchForActions = new List <Type>()
            {
                t
            };

            if (t.HasAttr <ArgActionResolver>())
            {
                typesToSearchForActions.AddRange(t.Attr <ArgActionResolver>().ResolveActionTypes());
            }

            typesToSearchForActions.AddRange(t.Attrs <ArgActionType>().Select(aat => aat.ActionType));

            foreach (var typeToSearch in typesToSearchForActions)
            {
                var requireStatic = typeToSearch != t;
                foreach (var method in typeToSearch.GetMethods(flags).Where(m => CommandLineAction.IsActionImplementation(m)))
                {
                    if (requireStatic && method.IsStatic == false)
                    {
                        throw new InvalidArgDefinitionException("The method " + method.DeclaringType.FullName + "." + method.Name + " must be static because it has been imported using [ArgActionType] or [ArgActions]");
                    }

                    var action = CommandLineAction.Create(method, knownAliases.ToList());
                    var matchingPropertyBasedAction = actions.Where(a => a.Aliases.First() == action.Aliases.First()).SingleOrDefault();
                    if (matchingPropertyBasedAction != null)
                    {
                        continue;
                    }
                    actions.Add(action);
                }
            }

            return(actions);
        }
Ejemplo n.º 5
0
        internal static bool IsArgument(PropertyInfo property)
        {
            if (property.HasAttr <ArgIgnoreAttribute>())
            {
                return(false);
            }
            if (CommandLineAction.IsActionImplementation(property))
            {
                return(false);
            }

            if (property.Name == Constants.ActionPropertyConventionName &&
                property.HasAttr <ArgPosition>() &&
                property.Attr <ArgPosition>().Position == 0 &&
                property.HasAttr <ArgRequired>())
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 6
0
        private static void ShowUsage(CommandLineAction specifiedAction)
        {
            if (specifiedAction == null)
            {
                ConsoleString.Write("Supported actions: ", ConsoleColor.Cyan);
                Console.WriteLine("Deploy, CreateListShardMap, CreateRangeShardMap, AddListMapShard, AddRangeMapShard");
                Console.WriteLine("");
                return;
            }

            Console.WriteLine("");
            Console.WriteLine("");
            ConsoleString.WriteLine(specifiedAction.DefaultAlias, ConsoleColor.Yellow);
            ConsoleString.WriteLine(new string('-', 80), ConsoleColor.DarkGray);
            Console.WriteLine("");
            Console.WriteLine(specifiedAction.Description);
            Console.WriteLine("");
            ConsoleString.WriteLine(new string('-', 80), ConsoleColor.DarkGray);
            Console.WriteLine("");

            switch (specifiedAction.DefaultAlias)
            {
                case "Deploy":
                    ArgUsage.GetStyledUsage<DeployArgs>("Deploy action").WriteLine();
                    break;
                case "CreateListShardMap":
                case "CreateRangeShardMap":
                    ArgUsage.GetStyledUsage<CreateShardMapArgs>($"{specifiedAction.DefaultAlias} action").WriteLine();
                    break;
                case "AddListMapShard":
                    ArgUsage.GetStyledUsage<AddListMapShardArgs>("AddListMapShard action").WriteLine();
                    break;
                case "AddRangeMapShard":
                    ArgUsage.GetStyledUsage<AddRangeMapShardArgs>("AddRangeMapShard action").WriteLine();
                    break;
                case "AddInt32RangeMapShards":
                    ArgUsage.GetStyledUsage<AddInt32RangeMapShardsArgs>("AddInt32RangeMapShards action").WriteLine();
                    break;
            }
        }
Ejemplo n.º 7
0
        internal static List <string> FindDefaultShortcuts(PropertyInfo info, List <string> knownShortcuts, bool ignoreCase)
        {
            List <string> ret = new List <string>();

            bool excludeName = info.Attrs <ArgShortcut>().Where(s => s.Policy == ArgShortcutPolicy.ShortcutsOnly).Count() > 0;

            if (excludeName == false)
            {
                knownShortcuts.Add(info.Name);

                if (CommandLineAction.IsActionImplementation(info) && info.Name.EndsWith(Constants.ActionArgConventionSuffix))
                {
                    ret.Add(info.Name.Substring(0, info.Name.Length - Constants.ActionArgConventionSuffix.Length));
                }
                else
                {
                    ret.Add(info.Name);
                }
            }

            var attrs = info.Attrs <ArgShortcut>();

            if (attrs.Count == 0)
            {
                var shortcut = GenerateShortcutAlias(info.Name, knownShortcuts, ignoreCase);
                if (shortcut != null)
                {
                    knownShortcuts.Add(shortcut);
                    ret.Add(shortcut);
                }

                return(ret);
            }
            else
            {
                return(ret);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// A helper that detects the argument represented by the current token given a definition.
        /// </summary>
        /// <param name="contextualAction">An action to inspect for a match if the current token does not match a global argument.  Pass null to only check global arguments.</param>
        /// <param name="currentToken">The token to inspect.  If you pass null you will get null back.</param>
        /// <param name="expectMatchingArg">This will be set to true if the current token starts with a '-' or a '/' meaning that the token was an argument indicator, even if it didn't match an argument in the definition.</param>
        /// <param name="def">The definition to inspect.  If null, the ambient definition will be used.  If there is no ambient definition and null is passed then this method throws a NullReferenceException.</param>
        /// <returns>An argument that is matched by the given token or null if there was no match</returns>
        public static CommandLineArgument FindCurrentTokenArgument(CommandLineAction contextualAction, string currentToken, out bool expectMatchingArg, CommandLineArgumentsDefinition def = null)
        {
            def = PassThroughOrTryGetAmbientDefinition(def);

            if (currentToken == null)
            {
                expectMatchingArg = false;
                return(null);
            }

            string currentTokenArgumentNameValue = null;

            expectMatchingArg = false;
            if (currentToken.StartsWith("-"))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg             = true;
            }
            else if (currentToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg             = true;
            }

            CommandLineArgument currentTokenArgument = null;

            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = def.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();

                if (currentTokenArgument == null && contextualAction != null)
                {
                    currentTokenArgument = contextualAction.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();
                }
            }
            return(currentTokenArgument);
        }
Ejemplo n.º 9
0
        internal static List <string> FindDefaultShortcuts(PropertyInfo info, List <string> knownShortcuts, bool ignoreCase)
        {
            List <string> ret = new List <string>();

            var argumentName = info.Name;

            bool excludeName = info.Attrs <ArgShortcut>().Where(s => s.Policy == ArgShortcutPolicy.ShortcutsOnly).Count() > 0;

            if (excludeName == false)
            {
                knownShortcuts.Add(info.Name);

                if (CommandLineAction.IsActionImplementation(info) && argumentName.EndsWith(Constants.ActionArgConventionSuffix))
                {
                    ret.Add(info.Name.Substring(0, argumentName.Length - Constants.ActionArgConventionSuffix.Length));
                }
                else
                {
                    ret.Add(argumentName);
                }
            }

            var attrs = info.Attrs <ArgShortcut>();

            if (attrs.Count == 0)
            {
                var longFormShortcut = PascalCaseNameSplitter(info.Name);
                if (!knownShortcuts.Any(x => x.Equals(longFormShortcut, StringComparison.OrdinalIgnoreCase)))
                {
                    knownShortcuts.Add(longFormShortcut);
                    ret.Add(longFormShortcut);
                }
            }
            ret.Reverse();
            return(ret);
        }
        /// <summary>
        /// A helper that detects the argument represented by the current token given a definition.  
        /// </summary>
        /// <param name="contextualAction">An action to inspect for a match if the current token does not match a global argument.  Pass null to only check global arguments.</param>
        /// <param name="currentToken">The token to inspect.  If you pass null you will get null back.</param>
        /// <param name="expectMatchingArg">This will be set to true if the current token starts with a '-' or a '/' meaning that the token was an argument indicator, even if it didn't match an argument in the definition.</param>
        /// <param name="def">The definition to inspect.  If null, the ambient definition will be used.  If there is no ambient definition and null is passed then this method throws a NullReferenceException.</param>
        /// <returns>An argument that is matched by the given token or null if there was no match</returns>
        public static CommandLineArgument FindCurrentTokenArgument(CommandLineAction contextualAction, string currentToken, out bool expectMatchingArg, CommandLineArgumentsDefinition def = null)
        {
            def = PassThroughOrTryGetAmbientDefinition(def);

            if (currentToken == null)
            {
                expectMatchingArg = false;
                return null;
            }

            string currentTokenArgumentNameValue = null;
            expectMatchingArg = false;
            if (currentToken.StartsWith("-"))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg = true;
            }
            else if (currentToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg = true;
            }

            CommandLineArgument currentTokenArgument = null;
            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = def.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();

                if (currentTokenArgument == null && contextualAction != null)
                {
                    currentTokenArgument = contextualAction.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();
                }
            }
            return currentTokenArgument;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// A helper that detects the argument represented by the current token given a definition.
        /// </summary>
        /// <param name="previousToken">The token to inspect.  If you pass null you will get null back.</param>
        /// <param name="contextualAction">An action to inspect for a match if the current token does not match a global argument.  Pass null to only check global arguments.</param>
        /// <param name="def">The definition to inspect.  If null, the ambient definition will be used.  If there is no ambient definition and null is passed then this method throws a NullReferenceException.</param>
        /// <returns>An argument that is matched by the given token or null if there was no match</returns>
        public static CommandLineArgument FindContextualArgument(string previousToken, CommandLineAction contextualAction, CommandLineArgumentsDefinition def = null)
        {
            def = PassThroughOrTryGetAmbientDefinition(def);

            if (previousToken == null)
            {
                return(null);
            }

            string currentTokenArgumentNameValue = null;

            if (previousToken.StartsWith("-"))
            {
                currentTokenArgumentNameValue = previousToken.Substring(1);
            }
            else if (previousToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = previousToken.Substring(1);
            }

            CommandLineArgument currentTokenArgument = null;

            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = def.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();

                if (currentTokenArgument == null && contextualAction != null)
                {
                    currentTokenArgument = contextualAction.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();
                }
            }
            return(currentTokenArgument);
        }
Ejemplo n.º 12
0
        public void TestModeledActionREPL()
        {
            int invokeCount = 0;

            CommandLineArgumentsDefinition definition = new CommandLineArgumentsDefinition();
            definition.Metadata.Add(new TabCompletion() { REPL = true, Indicator = "$" });

            var action = new CommandLineAction((d) =>
            {
                Assert.AreEqual("go", d.SpecifiedAction.DefaultAlias);
                if (invokeCount == 0)
                {
                    Assert.AreEqual("Hawaii", d.SpecifiedAction.Arguments[0].RevivedValue);
                }
                else if (invokeCount == 1)
                {
                    Assert.AreEqual("Mexico", d.SpecifiedAction.Arguments[0].RevivedValue);
                }
                invokeCount++;
            });

            action.Aliases.Add("go");
            action.Description = "A simple action";

            definition.Actions.Add(action);

            var destination = new CommandLineArgument(typeof(string), "destination");
            destination.Metadata.Add(new ArgRequired());
            destination.Description = "The place to go to";

            action.Arguments.Add(destination);

            var provider = TestConsoleProvider.SimulateConsoleInput("g\t -dest\t Hawaii{enter}go -dest\t Mexico{enter}quit");
            Args.InvokeAction(definition, "$");
            Assert.AreEqual(2, invokeCount);
        }
        /// <summary>
        /// A helper that detects the argument represented by the current token given a definition.  
        /// </summary>
        /// <param name="previousToken">The token to inspect.  If you pass null you will get null back.</param>
        /// <param name="contextualAction">An action to inspect for a match if the current token does not match a global argument.  Pass null to only check global arguments.</param>
        /// <param name="def">The definition to inspect.  If null, the ambient definition will be used.  If there is no ambient definition and null is passed then this method throws a NullReferenceException.</param>
        /// <returns>An argument that is matched by the given token or null if there was no match</returns>
        public static CommandLineArgument FindContextualArgument(string previousToken, CommandLineAction contextualAction, CommandLineArgumentsDefinition def = null)
        {
            def = PassThroughOrTryGetAmbientDefinition(def);

            if (previousToken == null)
            {
                return null;
            }

            string currentTokenArgumentNameValue = null;
            if (previousToken.StartsWith("-"))
            {
                currentTokenArgumentNameValue = previousToken.Substring(1);
            }
            else if (previousToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = previousToken.Substring(1);
            }

            CommandLineArgument currentTokenArgument = null;
            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = def.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();

                if (currentTokenArgument == null && contextualAction != null)
                {
                    currentTokenArgument = contextualAction.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();
                }
            }
            return currentTokenArgument;
        }
Ejemplo n.º 14
0
 protected bool Equals(CommandLineAction other)
 {
     return Equals(Source, other.Source);
 }
Ejemplo n.º 15
0
        public void TestModeledAction()
        {
            bool invoked = false;

            CommandLineArgumentsDefinition definition = new CommandLineArgumentsDefinition();

            var action = new CommandLineAction((d) =>
            {
                Assert.AreEqual("go", d.SpecifiedAction.DefaultAlias);
                Assert.AreEqual("Hawaii", d.SpecifiedAction.Arguments[0].RevivedValue);
                invoked = true;
            });

            action.Aliases.Add("go");
            action.Description = "A simple action";

            definition.Actions.Add(action);

            var actionString = action.ToString(); // Make sure it doesn't throw

            var destination  = new CommandLineArgument(typeof(string),"destination");
            destination.Metadata.Add(new ArgRequired());
            destination.Description = "The place to go to";

            action.Arguments.Add(destination);

            Args.InvokeAction(definition, "go", "-destination", "Hawaii");
            Assert.IsTrue(invoked);

            var usage = ArgUsage.GetUsage(definition, "test");
            Assert.IsTrue(usage.Contains("A simple action"));
            Assert.IsTrue(usage.Contains("The place to go to"));
        }
Ejemplo n.º 16
0
        public void TestPowerArgsRichCommandLineReaderFindCurrentTokenArgument()
        {
            bool expect;
            try
            {
                PowerArgsRichCommandLineReader.FindCurrentTokenArgument(null, null, out expect);
            }
            catch (NullReferenceException ex)
            {
                Assert.IsTrue(ex.Message.Contains("ambient"));
            }

            CommandLineArgumentsDefinition def = new CommandLineArgumentsDefinition();
            var globalArg = new CommandLineArgument(typeof(int), "TheInt");
            def.Arguments.Add(globalArg);
            Assert.IsNull(PowerArgsRichCommandLineReader.FindCurrentTokenArgument(null, null, out expect, def));
            Assert.IsFalse(expect);

            var found = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(null, "-TheInt", out expect, def);
            Assert.AreSame(globalArg, found);
            Assert.IsTrue(expect);

            found = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(null, "/TheInt", out expect, def);
            Assert.AreSame(globalArg, found);
            Assert.IsTrue(expect);

            found = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(null, "TheInt", out expect, def);
            Assert.IsNull(found);
            Assert.IsFalse(expect);

            found = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(null, "-ActionInt", out expect, def);
            Assert.IsNull(found);
            Assert.IsTrue(expect);

            var action = new CommandLineAction((d) => { });
            action.Aliases.Add("TheAction");
            var actionArg = new CommandLineArgument(typeof(int), "ActionInt");
            action.Arguments.Add(actionArg);
            def.Actions.Add(action);

            found = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(action, "-ActionInt", out expect, def);
            Assert.AreSame(actionArg, found);
            Assert.IsTrue(expect);
        }
Ejemplo n.º 17
0
        public void TestPowerArgsRichCommandLineReaderFindContextualArgument()
        {
            try
            {
                PowerArgsRichCommandLineReader.FindContextualArgument("-TheString", null);
                Assert.Fail("An exception should have been thrown");
            }
            catch(NullReferenceException ex)
            {
                Assert.IsTrue(ex.Message.Contains("ambient"));
            }

            CommandLineArgumentsDefinition def = new CommandLineArgumentsDefinition();
            var globalArg = new CommandLineArgument(typeof(string), "TheString");

            def.Arguments.Add(globalArg);
            var found = PowerArgsRichCommandLineReader.FindContextualArgument("-TheString", null, def);
            Assert.AreSame(globalArg, found);

            found = PowerArgsRichCommandLineReader.FindContextualArgument("/TheString", null, def);
            Assert.AreSame(globalArg, found);

            Assert.IsNull(PowerArgsRichCommandLineReader.FindContextualArgument("-ActionInt", null, def));
            Assert.IsNull(PowerArgsRichCommandLineReader.FindContextualArgument(null, null, def));

            var action = new CommandLineAction((d) => { });
            action.Aliases.Add("TheAction");

            var actionArg = new CommandLineArgument(typeof(int), "ActionInt");
            action.Arguments.Add(actionArg);
            def.Actions.Add(action);

            found = PowerArgsRichCommandLineReader.FindContextualArgument("-TheString", action, def);
            Assert.AreSame(globalArg, found);

            found = PowerArgsRichCommandLineReader.FindContextualArgument("-ActionInt", action, def);
            Assert.AreSame(actionArg, found);
        }
Ejemplo n.º 18
0
        public void TestPowerArgsRichCommandLineReaderFindContextualAction()
        {
            try
            {
                PowerArgsRichCommandLineReader.FindContextualAction("doesnotmatter");
                Assert.Fail("An exception should have been thrown");
            }
            catch (NullReferenceException ex)
            {
                Assert.IsTrue(ex.Message.Contains("ambient"));
            }

            CommandLineArgumentsDefinition def = new CommandLineArgumentsDefinition();
            Assert.IsNull(PowerArgsRichCommandLineReader.FindContextualAction(null, def));
            Assert.IsNull(PowerArgsRichCommandLineReader.FindContextualAction("", def));
            Assert.IsNull(PowerArgsRichCommandLineReader.FindContextualAction("NonMatchingAction", def));

            var action = new CommandLineAction((d) => { });
            action.Aliases.Add("TheAction");

            def.Actions.Add(action);

            var found = PowerArgsRichCommandLineReader.FindContextualAction("theaction", def);
            Assert.AreSame(action, found);
        }
Ejemplo n.º 19
0
        private void ValidateArgScaffold(Type t, List <string> shortcuts = null, Type parentType = null)
        {
            /*
             * Today, this validates the following:
             *
             *     - IgnoreCase can't be different on parent and child scaffolds.
             *     - No collisions on shortcut values for properties and enum values
             *     - No reviver for type
             *
             */

            if (parentType != null)
            {
                if (parentType.HasAttr <ArgIgnoreCase>() ^ t.HasAttr <ArgIgnoreCase>())
                {
                    throw new InvalidArgDefinitionException("If you specify the " + typeof(ArgIgnoreCase).Name + " attribute on your base type then you must also specify it on each action type.");
                }
                else if (parentType.HasAttr <ArgIgnoreCase>() && parentType.Attr <ArgIgnoreCase>().IgnoreCase != t.Attr <ArgIgnoreCase>().IgnoreCase)
                {
                    throw new InvalidArgDefinitionException("If you specify the " + typeof(ArgIgnoreCase).Name + " attribute on your base and acton types then they must be configured to use the same value for IgnoreCase.");
                }
            }

            if (t.Attrs <ArgIgnoreCase>().Count > 1)
            {
                throw new InvalidArgDefinitionException("An attribute that is or derives from " + typeof(ArgIgnoreCase).Name + " was specified on your type more than once");
            }


            var actionProp = ArgAction.GetActionProperty(t);

            shortcuts = shortcuts ?? new List <string>();
            bool ignoreCase = true;

            if (t.HasAttr <ArgIgnoreCase>() && t.Attr <ArgIgnoreCase>().IgnoreCase == false)
            {
                ignoreCase = false;
            }

            foreach (PropertyInfo prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                if (prop.Attr <ArgIgnoreAttribute>() != null)
                {
                    continue;
                }
                if (CommandLineAction.IsActionImplementation(prop))
                {
                    continue;
                }

                // This check happens in the CommandLineArgumentsDefinition validation method and should not be repeated here.  Leaving the code commented while this bakes, but this code
                // should be removable in the future.
                //if (ArgRevivers.CanRevive(prop.PropertyType) == false)
                //{
                //    throw new InvalidArgDefinitionException("There is no reviver for type " + prop.PropertyType.Name + ". Offending Property: " + prop.DeclaringType.Name + "." + prop.Name);
                //}

                if (prop.PropertyType.IsEnum)
                {
                    prop.PropertyType.ValidateNoDuplicateEnumShortcuts(ignoreCase);
                }

                var attrs = prop.Attrs <ArgShortcut>();
                var noShortcutsAllowed   = attrs.Where(a => a.Policy == ArgShortcutPolicy.NoShortcut).Count() != 0;
                var shortcutsOnly        = attrs.Where(a => a.Policy == ArgShortcutPolicy.ShortcutsOnly).Count() != 0;
                var actualShortcutValues = attrs.Where(a => a.Policy == ArgShortcutPolicy.Default && a.Shortcut != null).Count() != 0;

                if (noShortcutsAllowed && shortcutsOnly)
                {
                    throw new InvalidArgDefinitionException("You cannot specify a policy of NoShortcut and another policy of ShortcutsOnly.");
                }
                if (noShortcutsAllowed && actualShortcutValues)
                {
                    throw new InvalidArgDefinitionException("You cannot specify a policy of NoShortcut and then also specify shortcut values via another attribute.");
                }
                if (shortcutsOnly && actualShortcutValues == false)
                {
                    throw new InvalidArgDefinitionException("You specified a policy of ShortcutsOnly, but did not specify any shortcuts by adding another ArgShortcut attrivute.");
                }
            }

            if (actionProp != null)
            {
                foreach (PropertyInfo prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                {
                    if (CommandLineAction.IsActionImplementation(prop))
                    {
                        ArgAction.ResolveMethod(t, prop);
                        ValidateArgScaffold(prop.PropertyType, shortcuts.ToArray().ToList(), t);
                    }
                }
            }

            foreach (var actionMethod in t.GetActionMethods())
            {
                if (actionMethod.GetParameters().Length == 0)
                {
                    continue;
                }

                ValidateArgScaffold(actionMethod.GetParameters()[0].ParameterType, shortcuts.ToArray().ToList(), t);
            }
        }
Ejemplo n.º 20
0
 protected bool Equals(CommandLineAction other)
 {
     return(Equals(Source, other.Source));
 }