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); }
/// <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 } }