/// <summary>
 /// Checks to see if the current argument is allowed to have a value based on which other arguments are present and based on the expression
 /// passed to the constructor.  If it's not allowed and has been specified then an UnexpectedArgException is thrown.
 /// </summary>
 /// <param name="context">The current PowerArgs processing context</param>
 public override void AfterPopulateProperties(ArgHook.HookContext context)
 {
     if(IsCurrentArgumentAllowed(context) == false && context.CurrentArgument.RevivedValue != null)
     {
         throw new UnexpectedArgException("The argument '" + context.CurrentArgument.DefaultAlias + "' cannot be used with one or more arguments: " + ExpressionText);
     }
 }
Beispiel #2
0
 /// <summary>
 /// Makes sure the target is a boolean
 /// </summary>
 /// <param name="context">Context passed by the parser</param>
 public override void BeforePopulateProperty(ArgHook.HookContext context)
 {
     base.BeforePopulateProperty(context);
     if (context.CurrentArgument.ArgumentType != typeof(bool))
     {
         throw new InvalidArgDefinitionException(typeof(HelpHook).Name +" attributes can only be used with boolean properties or parameters");
     }
 }
Beispiel #3
0
 /// <summary>
 /// Writes the help as long as WriteHelp is true
 /// </summary>
 /// <param name="context">Context passed by the parser</param>
 public override void AfterCancel(ArgHook.HookContext context)
 {
     base.AfterCancel(context);
     
     if (WriteHelp == false) return;
         
     ArgUsage.GetStyledUsage(context.Definition, EXEName, new ArgUsageOptions()
     {
         ShowPosition = ShowPositionColumn,
         ShowType = ShowTypeColumn,
         ShowPossibleValues = ShowPossibleValues,
     }).Write();
 }
        public override void BeforeInvoke(ArgHook.HookContext context)
        {
            var action = context.SpecifiedAction;
            var storageAccountNameArgument = action.FindMatchingArgument("StorageAccountName");
            var storageAccountKeyArgument = action.FindMatchingArgument("StorageAccountKey");

            if (storageAccountNameArgument != null && storageAccountKeyArgument != null)
            {
                CommandLineStorageConfigProvider.CommandLineAccountName = "" + storageAccountNameArgument.RevivedValue;
                CommandLineStorageConfigProvider.CommandLineAccountKey = "" + storageAccountKeyArgument.RevivedValue;
                SharedStorageAccount.Reset(new CommandLineStorageConfigProvider());
            }
        }
        /// <summary>
        /// Determines if the current argument is allowed to be populated based on which other arguments are present and based on the expression passed to the constructor.
        /// </summary>
        /// <param name="context">The current PowerArgs processing context</param>
        /// <returns>True if this argument can be specified, false otherwise</returns>
        public bool IsCurrentArgumentAllowed(ArgHook.HookContext context)
        {
            if (context.CurrentArgument == null)
            {
                throw new InvalidArgDefinitionException("The " + GetType().Name + " metadata must be applied to a particular argument");
            }

            try
            {
                bool eval = this.Expression.Evaluate(context.Definition.CreateVariableResolver());
                if (eval == true)
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                var targetText = context.CurrentArgument.DefaultAlias;
                throw new InvalidArgDefinitionException("Failed to evaluate conditional " + GetType().Name + " clause on target '" + targetText + "' - " + ex.Message);
            }

            return true;
        }
        /// <summary>
        /// Prompts the user to enter a value for the given property in the case that the option was specified with no value
        /// </summary>
        /// <param name="context">the parser context</param>
        public override void BeforePopulateProperty(ArgHook.HookContext context)
        {
            if (context.ArgumentValue == string.Empty)
            {
                var cli = new CliHelper();

                ITabCompletionHandler tabHandler;
                IHighlighterConfigurator highlighterConfigurator;

                if (TabCompletionHandlerType.TryCreate<ITabCompletionHandler>(out tabHandler))
                {
                    cli.Reader.TabHandler.TabCompletionHandlers.Add(tabHandler);
                }

                if (HighlighterConfiguratorType.TryCreate<IHighlighterConfigurator>(out highlighterConfigurator))
                {
                    cli.Reader.Highlighter = new SimpleSyntaxHighlighter();
                    highlighterConfigurator.Configure(cli.Reader.Highlighter);
                }

                context.ArgumentValue = cli.PromptForLine("Enter value for " + context.CurrentArgument.DefaultAlias);
            }
        }
        /// <summary>
        /// If the current argument is a boolean and it is specified on the command line then
        /// this hook sets the IsNonInteractive flag on the current argument definition.
        /// </summary>
        /// <param name="context"></param>
        public override void BeforeParse(ArgHook.HookContext context)
        {
            if(context.CurrentArgument.ArgumentType != typeof(bool))
            {
                throw new InvalidArgDefinitionException(GetType().Name + " can only be used on boolean arguments");
            }

            for (int i = 0; i < context.CmdLineArgs.Length; i++ )
            {
                var arg = context.CmdLineArgs[i];
                string key;

                if (ArgParser.TryParseKey(arg, out key))
                {
                    var nextArg = i == context.CmdLineArgs.Length - 1 ? "" : context.CmdLineArgs[i + 1].ToLower();

                    // TODO - Find a better way to detect explicit 'false'
                    if (context.CurrentArgument.IsMatch(key) && nextArg != "false" && nextArg != "0")
                    {
                        context.Definition.IsNonInteractive = true;
                    }
                }
            }
        }
Beispiel #8
0
 public override void BeforeParse(ArgHook.HookContext context)
 {
     context.SetProperty("Year", 2013);
     context.SetProperty("Year", 2013);
     context.SetProperty("Name", "Adam");
     context.SetProperty("Name", "Adam");
 }
Beispiel #9
0
            public override void AfterPopulateProperties(ArgHook.HookContext context)
            {
                Assert.IsTrue(context.HasProperty("Year"));
                Assert.IsTrue(context.HasProperty("Name"));

                var year = context.GetProperty<int>("Year");
                var name = context.GetProperty<string>("Name");

                Assert.AreEqual(2013, year);
                Assert.AreEqual("Adam", name);

                context.ClearProperty("Year");
                context.SetProperty<string>("Name", null);

                Assert.IsFalse(context.HasProperty("Year"));
                Assert.IsFalse(context.HasProperty("Name"));

                Assert.IsNull(context.GetProperty<string>("Name"));

                try
                {
                    context.GetProperty<int>("Year");
                    Assert.Fail("An exception should have been thrown");
                }
                catch (KeyNotFoundException)
                {
                    // Throw for value types, return null for reference types
                }

                WasRun = true;
            }
Beispiel #10
0
        private bool TryPreventExceptionWithPrompt(ArgHook.HookContext context)
        {
            if (parent.PromptIfMissing && ArgHook.HookContext.Current.Definition.IsNonInteractive == false)
            {

                var cli = new Cli();

                ITabCompletionHandler tabHandler;
                IHighlighterConfigurator highlighterConfigurator;

                if (TabCompletionHandlerType.TryCreate<ITabCompletionHandler>(out tabHandler))
                {
                    cli.Reader.TabHandler.TabCompletionHandlers.Add(tabHandler);
                }

                if (HighlighterConfiguratorType.TryCreate<IHighlighterConfigurator>(out highlighterConfigurator))
                {
                    cli.Reader.Highlighter = new SimpleSyntaxHighlighter();
                    highlighterConfigurator.Configure(cli.Reader.Highlighter);
                }

                context.ArgumentValue = cli.PromptForLine("Enter value for " + context.CurrentArgument.DefaultAlias);
                context.CurrentArgument.Populate(context);
                return true;
            }
            else
            {
                return false;
            }
        }
Beispiel #11
0
        private void Evaluate(ArgHook.HookContext context, string expressionText, bool not)
        {
            try
            {
                var newExpressionText = expressionText;
                if(not)
                {
                    newExpressionText = "!(" + expressionText + ")";
                }

                var expression = BooleanExpressionParser.Parse(newExpressionText);
                var eval = expression.Evaluate(context.Definition.CreateVariableResolver());

                if(not)
                {
                    if (eval == true && context.CurrentArgument.RevivedValue == null)
                    {
                        if (TryPreventExceptionWithPrompt(context) == false)
                        {
                            throw new MissingArgException("The argument '" + context.CurrentArgument.DefaultAlias + "' is required if the following argument(s) are not specified: " + expressionText);
                        }
                    }
                }
                else
                {
                    if (eval == true && context.CurrentArgument.RevivedValue == null)
                    {
                        if (TryPreventExceptionWithPrompt(context) == false)
                        {
                            throw new MissingArgException("The argument '" + context.CurrentArgument.DefaultAlias + "' is required if the following argument(s) are specified: " + expressionText);
                        }
                    }
                }
            }
            catch(MissingArgException)
            {
                throw;
            }
            catch (Exception ex)
            {
                var targetText = context.CurrentArgument.DefaultAlias + " (" + expressionText + ")";
                throw new InvalidArgDefinitionException("Failed to evaluate conditional ArgRequired clause on target '" + targetText + "'" + ex.Message);
            }
        }
 internal static void PopulateArguments(List<CommandLineArgument> arguments, ArgHook.HookContext context)
 {
     foreach (var argument in arguments)
     {
         argument.FindMatchingArgumentInRawParseData(context);
         argument.Populate(context);
     }
 }
Beispiel #13
0
 /// <summary>
 /// Writes the help as long as WriteHelp is true
 /// </summary>
 /// <param name="context">Context passed by the parser</param>
 public override void AfterCancel(ArgHook.HookContext context)
 {
     base.AfterCancel(context);
     if (iDidTheCancel == false) return;
     if (WriteHelp == false) return;
     var usage = UsageTemplateProvider.GetUsage(UsageTemplateProviderType, context.Definition);
     usage.Write();
     FireUsageWritten(usage);
 }
 public override void BeforeInvoke(ArgHook.HookContext context)
 {
     context.CancelAllProcessing();
 }
 internal static void PopulateArguments(List<CommandLineArgument> arguments, ArgHook.HookContext context)
 {
     var oldCurrent = context.CurrentArgument;
     try
     {
         foreach (var argument in arguments)
         {
             context.CurrentArgument = argument;
             argument.FindMatchingArgumentInRawParseData(context);
             argument.Populate(context);
         }
     }
     finally
     {
         context.CurrentArgument = oldCurrent;
     }
 }
Beispiel #16
0
        /// <summary>
        /// Before PowerArgs parses the args, this hook inspects the command line for the indicator and if found 
        /// takes over the command line and provides tab completion.
        /// </summary>
        /// <param name="context">The context used to inspect the command line arguments.</param>
        public override void BeforeParse(ArgHook.HookContext context)
        {
            if (Indicator == "" && context.CmdLineArgs.Length != 0) return;
            else if (Indicator != "" && (context.CmdLineArgs.Length != 1 || context.CmdLineArgs[0] != Indicator)) return;

            var existingColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Cyan;
            try
            {
                if (REPL && ShowREPLWelcome)
                {
                    Console.WriteLine();
                    var message = REPLWelcomeMessage.Replace("{{Indicator}}", REPLExitIndicator);
                    Console.WriteLine(message);
                    Console.WriteLine();
                    Console.Write(Indicator + "> ");
                    ShowREPLWelcome = false;
                }
                else if (REPL)
                {
                    Console.Write(Indicator + "> ");
                }
                else
                {

                    // This is a little hacky, but I could not find a better way to make the tab completion start on the same lime
                    // as the command line input
                    try
                    {
                        var lastLine = StdConsoleProvider.ReadALineOfConsoleOutput(Console.CursorTop - 1);
                        Console.CursorTop--;
                        Console.WriteLine(lastLine);
                        Console.CursorTop--;
                        Console.CursorLeft = lastLine.Length + 1;
                    }
                    catch (Exception)
                    {
                        Console.WriteLine();
                        Console.Write(Indicator + "> ");
                    }
                }
            }
            finally
            {
                Console.ForegroundColor = existingColor;
            }

            List<string> completions = FindTabCompletions(context.Definition.Arguments, context.Definition.Actions);

            List<ITabCompletionSource> completionSources = new List<ITabCompletionSource>();

            if(this.completionSource != null) completionSources.Add((ITabCompletionSource)Activator.CreateInstance(this.completionSource));
            completionSources.Add(new EnumTabCompletionSource(context.Definition));
            completionSources.Add(new SimpleTabCompletionSource(completions) { MinCharsBeforeCyclingBegins = 0 });
            completionSources.Add(new FileSystemTabCompletionSource());
            
            string str = null;
            var newCommandLine = ConsoleHelper.ReadLine(ref str, LoadHistory(), new MultiTabCompletionSource(completionSources));

            if (REPL && newCommandLine.Length == 1 && string.Equals(newCommandLine[0], REPLExitIndicator, StringComparison.OrdinalIgnoreCase))
            {
                throw new REPLExitException();
            }

            if (REPL && newCommandLine.Length == 1 && newCommandLine[0] == "cls")
            {
                ConsoleHelper.ConsoleImpl.Clear();
                throw new REPLContinueException();
            }

            else if (REPL && newCommandLine.Length == 0 && string.IsNullOrWhiteSpace(REPLExitIndicator) == false)
            {
                throw new REPLContinueException();
            }

            context.CmdLineArgs = newCommandLine;
            AddToHistory(str);
        }
        private void FindMatchingArgumentInRawParseData(ArgHook.HookContext context)
        {
            var match = from k in context.ParserData.ExplicitParameters.Keys where IsMatch(k) select k;

            if (match.Count() > 1)
            {
                throw new DuplicateArgException("Argument specified more than once: " + Aliases.First());
            }
            else if (match.Count() == 1)
            {
                var key = match.First();
                context.ArgumentValue = context.ParserData.ExplicitParameters[key];
                context.ParserData.ExplicitParameters.Remove(key);
            }
            else if (context.ParserData.ImplicitParameters.ContainsKey(Position))
            {
                var position = Position;
                context.ArgumentValue = context.ParserData.ImplicitParameters[position];
                context.ParserData.ImplicitParameters.Remove(position);
            }
            else
            {
                context.ArgumentValue = null;
            }
        }
 internal void RunBeforePopulateProperty(ArgHook.HookContext context)
 {
     RunArgumentHook(context, h => h.BeforePopulatePropertyPriority, (h) => { h.BeforePopulateProperty(context); });
 }
        internal void RunArgumentHook(ArgHook.HookContext context, Func<ArgHook, int> orderby, Action<ArgHook> hookAction)
        {
            context.Property = Source as PropertyInfo;
            context.CurrentArgument = this;

            foreach (var hook in Hooks.OrderBy(orderby))
            {
                hookAction(hook);
            }

            context.Property = null;
            context.CurrentArgument = null;
        }
        internal void Populate(ArgHook.HookContext context)
        {
            RunBeforePopulateProperty(context);

            if (RevivedValueOverride == null)
            {
                Validate(ref context.ArgumentValue);
                Revive(context.ArgumentValue);
            }
            else
            {
                RevivedValue = RevivedValueOverride;
                RevivedValueOverride = null;
            }

            RunAfterPopulateProperty(context);
        }
Beispiel #21
0
        /// <summary>
        /// Before PowerArgs parses the args, this hook inspects the command line for the indicator and if found 
        /// takes over the command line and provides tab completion.
        /// </summary>
        /// <param name="context">The context used to inspect the command line arguments.</param>
        public override void BeforeParse(ArgHook.HookContext context)
        {
            if (indicator == "" && context.CmdLineArgs.Length != 0)return;
            else if (indicator != "" && (context.CmdLineArgs.Length != 1 || context.CmdLineArgs[0] != indicator)) return;

            try
            {
                // This is a little hacky, but I could not find a better way to make the tab completion start on the same lime
                // as the command line input

                var color = Console.ForegroundColor;
                var lastLine = ConsoleHelper.StdConsoleProvider.ReadALineOfConsoleOutput(Console.CursorTop - 1);
                Console.CursorTop--;
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine(lastLine);
                Console.ForegroundColor = color;
                Console.CursorTop--;
                Console.CursorLeft = lastLine.Length + 1;
            }
            catch (Exception)
            {
                Console.Write(indicator + "> ");
            }

            List<string> completions = FindTabCompletions(context.Args.GetType());

            List<ITabCompletionSource> completionSources = new List<ITabCompletionSource>();

            if(this.completionSource != null) completionSources.Add((ITabCompletionSource)Activator.CreateInstance(this.completionSource));
            completionSources.Add(new EnumTabCompletionSource(context.Args.GetType()));
            completionSources.Add(new SimpleTabCompletionSource(completions) { MinCharsBeforeCyclingBegins = 0 });
            completionSources.Add(new FileSystemTabCompletionSource());

            string str = null;
            context.CmdLineArgs = ConsoleHelper.ReadLine(ref str, LoadHistory(), new MultiTabCompletionSource(completionSources));
            AddToHistory(str);
        }
 public override void AfterCancel(ArgHook.HookContext context)
 {
     AfterCancelCalled = true;
 }
Beispiel #23
0
        /// <summary>
        /// Before PowerArgs parses the args, this hook inspects the command line for the indicator and if found 
        /// takes over the command line and provides tab completion.
        /// </summary>
        /// <param name="context">The context used to inspect the command line arguments.</param>
        public override void BeforeParse(ArgHook.HookContext context)
        {
          
            if (CompletionSourceType != null && 
                CompletionSourceType.GetInterfaces().Contains(typeof(ITabCompletionSource)) == false &&
                CompletionSourceType.GetInterfaces().Contains(typeof(ISmartTabCompletionSource)) == false)
            {
                throw new InvalidArgDefinitionException("Type does not implement ITabCompletionSource or ISmartTabCompletionSource: " + CompletionSourceType.FullName);
            }

            if (context.Definition.IsNonInteractive)
            {
                this.REPL = false;
                return;
            }
            if (Indicator == "" && context.CmdLineArgs.Length != 0)
            {
                this.REPL = false;
                return;
            }
            if (Indicator != "" && (context.CmdLineArgs.Length != 1 || context.CmdLineArgs[0] != Indicator))
            {
                this.REPL = false;
                return;
            }
            
            if (REPL && ShowREPLWelcome)
            {
                ConsoleString.Empty.WriteLine();
                var message = REPLWelcomeMessage.Replace("{{Indicator}}", REPLExitIndicator);
                ConsoleString.WriteLine(message, ConsoleColor.Cyan);
                ConsoleString.Empty.WriteLine();
                ConsoleString.Write(Indicator + "> ", ConsoleColor.Cyan);
                ShowREPLWelcome = false;
            }
            else if (REPL)
            {
                ConsoleString.Write(Indicator + "> ", ConsoleColor.Cyan);
            }
            else
            {

                // This is a little hacky, but I could not find a better way to make the tab completion start on the same lime
                // as the command line input
                try
                {
                    var lastLine = StdConsoleProvider.ReadALineOfConsoleOutput(Console.CursorTop - 1);
                    Console.CursorTop--;
                    Console.WriteLine(lastLine);
                    Console.CursorTop--;
                    Console.CursorLeft = lastLine.Length + 1;
                }
                catch (Exception)
                {
                    Console.WriteLine();
                    Console.Write(Indicator + "> ");
                }
            }

            PowerArgsRichCommandLineReader reader = new PowerArgsRichCommandLineReader(context.Definition, LoadHistory());

            IHighlighterConfigurator customConfigurator;
            if(HighlighterConfiguratorType.TryCreate<IHighlighterConfigurator>(out customConfigurator))
            {
                customConfigurator.Configure(reader.Highlighter);
            }

            var newCommandLineString = reader.ReadLine().ToString();
            var newCommandLineArray = Args.Convert(newCommandLineString);

            if (REPL && newCommandLineArray.Length == 1 && string.Equals(newCommandLineArray[0], REPLExitIndicator, StringComparison.OrdinalIgnoreCase))
            {
                throw new REPLExitException();
            }

            if (REPL && newCommandLineArray.Length == 1 && newCommandLineArray[0] == "cls")
            {
                ConsoleProvider.Current.Clear();
                throw new REPLContinueException();
            }

            else if (REPL && newCommandLineArray.Length == 0 && string.IsNullOrWhiteSpace(REPLExitIndicator) == false)
            {
                throw new REPLContinueException();
            }

            context.CmdLineArgs = newCommandLineArray;
            AddToHistory(newCommandLineString);
        }
 internal void Validate(ArgHook.HookContext context)
 {
     context.RunBeforeValidateDefinition();
     ValidateArguments(Arguments);
     ValidateActionAliases();
     foreach (var action in Actions)
     {
         if (action.Aliases.Count == 0) throw new InvalidArgDefinitionException("One of your actions has no aliases");
         ValidateArguments(Arguments.Union(action.Arguments));
         if (action.ActionMethod == null) throw new InvalidArgDefinitionException("The action '"+action.DefaultAlias+"' has no ActionMethod defined");
     }
 }
Beispiel #25
0
 public override void AfterPopulateProperties(ArgHook.HookContext context)
 {
     if(parent.If != null && parent.IfNot != null)
     {
         throw new InvalidArgDefinitionException("You cannot specify both the 'If' and the 'IfNot' properties on the ArgRequired metadata");
     }
     else if(parent.If != null)
     {
         Evaluate(context, parent.If, false);
     }
     else if (parent.IfNot != null)
     {
         Evaluate(context, parent.IfNot, true);
     }
     else
     {
         throw new InvalidOperationException("ArgRequired could not determine if the given argument was required.  This is likely a bug in PowerArgs.");
     }
 }
Beispiel #26
0
        private bool TryPreventExceptionWithPrompt(ArgHook.HookContext context)
        {
            if (parent.PromptIfMissing && ArgHook.HookContext.Current.Definition.IsNonInteractive == false)
            {

                var cli = new CliHelper();

                ITabCompletionHandler tabHandler;
                IHighlighterConfigurator highlighterConfigurator;

                if (TabCompletionHandlerType.TryCreate<ITabCompletionHandler>(out tabHandler))
                {
                    cli.Reader.TabHandler.TabCompletionHandlers.Add(tabHandler);
                }

                if (HighlighterConfiguratorType.TryCreate<IHighlighterConfigurator>(out highlighterConfigurator))
                {
                    cli.Reader.Highlighter = new SimpleSyntaxHighlighter();
                    highlighterConfigurator.Configure(cli.Reader.Highlighter);
                }

                cli.Reader.UnregisterHandler(ConsoleKey.Escape);
                cli.Reader.RegisterHandler(KeyHandler.FromAction((searchReaderContext) =>
                {
                    TabCompletion tabCompletionInfo;
                    if (context.Definition.IsNonInteractive == false &&
                        context.Definition.Metadata.TryGetMeta<TabCompletion>(out tabCompletionInfo) &&
                        tabCompletionInfo.REPL == true)
                    {
                        // if this is an interactive REPL then continue the REPL in this case as the user may have changed their mind about taking
                        // this action - Note there are two places in this file that have this logic
                        throw new REPLContinueException();
                    }
                    else
                    {
                        throw new MissingArgException("The argument '" + context.CurrentArgument.DefaultAlias + "' is required", new ArgumentNullException(context.CurrentArgument.DefaultAlias));
                    }
                }, ConsoleKey.Escape));

                context.ArgumentValue = cli.PromptForLine("Enter value for " + context.CurrentArgument.DefaultAlias);
                context.CurrentArgument.Populate(context);
                return true;
            }
            else
            {
                return false;
            }
        }
 internal static void PopulateArguments(List<CommandLineArgument> arguments, ArgHook.HookContext context)
 {
     foreach (var argument in arguments)
     {
         argument.FindMatchingArgumentInRawParseData(context);
         argument.RunBeforePopulateProperty(context);
         argument.Validate(ref context.ArgumentValue);
         argument.Revive(context.ArgumentValue);
         argument.RunAfterPopulateProperty(context);
     }
 }