Пример #1
0
    /// <summary>
    /// Performs execution of the source of the script
    /// </summary>
    /// <param name="scriptSource">The source of the script to execute</param>
    /// <param name="directive">The execution directives to execute with</param>
    /// <returns>The outcome of the execution</returns>
    private CommandResult ExecuteScriptSource(string scriptSource, ExecutionDirective directive)
    {
      var output = new StringBuilder();
      var status = CommandStatus.Success;
      var lines = Parser.ParseScriptLines(scriptSource, _formatter);

      var workingDirective = ExecutionDirective.GetDefault();

      if (!directive.IsEmpty())
        workingDirective.Patch(directive);

      _executionFaulted = false;

      // Execute each line
      foreach(var line in lines)
      {
        // Don't execute a comment line (starts with #) and don't execute if faulted
        if (!line.StartsWith(Constants.ScriptCommentLineIndicator) && !_executionFaulted)
        {
          // Look for directives
          if (line.StartsWith(Constants.ScriptDirectiveIndicator))
          {
            // Extract directive in string
            var directiveString = line.Substring(1);

            // Parse string to get directive
            var currentDirective = ExecutionDirective.Parse(directiveString);

            if (currentDirective.IsEmpty())
              _formatter.PrintLine("Unknown directive '" + directiveString + "'", output);

            workingDirective.Patch(currentDirective);
          }
          else
          {
            var res = Execute(line, workingDirective);

            if (res != null)
            {
              if (!(bool)(workingDirective.EchoOff ?? false))
              {
                _formatter.PrintLine(res.Message, output);
              }

              if (res.Status == CommandStatus.Abort)
                return new CommandResult(CommandStatus.Success, res.Message);

              if (res.Status != CommandStatus.Success)
                status = CommandStatus.Failure;
            }
            else
            {
              _executionFaulted = false;
              return null;
            }
          }
        }
      }

      _executionFaulted = false;
      return new CommandResult(status, output.ToString());
    }
Пример #2
0
    /// <summary>
    /// Execute a script
    /// </summary>
    /// <param name="name">The name of the script to process</param>
    /// <param name="args">The arguments to the script</param>
    /// <param name="directive">Execution directives to control how execution should perform</param>
    /// <returns>The output from the script if the script was found, otherwise null</returns>
    private CommandResult ExecuteScript(string name, string[] args, ExecutionDirective directive)
    {
      try
      {
        var script = ScriptLocator.GetScript(name);
        if (script != null)
        {
          // Substitute script parameters
          for (int i = 0; i < args.Length; i++)
          {
            script = script.Replace("$" + (i + 1) + "$", args[i]);
          }

          return ExecuteScriptSource(script, directive);
        }
      }
      catch (MultipleScriptsFoundException ex)
      {
        var message = new StringBuilder();
        foreach (var scriptName in ex.Names)
        {
          _formatter.PrintLine(scriptName, message);
        }

        message.Append("Multiple scripts found by name '");
        message.Append(name);
        _formatter.PrintLine("'", message);
        message.Append("Script names must be unique");

        return new CommandResult(CommandStatus.Failure, message.ToString());
      }

      if (directive.StopOnError.HasValue && directive.StopOnError.Value)
        _executionFaulted = true;

      return null;
    }
Пример #3
0
    /// <summary>
    /// Executes a command
    /// </summary>
    /// <param name="cmd">The command to execute</param>
    /// <param name="args">Arguments to apply to the command</param>
    /// <param name="directive">Directives to execute with</param>
    /// <returns>The outcome of the execution</returns>
    private CommandResult ExecuteCommand(ICommand cmd, string[] args, ExecutionDirective directive)
    {
      cmd.Initialise(_context, _formatter);
      CommandResult result = null;

      var manualParseInterface = CommandInspector.GetManualParseCommand(cmd);
      if (manualParseInterface != null)
      {
        var subArgs = from arg in args
                      select Parser.PerformSubstitution(_context, arg);

        result = manualParseInterface.Run(subArgs.ToArray());
      }
      else
      {
        var properties = cmd.GetType().GetProperties();

        object propValue = null;
        var processingArgs = args;

        // Process multi-word named parameters first
        foreach (var prop in properties)
        {
          propValue = null;

          var namedParameterAttribute = CommandInspector.GetNamedParameter(prop);
          if (namedParameterAttribute != null && namedParameterAttribute.WordCount > 1)
          {
            var words = new List<string>();

            for (var i = 0; i < namedParameterAttribute.WordCount; i++)
            {
              var value = string.Empty;
              ParameterUtil.GetParameter(args, "-" + namedParameterAttribute.Name, i, ref value);
              if (!string.IsNullOrEmpty(value))
                words.Add(value);
            }

            if (words.Count > 0)
            {
              propValue = words.ToArray();
              processingArgs = ParameterUtil.RemoveParameter(processingArgs, "-" + namedParameterAttribute.Name, namedParameterAttribute.WordCount);
            }
          }

          ConvertAndAssignParameter(prop, cmd, propValue);
        }

        // Find flags
        var flags = from prop in properties
                    let attr = CommandInspector.GetFlagParameter(prop)
                    where attr != null
                    select attr.Name;

        // Parse remaining arguments
        StringDictionary named = null;
        string[] numbered = null;
        ParameterUtil.ExtractParameters(out named, out numbered, processingArgs, flags.ToArray());

        // Map the parameters to properties
        foreach (var prop in properties)
        {
          propValue = null;

          var namedParameterAttribute = CommandInspector.GetNamedParameter(prop);
          if (namedParameterAttribute != null)
          {
            if (named.ContainsKey(namedParameterAttribute.Name))
              propValue = named[namedParameterAttribute.Name];
          }

          var numberedParameterAttribute = CommandInspector.GetNumberedParameter(prop);
          if (numberedParameterAttribute != null)
          {
            if (numberedParameterAttribute.Number < numbered.Length)
              propValue = numbered[numberedParameterAttribute.Number];
          }

          var flagParameterAttribute = CommandInspector.GetFlagParameter(prop);
          if (flagParameterAttribute != null)
          {
            if (named.ContainsKey(flagParameterAttribute.Name))
            {
#if NET45
              var origVal = (bool)prop.GetValue(cmd);
#else
              var origVal = (bool)prop.GetValue(cmd, null);
#endif
              propValue = !origVal;
            }
          }

          ConvertAndAssignParameter(prop, cmd, propValue);
        }

        AssignListParameter(cmd, properties, numbered);

        result = cmd.Run();
      }

      if ((bool)(directive.StopOnError ?? false) && (result.Status == CommandStatus.Failure))
        _executionFaulted = true;

      return result;
    }
Пример #4
0
    /// <summary>
    /// Execute a command or script
    /// </summary>
    /// <param name="command">The command or script name</param>
    /// <param name="args">Arguments to pass to the command</param>
    /// <param name="directive">Execution directives to control how execution should perform</param>
    /// <returns>True if the command was run, otherwise returns false</returns>
    private CommandResult Execute(string command, string[] args, ExecutionDirective directive)
    {
      // update current date and time in environment variable
      Context.EnvironmentVariables["now"] = Sitecore.DateUtil.IsoNow;

      command = Parser.PerformSubstitution(_context, command);

      if (command == string.Empty)
        return new CommandResult(CommandStatus.Success, string.Empty);

      ICommand cmd = null;

      if (_commands.ContainsKey(command))
      {
        cmd = (ICommand)Activator.CreateInstance(_commands[command]);
      }
      else if (_custcommands.ContainsKey(command))
      {
        cmd = (ICommand)Activator.CreateInstance(_custcommands[command]);
      }
      else if(_commandAliases.ContainsKey(command) && _commands.ContainsKey(_commandAliases[command].CommandName))
      {
        var alias = _commandAliases[command];
        cmd = (ICommand)Activator.CreateInstance(_commands[alias.CommandName]);
        
        if(alias.Parameters != null && alias.Parameters.Length > 0)
        {
          var paramsList = new List<string>(alias.Parameters);
          paramsList.AddRange(args);
          args = paramsList.ToArray();
        }
      }

      if (cmd != null)
      {
        return ExecuteCommand(cmd, args, directive);
      }
      else
        return ExecuteScript(command, args, directive);
    }
Пример #5
0
    /// <summary>
    /// Executes a command
    /// </summary>
    /// <param name="elements">The elements forming the command and arguments</param>
    /// <param name="directive">Execution directives to control how execution should perform</param>
    private CommandResult Execute(string[] elements, ExecutionDirective directive)
    {
      EnsureValidContextItem();

      // Check if we have any subcommands
      var ind = Array.IndexOf(elements, Constants.SubcommandSymbol);
      while (ind >= 0)
      {
        var innerOutput = string.Empty;
        if (elements.Length >= (ind + 2))
        {
          var subelements = Parser.ParseInputLine(elements[ind + 1]);

          var innerResult = Execute(subelements, directive);
          if (innerResult.Status != CommandStatus.Success)
            return new CommandResult(innerResult.Status, "Subcommand failure: " + innerResult.Message);

          innerOutput = innerResult.Message;

          elements = elements.Take(ind).Concat(new[] { innerOutput }).Concat(elements.Skip(ind + 2)).ToArray();
        }

        ind = Array.IndexOf(elements, Constants.SubcommandSymbol);
      }

      // Check if we have any forwarding sub commands
      ind = Array.IndexOf(elements, Constants.CommandChainSymbol);
      while (ind >= 0)
      {
        var subelements = elements.Take(ind);

        var innerResult = Execute(subelements.ToArray(), directive);
        if (innerResult.Status != CommandStatus.Success)
          return new CommandResult(innerResult.Status, "Subcommand failure: " + innerResult.Message);

        _context.EnvironmentVariables[Constants.CommandChainedValue] = innerResult.Message;

        elements = elements.Skip(ind + 1).ToArray();

        ind = Array.IndexOf(elements, Constants.CommandChainSymbol);
      }

      if (elements.Length > 0)
      {
        for (var i = 0; i < elements.Length; i++)
        {
          if (elements[i].Contains(Constants.EscapedSubcommandSymbol))
            elements[i] = elements[i].Replace(Constants.EscapedSubcommandSymbol, Constants.SubcommandSymbol);

          if (elements[i].Contains(Constants.EscapedCommandChainSymbol))
            elements[i] = elements[i].Replace(Constants.EscapedCommandChainSymbol, Constants.CommandChainSymbol);
        }

        var args = elements.Skip(1).ToArray();

        var result = Execute(elements[0].Trim(), args, directive);
        if (result != null)
          return result;
        
        if (directive.IgnoreUnknownCommands == null || !directive.IgnoreUnknownCommands.Value)
          return new CommandResult(CommandStatus.Failure, "Unknown command or script name " + elements[0].Trim());
      }

      return new CommandResult(CommandStatus.Success, string.Empty);
    }
Пример #6
0
    /// <summary>
    /// Execute a single command line
    /// </summary>
    /// <param name="commandLine">The command line to execute</param>
    /// <param name="directive">Execution directives to control how execution should perform</param>
    /// <returns>String output from the execution</returns>
    public CommandResult Execute(string commandLine, ExecutionDirective directive)
    {
      var elements = Parser.ParseInputLine(commandLine);

      // Dispatch the command to the core command handler
      var result = Execute(elements, directive);
      return new CommandResult(result.Status, result.Message);
    }