Call is a handler which runs on every [syntax.CallExpr]. It is called once variable assignments and field expansion have occurred. The call's arguments are replaced by what the handler returns, and then the call is executed by the Runner as usual. This handler is similar to [Exec], but has two maj
(ctx context.Context, args []string)
| 92 | // This is used mainly to resolve conflicts. For example, "echo" is an |
| 93 | // interpreter builtin but can also be a Dagger function. |
| 94 | func (h *shellCallHandler) Call(ctx context.Context, args []string) ([]string, error) { |
| 95 | if args[0] == shellInternalCmd { |
| 96 | return args, fmt.Errorf("command %q is reserved for internal use", shellInternalCmd) |
| 97 | } |
| 98 | |
| 99 | // If command has an interpolated state token, make sure to resolve it. |
| 100 | // If it's a single token let it pass through so the handler just pipes it. |
| 101 | // Example: `.$FOO | .help` |
| 102 | if HasState(args[0]) && GetStateKey(args[0]) == "" { |
| 103 | r, err := h.resolveResult(ctx, args[0]) |
| 104 | if err != nil { |
| 105 | return args, err |
| 106 | } |
| 107 | if r != args[0] { |
| 108 | args[0] = r |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | // We may allow some interpreter builtins to be used as dagger shell |
| 113 | // builtins but rather than calling the interpreter builtin from the |
| 114 | // command's Run function it's simpler to use ShellCommand just for the |
| 115 | // documentation (.help) but strip the builtin prefix here ('.') when executing |
| 116 | // so the interpreter runs the builtin directly instead of our exec handler. |
| 117 | if after, ok := strings.CutPrefix(args[0], "."); ok && interp.IsBuiltin(after) { |
| 118 | if cmd, _ := h.BuiltinCommand(args[0]); cmd != nil && cmd.Run == nil { |
| 119 | args[0] = shellInterpBuiltinPrefix + after |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | // When there's a Dagger function with a name that conflicts |
| 124 | // with an interpreter builtin, the Dagger function is favored. |
| 125 | // To force the builtin to execute instead, prefix the command |
| 126 | // with "_". For example: "container | from $(_echo alpine)". |
| 127 | if after, found := strings.CutPrefix(args[0], shellInterpBuiltinPrefix); found && interp.IsBuiltin(after) { |
| 128 | // Make sure to resolve state in arguments since this is going |
| 129 | // to be handed off to the interpreter. |
| 130 | a, err := h.resolveResults(ctx, args[1:]) |
| 131 | args = append([]string{after}, a...) |
| 132 | return args, err |
| 133 | } |
| 134 | |
| 135 | // If the command is an interpreter builtin (no prefix), bypass the |
| 136 | // interpreter and run our exec handler instead to ensure module functions |
| 137 | // take precedence. |
| 138 | if interp.IsBuiltin(args[0]) { |
| 139 | return append([]string{shellInternalCmd}, args...), nil |
| 140 | } |
| 141 | |
| 142 | return args, nil |
| 143 | } |
| 144 | |
| 145 | // Exec is the main handler for executing simple commands. |
| 146 | // |
nothing calls this directly
no test coverage detected