namespace WoofWorkflows open System.IO type Stdout = Stdout of string Comp type PipelineModifier = private | WithEnv of key : string * value : string Comp | WorkingDir of dir : DirectoryInfo Comp | Remote of image : string Comp type Pipeline = | Empty | ShellScript of script : string * andThen : Pipeline | ShellScriptBind of script : string * consumeStdout : (Stdout -> Pipeline) | WithModifier of Pipeline * PipelineModifier list | Sequence of first : Pipeline * second : Pipeline [] type Pipeline<'plat> () = [] member _.WithEnv (mods : PipelineModifier list, (key : string, value : string Comp)) : PipelineModifier list = PipelineModifier.WithEnv (key, value) :: mods [] member _.WithEnv (() : unit, (key : string, value : string Comp)) : PipelineModifier list = [PipelineModifier.WithEnv (key, value)] [] member _.WorkingDir (mods : PipelineModifier list, (dir : DirectoryInfo Comp)) : PipelineModifier list = PipelineModifier.WorkingDir dir :: mods [] member _.WorkingDir (() : unit, dir : DirectoryInfo Comp) : PipelineModifier list = [PipelineModifier.WorkingDir dir] [] member _.Remote (() : unit, image : string Comp) : PipelineModifier list = [PipelineModifier.Remote image] [] member _.Remote (mods : PipelineModifier list, image : string Comp) : PipelineModifier list = PipelineModifier.Remote image :: mods member _.Return (() : unit) = Pipeline.Empty /// For running a script, capturing stdout member _.Bind<'b> (toRun : string, cont : Stdout -> Pipeline) : Pipeline = Pipeline.ShellScriptBind (toRun, cont) /// For running a script, without capturing stdout member _.Bind (toRun : string, cont : unit -> Pipeline) : Pipeline = Pipeline.ShellScript (toRun, cont ()) member _.Bind (p : Pipeline, cont : unit -> Pipeline) : Pipeline = Pipeline.Sequence (p, cont ()) member _.Yield (() : unit) : unit = () member _.For (expr : PipelineModifier list, cont : unit -> Pipeline) : Pipeline = Pipeline.WithModifier (cont (), expr) [] module Pipeline = let pipeline<'plat> = Pipeline<'plat> () let toStepDag (p : Pipeline) : SealedStepDag = failwith "TODO" let foo : SealedStepDag = pipeline { withEnv ("hi", Comp.make "bye") workingDir (Comp.make (DirectoryInfo "code root here")) withEnv ("foo", Comp.make "bar") remote (Comp.make "some-image") let! (Stdout stdout) = "sh script here" do! pipeline { withEnv ("foo", stdout) do! "git config --foo" return () } do! "a shell script" return () } |> toStepDag (* declarative.Bind>( declarative.RunShell( declarative.Bind, object, string>( "sh script here", (FSharpFunc, SealedStepDag>) declarative.Return ), (FSharpFunc) (fun _ -> "a shell script") ), (FSharpFunc>) (fun _ -> string message = "hi"; if (true) throw Operators.Failure(message); StepDag sd = (StepDag) null; return declarative.Return(sd); ) ); *)