internal PipelineStage CreateNextStage(ArgHook.HookContext context, string[] commandLine, ICommandLineArgumentsDefinitionFactory factory)
        {
            PipelineStage     next;
            CommandLineAction inProcAction;

            if (Stages.Count == 0)
            {
                next = new RootPipelineStage(commandLine);
            }
            else if (commandLine[0].StartsWith(ArgPipeline.PipelineStageActionIndicator) && ArgPipelineActionStage.TryCreateActionStage(commandLine, out next))
            {
                // do nothing, next is populated
            }
            else if (TryParseStageAction(context.Definition, commandLine[0], out inProcAction))
            {
                next = new InProcessPipelineStage(context.Definition, commandLine);
            }
            else if (ExternalPipelineProvider.TryLoadOutputStage(commandLine, out next) == false)
            {
                throw new UnexpectedArgException("The pipeline action '" + string.Join(" ", commandLine) + "' is not valid.  If you want to support piping between processes, learn how to here (TODO URL)");
            }

            next.CommandLineDefinitionFactory = factory;

            this.AddStage(next);
            return(next);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This is the main hook point where the pipeline features get injected.  This method is responsible for creating the pipeline if needed.  It is also
        /// responsible for connecting to an external program if this program was launched by another program's pipeline manager.  It is also responsible for
        /// supporting any pipeline stage actions (e.g. $filter) that are not supported if the [ArgPipeline] metadata is omitted from the root definition.
        /// </summary>
        /// <param name="context">The processing context</param>
        public override void BeforeParse(ArgHook.HookContext context)
        {
            ExternalPipelineInputStage externalStage;

            if (ExternalPipelineProvider.TryLoadInputStage(context.Definition, context.CmdLineArgs, out externalStage) && externalStage.IsProgramLaunchedByExternalPipeline)
            {
                externalStage.CommandLineDefinitionFactory = this.commandLineDeinitionFactory;
                while (externalStage.IsDrained == false)
                {
                    Thread.Sleep(10);
                }
                PowerLogger.LogLine("Input stage drained");
                context.CancelAllProcessing();
                return;
            }
            else if (context.CmdLineArgs.Contains(PowerArgsPipeIndicator))
            {
                ValidatePipeline(context);
                List <List <string> > stageCommandLines = new List <List <string> >();
                stageCommandLines.Add(new List <string>());

                for (int i = 0; i < context.CmdLineArgs.Length; i++)
                {
                    var arg = context.CmdLineArgs[i];
                    if (arg == PowerArgsPipeIndicator)
                    {
                        stageCommandLines.Add(new List <string>());
                    }
                    else
                    {
                        stageCommandLines.Last().Add(arg);
                    }
                }

                context.CmdLineArgs = stageCommandLines.First().ToArray();

                var manager = GetPipelineManagerFromContext(context);

                for (int i = 0; i < stageCommandLines.Count; i++)
                {
                    var args = stageCommandLines[i];
                    if (args.Count == 0)
                    {
                        throw new ArgException("Missing action after pipeline indicator: " + PowerArgsPipeIndicator);
                    }
                    manager.CreateNextStage(context, args.ToArray(), this.commandLineDeinitionFactory);
                }

                context.CmdLineArgs = manager.Stages[0].CmdLineArgs.ToArray();
            }
            else
            {
                // do nothing
            }
        }