/// <summary>
        /// <para>
        /// Overridden.  Provides the actual paramater parsing mechanism, outputting results to the
        /// <paramref name="output"/> collection.
        /// </para>
        /// </summary>
        /// <param name="rawCommandLine">
        /// A collection of <see cref="System.String"/> - the raw collection of string arguments received via the
        /// commandline.
        /// </param>
        /// <param name="longAliases">
        /// A dictionary of <see cref="System.String"/> and a collection of <see cref="IParameter"/>
        /// </param>
        /// <param name="shortAliases">
        /// A dictionary of <see cref="System.String"/> and a collection of <see cref="IParameter"/>
        /// </param>
        /// <param name="output">
        /// A <see cref="ParsedParameters"/>
        /// </param>
        /// <returns>
        /// A <see cref="ParsedParameters"/>
        /// </returns>
        protected override void Parse(IList<string> rawCommandLine,
                                  IDictionary<string, IList<IParameter>> longAliases,
                                  IDictionary<string, IList<IParameter>> shortAliases,
                                  ref ParsedParameters output)
        {
            IList<IParameter> previousParameters = null;
              string previousArgument = null;

              foreach(string argument in rawCommandLine)
              {
            IList<IParameter> currentParameters = this.GetMatchingParameters(argument, longAliases, shortAliases);

            if(previousParameters != null
               && previousParameters.Count > 0
               && previousParameters[0].Type == ParameterType.ValueRequired)
            {
              /* We are dealing with the value from a value-required parameter, store the results and remove the
               * reference to the previous parameter.
               */
              foreach(IParameter param in previousParameters)
              {
            output.StoreResult(param, argument);
              }
              previousParameters = null;
            }
            else if(previousParameters != null
                && previousParameters.Count > 0
                && previousParameters[0].Type == ParameterType.ValueOptional
                && currentParameters == null)
            {
              /* We are dealing with a value from a value-optional parameter - the argument does not look like a parameter
               * itself and so we treat it as the value, exactly as above.
               */
              foreach(IParameter param in previousParameters)
              {
            output.StoreResult(param, argument);
              }
              previousParameters = null;
            }
            else if(currentParameters != null)
            {
              /* We are dealing with a new parameter definition.  If there are parameters waiting to be stored then store
               * them and then deal with this new parameter.
               */
              if(previousParameters != null)
              {
            foreach(IParameter param in previousParameters)
            {
              output.StoreResult(param, null);
            }
            previousParameters = null;
              }

              previousParameters = currentParameters;
            }
            else
            {
              // We are dealing with a non-parameter argument; store it.
              output.StoreResult(argument);
            }

            previousArgument = argument;
              }

              /* After we have finished parsing everything else, if we still have 'previous parameters' buffered and not
               * stored then store them unless they are "value required" parameters, in which case add their argument as a
               * non-parameter argument.
               */
              if(previousParameters != null)
              {
            foreach(IParameter param in previousParameters)
            {
              if(param.Type != ParameterType.ValueRequired)
              {
            output.StoreResult(param, null);
              }
              else
              {
            output.StoreResult(previousArgument);
              }
            }
              }
        }
Beispiel #2
0
        /// <summary>
        /// Parse the controller classes and the input parameters.
        /// Pass execution to a controller.
        /// </summary>
        /// <param name="args">Command line arguments</param>
        public static async Task <int> Run(string[] args)
        {
            CLI.ParseMetadata();
            var cmd = new ParsedParameters(args);

            if (cmd.ShowHelpScreen)
            {
                // TODO: Show help screen
                return(1);
            }

            if (!controllers.ContainsKey(cmd.Controller))
            {
                throw new CommandParserException($"Controller '{cmd.Controller}' is unknown.");
            }

            var ctr = controllers[cmd.Controller];

            if (!ctr.Entries.ContainsKey(cmd.EntryPoint))
            {
                throw new CommandParserException($"Controller '{cmd.Controller}' has no entry point '{cmd.EntryPoint}'.");
            }

            var entryPoint = ctr.Entries[cmd.EntryPoint];

            /*
             *  Invoke a method
             */
            if (!entryPoint.MethodInfo.IsStatic)
            {
                throw new CommandParserException($"The method for entry point {cmd.Controller}/{cmd.EntryPoint} "
                                                 + $"is not static. Method name: '{entryPoint.MethodInfo.Name}'");
            }

            foreach (var p in entryPoint.Params)
            {
                if (!p.Value.Param.Optional && !cmd.Params.ContainsKey(p.Value.Param.Name))
                {
                    throw new CommandParserException($"Missing parameter '{p.Value.Param.Name}'.");
                }
            }

            object[] plist = null;

            if (entryPoint.Params.Count > 0)
            {
                plist = cmd.generateInvokeArray(entryPoint.Params.Values.Select(x => x.ParameterInfo).ToList());
            }

            try {
                if (entryPoint.MethodInfo.ReturnType.Name.StartsWith("Task"))
                {
                    await(Task) entryPoint.MethodInfo.Invoke(null, plist);
                }
                else
                {
                    entryPoint.MethodInfo.Invoke(null, plist);
                }
            } catch (TargetInvocationException ex) {
                if (ex.InnerException != null)
                {
                    throw(ex.InnerException);
                }
                else
                {
                    throw ex;
                }
            }

            return(0);
        }