Library
Module
Module type
Parameter
Class
Class type
The “legacy” Embedded Domain Specific Lanaguage.”
This is the 0.1.0 version of the EDSL. It is lower-level than EDSL
as it explicitly separates the types byte_array
and c_string
while the functions in the EDSL
module “hide” the conversions byte_array
→ c_string
in the API.
type 'a t = 'a Language.t
The type of a Genspio expression.
type byte_array = Language.byte_array
Type to encode arbitrary byte-arrays in the EDSL as byte_array t
values, OCaml literal strings or the outputs (as in stdout
) of processes are byte-arrays.
type c_string = Language.c_string
Type to encode NUL-terminated strings in the EDSL as c_string t
values. C-strings cannot contain the '\x00'
character. The command line arguments of commands as well as the contents of environment variables must be C-strings.
val byte_array : string -> byte_array t
Create a byte_array
literal.
val int : int -> int t
val bool : bool -> bool t
Add a “comment” string to an expression (will be displayed in error messages happening inside the expression).
"Some comment" %%% expr
is an alias for comment "Some comment" expr
.
Call a command from its list of “arguments” (including the first argument being the actual command).
val exec : string list -> unit t
Like call
but with string literals; i.e. exec ["a"; "b"]
is actually call [string "a"; string "b"]
which is the usual shell command "a b"
(with proper escaping).
Get the value of an environment variable as a string; it returns the empty string when the variable is not defined. If the argument is not a valid variable name, behavior is undefined.
Set the value of an environment variable as a string; it returns the empty string is the variable is not defined.
If the ~var
argument is not a valid variable name or if the value does not fit in a shell variable (e.g. newlines), behavior is undefined.
Also, the total environment of a UNIX process counts towards the total size of the arguments passed on to a sub-process (see usually the result of "getconf ARG_MAX"
). Genspio does not check for that limit which is not that high in some operating systems (e.g. about 200 KiB on the MacOSX Sierra that the Travis CI runs …). You might prefer putting or accumulating things in a tmp_file
.
Check whether a file exists, i.e. a shortcut for call [c_string "test"; c_string "-f"; path] |> succeeds
.
module Bool : sig ... end
Conversions of the bool t
type.
module Integer : sig ... end
Functions on int t
values (arithmetic, comparisons, conversions, etc.).
module Elist : sig ... end
Functions on 'a list t
values.
module Byte_array : sig ... end
module C_string : sig ... end
val nop : unit t
The silent “no-operation.”
loop_seq_while condition body
is a shortcut for loop_while condition ~body:(seq body)
.
if_seq c ~t ~e
is an alternate API for if_then_else
(when ?e
is provided) or if_then
(otherwise) that takes “then” and “else” bodies which are lists for the seq
construct.
Create a normal case for a switch
statement.
val to_fd : int t -> int t -> fd_redirection
Create a file-descriptor to file-descriptor redirection.
val to_file : int t -> c_string t -> fd_redirection
Create a file-descriptor to file redirection.
val with_redirections : unit t -> fd_redirection list -> unit t
Run a unit t
expression after applying a list of file-descriptor redirections.
The redirections are applied in the list's order (which means they can be more easily followed in reverse order), see the “Arbitrary Redirections” example.
Invalid cases, like redirecting to a file-descriptor has not been opened, lead to undefined behavior; see issue #41. If the shell is POSIX, the whole expression with_redirections expr redirs
exits and its return value is in [1, 125]
; if the shell is "bash"
or "zsh"
, the failing redirection is just ignored and expr
is executed with the remaining redirections if any.
val write_output :
?stdout:c_string t ->
?stderr:c_string t ->
?return_value:c_string t ->
unit t ->
unit t
Redirect selected streams or the return value to files (stdout
, stderr
, return_value
are paths).
write_stdout ~path expr
is write_output expr ~stdout:path
.
Pipe commands together ("stdout"
into "stdin"
exactly like the " | "
operator).
val get_stdout : unit t -> byte_array t
Get the contents of stdout
into a byte array (in previous versions this function was called output_as_string
).
val feed : string:byte_array t -> unit t -> unit t
Feed some content (~string
) into the "stdin"
filedescriptor of a unit t
expression.
val (>>) : byte_array t -> unit t -> unit t
str >> cmd
is feed ~string:str cmd
.
printf fmt l
is call (string "printf" :: string "--" :: fmt :: l)
.
val fail : string -> unit t
Expression that aborts the whole script/command immediately, it will try to output its argument to stderr
(but this may be silent depending on the redirections active at a given time).
type file =
< get : byte_array t
; get_c : c_string t
; set : byte_array t -> unit t
; set_c : c_string t -> unit t
; append : byte_array t -> unit t
; delete : unit t
; path : c_string t >
Abstraction of a file, cf. tmp_file
.
Create a temporary file that may contain arbitrary strings (can be used as variable containing string t
values).
tmp_file "foo"
points to a path that is a function of the string "foo"
; it does not try to make temporary-files unique, on the contrary: two calls to tmp_file "foo"
ensure that it is the same file.
module Command_line : sig ... end
Typed command-line parsing for your shell scripts, à la Printf.scanf
.
val loop_until_true :
?attempts:int ->
?sleep:int ->
?on_failed_attempt:(int t -> unit t) ->
bool t ->
bool t
loop_until_true eval_condition
tries to run eval_condition
in a loop until it succeeds. It makes ~attempts
attemps (default 20), and sleeps for sleep
seconds (default 2) after each failed attempt. The argument ~on_failed_attempt
can be used for instance to display something between each failed attempt and the call to sleep
, the default is
fun nth -> printf (string "%d.") [Integer.to_string nth]
.
silently expr
is expr
with stdout
and stderr
redirected to "/dev/null"
.
seq_and [a; b; c]
is like succeeds a &&& succeeds b &&& succeeds c
.
output_markdown_code "ocaml" (exec ["echo"; "let x = 42"])
runs its second argument within markdown-like code fences.
cat_markdown tag path
outputs the contents of the file at path
(with "cat"
) within a markdown code bloc.
val check_sequence :
?verbosity:[ `Announce of string | `Output_all | `Silent ] ->
?on_failure:
(step:(string * unit t) ->
stdout:c_string t ->
stderr:c_string t ->
unit t) ->
?on_success:
(step:(string * unit t) ->
stdout:c_string t ->
stderr:c_string t ->
unit t) ->
?tmpdir:string ->
(string * unit t) list ->
unit t
Run a sequence of expressions until the first that fails:
?verbosity
configures the output behavior,
`Announce prompt
uses prompt
to output the name-tag of the command, the output of the command is redirected to temporary files (accessible through the ~on_success
and ~on_failure
functions). The default value is `Announce ">> "
.`Output_all
lets all the output of the commands go through.`Silent
is like `Announce _
but without even the “prompt” command annoucement.?on_failure
configures what to do when encountering the first failure, the default is to display on stdout the name-tag of the failing command and outputting the contents of its stdout
and stderr
log-files (if any) and then call exec ["false"]
.?on_success
is a similar function as ?on_failure
, called before starting the next command, the default is to do nothing.?tmpdir
configures where to create the logging files.on_stdin_lines body
builds a loop that iterates over the lines of the stdin
file descriptor. The argument of `body` is the current line. Note that this is for text-like input, '\000'
characters in the input lead to undefined behavior.