|
19 | 19 | "Start a shell process, returning the process object for deref/management. |
20 | 20 |
|
21 | 21 | Options: |
22 | | - - :cwd Working directory (required) |
23 | | - - :script Inline script string (mutually exclusive with :file) |
24 | | - - :file Script file path (mutually exclusive with :script) |
25 | | - - :input String to pass as stdin (optional) |
| 22 | + - :cwd Working directory (required) |
| 23 | + - :script Inline script string (mutually exclusive with :file) |
| 24 | + - :file Script file path (mutually exclusive with :script) |
| 25 | + - :input String to pass as stdin (optional) |
| 26 | + - :shell-path Custom shell executable path (optional, overrides platform default) |
| 27 | + - :shell-args Custom shell args placed before the script/file arg (optional) |
26 | 28 |
|
27 | 29 | Returns: babashka.process process object (deref-able)" |
28 | | - [{:keys [cwd script file input]}] |
| 30 | + [{:keys [cwd script file input shell-path shell-args]}] |
29 | 31 | {:pre [(some? cwd) |
30 | 32 | (or (some? script) (some? file)) |
31 | 33 | (not (and script file))]} |
32 | | - (let [win? (string/starts-with? (System/getProperty "os.name") "Windows") |
33 | | - cmd (cond |
34 | | - (and win? file) |
35 | | - ["powershell.exe" "-ExecutionPolicy" "Bypass" "-File" file] |
| 34 | + (let [cmd (if shell-path |
| 35 | + (into (vec (cons shell-path shell-args)) [(or script file)]) |
| 36 | + (let [win? (string/starts-with? (System/getProperty "os.name") "Windows")] |
| 37 | + (cond |
| 38 | + (and win? file) |
| 39 | + ["powershell.exe" "-ExecutionPolicy" "Bypass" "-File" file] |
36 | 40 |
|
37 | | - (and win? script) |
38 | | - ["powershell.exe" "-NoProfile" "-Command" script] |
| 41 | + (and win? script) |
| 42 | + ["powershell.exe" "-NoProfile" "-Command" script] |
39 | 43 |
|
40 | | - file |
41 | | - ["bash" file] |
| 44 | + file |
| 45 | + ["bash" file] |
42 | 46 |
|
43 | | - :else |
44 | | - ["bash" "-c" script])] |
| 47 | + :else |
| 48 | + ["bash" "-c" script])))] |
45 | 49 | (p/process (cond-> {:cmd cmd |
46 | 50 | :dir cwd |
47 | 51 | :out :string |
48 | 52 | :err :string |
49 | 53 | :continue true} |
50 | 54 | input (assoc :in input))))) |
51 | 55 |
|
52 | | -(defn ^:private shell-command [arguments {:keys [db tool-call-id call-state-fn state-transition-fn]}] |
| 56 | +(defn ^:private shell-command [arguments {:keys [db config tool-call-id call-state-fn state-transition-fn]}] |
53 | 57 | (let [command-args (get arguments "command") |
54 | 58 | user-work-dir (get arguments "working_directory") |
55 | | - timeout (min (or (get arguments "timeout") default-timeout) max-timeout)] |
| 59 | + timeout (min (or (get arguments "timeout") default-timeout) max-timeout) |
| 60 | + shell-config (get-in config [:toolCall :shellCommand]) |
| 61 | + shell-path (get shell-config :path) |
| 62 | + shell-args (get shell-config :args)] |
56 | 63 | (or (tools.util/invalid-arguments arguments [["working_directory" #(or (nil? %) |
57 | 64 | (fs/exists? %)) "working directory $working_directory does not exist"]]) |
58 | 65 | (let [work-dir (or (some-> user-work-dir fs/canonicalize str) |
|
64 | 71 | _ (logger/debug logger-tag "Running command:" command-args) |
65 | 72 | result (try |
66 | 73 | (if-let [proc (when-not (= :stopping (:status (call-state-fn))) |
67 | | - (start-shell-process! {:cwd work-dir |
68 | | - :script command-args}))] |
| 74 | + (start-shell-process! (cond-> {:cwd work-dir |
| 75 | + :script command-args} |
| 76 | + shell-path (assoc :shell-path shell-path) |
| 77 | + shell-args (assoc :shell-args shell-args))))] |
69 | 78 | (do |
70 | 79 | (state-transition-fn :resources-created {:resources {:process proc}}) |
71 | 80 | (try (deref proc |
|
0 commit comments