Skip to content

command

caumond edited this page Jan 10, 2025 · 4 revisions

Command

Execute external commands.

See the API for details.

Describe a command

To execute a command, first build a vector of strings (e.g. `[“ls” “-la”]`)

There are many flavors to execute this command, the generic one made of `create-process`, `wait-for`, … and the helpers to simplify some typical use cases.

All functions deal with a **process**, a map describing the command execution and then enriched as the process is going on.

High level API

The sections below describe the process, a common data for all the use cases, and the easy to use functions setting up the low level API for most common use cases. All of that functions are blocking, except if their name ends with `-non-blocking`.

Process

A process is the object built for the execution of the command, it is a map with following keys:

  • `:cmd` the command, e.g. ["ls" "-la"]
  • `:cmd` the command ready to execute, as a long string
  • `:dir` the directory as provided by the user, e.g. ""
  • `:status` is a value among `:wip`, `:didnt-start`, `:success`, `:failure`. Its status will depend on the success of the command, and kind of execution.
  • `:adir` the expanded directory, e.g. "/User/johndoe/hephaistox" so you know the context where it executes
  • `:out-stream` output stream, for internal use only except specific use cases
  • `:err-stream` error stream, for internal use only except specific use cases
  • `:bb-proc` the babashka process, normally for internal use only

For example,

(require '[automaton-build.os.cmd :as build-cmd])
(-> ["echo" "hello"]
    (build-cmd/muted ""))
{:cmd ["echo" "hello"], :cmd-str "echo hello ", :dir "", :status :success, :adir "/Users/...", :bb-proc {...}, :out-stream ["hello"], :err-stream []}

muted-process

Use `muted-process` when you’d like to execute a command and stay muted and get back the process.

(require '[automaton-build.os.cmd :as build-cmd])
(-> ["echo" "2"]
    (build-cmd/muted ""))
{:cmd ["echo" "2"], :cmd-str "echo 2", :dir "", :status :success, :adir "/Users/....", :bb-proc {...} :out-stream [], :err-stream []}

Note the output stream are empty and will stay. Nothing will appear on the terminal even in case of errors. If you need anotherTODO

muted-non-blocking

`muted-non-blocking` executes a command and returns only a process.

(require '[automaton-build.os.cmd :as build-cmd])
(-> ["sleep" "2"]
    (build-cmd/muted-non-blocking ""))
{:cmd ["sleep" "2"], :cmd-str "sleep 2", :dir "", :status :wip, :adir "/Users/...", :bb-proc {...}, :out-stream #object[...], :err-stream #object[...]}

You need to deal with the low level API to interact with this object.

as-string

Use `as-string` when you’d like to get the feedback of the command as strings in `:out-stream` and `:err-stream`.

(require '[automaton-build.os.cmd :as build-cmd])
(-> ["echo" "hello"]
    (build-cmd/as-string ""))

printing

For a command execution that should be printed, and which is blocking, you can use `printing`:

(require '[automaton-build.os.cmd :as build-cmd])

(defn printer
  [prefix]
  (fn [line] (println (str prefix "-" line))))

(-> ["ls" "hello"]
    (build-cmd/printing "" (printer "out") (printer "err") #(println "end of command") 10))
{:cmd ["ls" "hello"], :cmd-str "ls hello", :dir "", :status :failure, :adir "/Users/...", :bb-proc {}, :out-stream [], :err-stream []}

And this is printing on the terminal, with err prefix:

err-ls: hello: No such file or directory
end of command

printing-non-blocking

To be used for long living operations, that should print their streams:

(require '[automaton-build.os.cmd :as build-cmd])

(defn printer
  [prefix]
  (fn [line] (println (str prefix "-" line))))

(-> ["ls" "hello"]
    (build-cmd/printing-non-blocking "" (printer "out") (printer "err") #(println "end of command") 10))
{:cmd ["ls" "hello"], :cmd-str "ls hello", :dir "", :status :wip, :adir "/Users/...", :bb-proc {...} , :out-stream ..., :err-stream ...}

What is specific to this function is the printing of that data on the terminal that is happening. Note there are three functions to print, one for each stream `:err` and `:out`, the last one for the end of the execution of the command.

print-on-error

This version is normally quiet, except if you an error occur. The signature is close from printing but arguments `max-out-lines` and `max-err-lines` are telling how many lines are stored.

Indeed the output may be big before the command is failing.

(require '[automaton-build.os.cmd :as build-cmd])

(defn printer
  [prefix]
  (fn [line] (println (str prefix "-" line))))

(-> ["ls" "hello"]
    (build-cmd/print-on-error "" (printer "out") (printer "err") 10 100 100))
{:cmd ["ls" "hello"], :cmd-str "ls hello", :dir "", :status :failure, :adir "/Users/...", :bb-proc {...}, :out-stream [], :err-stream ["ls: hello: No such file or directory"]}

Low level API

See the API for details of each function.