@@ -349,13 +349,22 @@ func (cg *CodeGen) EmitFilesystemBuiltinChainStmt(ctx context.Context, scope *pa
349349 // to be in the context of a specific function run is in.
350350 case with .Expr .FuncLit != nil :
351351 for _ , stmt := range with .Expr .FuncLit .Body .NonEmptyStmts () {
352- if stmt .Call .Func . Name () != "mount" || stmt . Call . Alias == nil {
352+ if stmt .Call .Alias == nil {
353353 continue
354354 }
355355
356- target , err := cg .EmitStringExpr (ctx , scope , stmt .Call .Args [1 ])
357- if err != nil {
358- return fc , err
356+ var target string
357+ switch stmt .Call .Func .Name () {
358+ case "mount" :
359+ target , err = cg .EmitStringExpr (ctx , scope , stmt .Call .Args [1 ])
360+ if err != nil {
361+ return fc , err
362+ }
363+ case "capture" :
364+ target = "capture"
365+ }
366+ if target == "" {
367+ continue
359368 }
360369
361370 calls [target ] = stmt .Call
@@ -381,7 +390,43 @@ func (cg *CodeGen) EmitFilesystemBuiltinChainStmt(ctx context.Context, scope *pa
381390 for _ , target := range targets {
382391 // Mounts are unique by its mountpoint, and its vertex representing the
383392 // mount after execing can be aliased.
384- cont := ac (calls [target ], exec .GetMount (target ))
393+ var cont bool
394+ switch calls [target ].Func .Name () {
395+ case "mount" :
396+ cont = ac (calls [target ], exec .GetMount (target ))
397+ case "capture" :
398+ cont = ac (calls [target ], func () (string , error ) {
399+ st := exec .Root ()
400+ pw := cg .mw .WithPrefix ("" , false )
401+
402+ s , err := cg .newSession (ctx )
403+ if err != nil {
404+ return "" , err
405+ }
406+
407+ g , ctx := errgroup .WithContext (ctx )
408+
409+ g .Go (func () error {
410+ return s .Run (ctx , cg .cln .Dialer ())
411+ })
412+
413+ var captureBuf strings.Builder
414+ g .Go (func () error {
415+ opts , err := cg .SolveOptions (ctx , st )
416+ if err != nil {
417+ return err
418+ }
419+ opts = append (opts , solver .WithOutputCapture (& captureBuf ))
420+ def , err := st .Marshal (ctx , llb .LinuxAmd64 )
421+ if err != nil {
422+ return err
423+ }
424+ return solver .Solve (ctx , cg .cln , s , pw , def , opts ... )
425+ })
426+ err = g .Wait ()
427+ return captureBuf .String (), err
428+ })
429+ }
385430 if ! cont {
386431 return exec .Root (), ErrAliasReached
387432 }
@@ -940,11 +985,13 @@ func (cg *CodeGen) EmitStringChainStmt(ctx context.Context, scope *parser.Scope,
940985 return nil , err
941986 }
942987 return func (_ string ) (string , error ) {
943- str , ok := v .(string )
944- if ! ok {
945- return str , errors .WithStack (ErrCodeGen {obj .Node , ErrBadCast })
988+ switch s := v .(type ) {
989+ case string :
990+ return s , nil
991+ case func () (string , error ):
992+ return s ()
946993 }
947- return str , nil
994+ return "" , errors . WithStack ( ErrCodeGen { obj . Node , ErrBadCast })
948995 }, nil
949996 }
950997}
0 commit comments