mte/unikernel/duniverse/mirage/lib/functoria/action.mli
2025-11-11 02:07:51 +01:00

182 lines
6 KiB
OCaml

(*
* Copyright (c) 2013-2020 Thomas Gazagnaire <thomas@gazagnaire.org>
* Copyright (c) 2013-2020 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2015-2020 Gabriel Radanne <drupyog@zoho.com>
* Copyright (c) 2019-2020 Etienne Millon <etienne@tarides.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
(** Wrapper around [Bos] which provides a "dry run" feature. *)
(** {1 The action type} *)
type 'a t
(** An action that when executed may return a value of type ['a]. *)
val ok : 'a -> 'a t
(** An action that returns a value. *)
val error : string -> 'a t
(** [error e] is the failed action with error message [e]. *)
val errorf : ('a, Format.formatter, unit, 'b t) format4 -> 'a
(** [errorf fmt] is the failed action with error message [fmt]. *)
val map : f:('a -> 'b) -> 'a t -> 'b t
(** Functor instance. *)
val bind : f:('a -> 'b t) -> 'a t -> 'b t
(** Monad instance. *)
val seq : unit t list -> unit t
(** [seq t] runs the elements of [t] in sequence. *)
module List : sig
val iter : f:('a -> unit t) -> 'a list -> unit t
val map : f:('a -> 'b t) -> 'a list -> 'b list t
end
module Infix : sig
val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t
val ( >|= ) : 'a t -> ('a -> 'b) -> 'b t
end
module Syntax : sig
val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t
val ( let+ ) : 'a t -> ('a -> 'b) -> 'b t
end
(** {1 Actions} *)
val rm : Fpath.t -> unit t
(** Delete a file. (see [Bos.OS.File.delete]) *)
val mkdir : Fpath.t -> bool t
(** Create a directory. (See [Bos.OS.Dir.create] *)
val rmdir : Fpath.t -> unit t
(** Remove a directory. (see [Bos.OS.Dir.delete]) *)
val with_dir : Fpath.t -> (unit -> 'a t) -> 'a t
(** [with_dir d f] runs [f] with [d] as current working directory. (See
[Bos.OS.Dir.with_current]). *)
val pwd : unit -> Fpath.t t
(** [pwd ()] is the current working directory. (See [Bos.OS.Dir.current]) *)
val is_file : Fpath.t -> bool t
(** Does a file exist? (see [Bos.OS.File.exists]) *)
val is_dir : Fpath.t -> bool t
(** Does a directory exist? (see [Bos.OS.Dir.exists]) *)
val size_of : Fpath.t -> int option t
(** [size_of f] is [Some i] if [f] exists and is of size [i], and [None] if [f]
doesn't exist. *)
val set_var : string -> string option -> unit t
(** [set_var v c] sets env variable [c] to [c]. (see [Bos.OS.Env.set_var]) *)
val get_var : string -> string option t
(** [get_var v] gets the value of the variable [c] in the environment. (see
[Bos.OS.Env.get]) *)
type channel = [ `Null | `Fmt of Format.formatter ]
(** The type for channels. *)
val run_cmd : ?err:channel -> ?out:channel -> Bos.Cmd.t -> unit t
(** Run a command. By default, [err] is [Fmt.stderr] and [out] is [Fmt.stdout].
(see [Bos.OS.Cmd.run]) *)
val run_cmd_out : ?err:channel -> Bos.Cmd.t -> string t
(** Run a command and return its trimmed stdout. By default [err] is
[Fmt.stderr]. (See [Bos.OS.Cmd.run_out]) *)
val run_cmd_cli : Bos.Cmd.t -> unit t
(** Run a command as a command line interface, meaning stdout and stderr remain
untouched. *)
val write_file : Fpath.t -> string -> unit t
(** Write some data to a file. (see [Bos.OS.File.write]) *)
val read_file : Fpath.t -> string t
(** [read_file f] is [f]'s contents. (see [Bos.OS.File.read]) *)
val tmp_file : ?mode:int -> Bos.OS.File.tmp_name_pat -> Fpath.t t
(** [tmp_file pat] is a tempory file built using the pattern [pat]. (See
[Bos.OS.File.tmp]) *)
val ls : Fpath.t -> (Fpath.t -> bool) -> Fpath.t list t
(** [ls dir] is the list of files in [dir]. *)
val with_output :
?mode:int ->
?append:bool ->
path:Fpath.t ->
purpose:string ->
(Format.formatter -> 'a) ->
'a t
(** Open a file with a given mode, and write some data to it through a function.
(see [Bos.OS.File.with_oc]). [purpose] is used in error messages. If
[append] is set (by default it is not), the data is appended to [path]. *)
(** {1 Interpreters} *)
val run : 'a t -> ('a, Rresult.R.msg) result
(** Run the command through [Bos]. *)
type env
(** The type for virtual environments. *)
type files = [ `Passtrough of Fpath.t | `Files of (Fpath.t * string) list ]
val default_exec : Bos.Cmd.t -> (string * string) option
(** [default_exec cmd] is [Some ("$(<cmd>)", "")]. *)
val env :
?exec:(Bos.Cmd.t -> (string * string) option) ->
?env:(string * string) list ->
?pwd:Fpath.t ->
?files:files ->
unit ->
env
type 'a domain = {
result : ('a, Rresult.R.msg) result;
env : env;
logs : string list;
}
(** The type for interpreted values. *)
val eq_domain : ('a -> 'a -> bool) -> 'a domain -> 'a domain -> bool
(** [eq_domain] is the equality function between {!domain}s. *)
val pp_domain : 'a Fmt.t -> 'a domain Fmt.t
(** [pp_domain] is the pretty-printer for {!domain}s. *)
val dry_run : ?env:env -> 'a t -> 'a domain
(** Emulate the action. This will not do IO on the actual files. Some
approximation is done to determine the result of actions. [files] is a list
of paths that are supposed to exist at the beginning. Returns:
- the result of the action (which can be an [Bos] error)
- the list of files after execution
- a trace (list of log messages) *)
val dry_run_trace : ?env:env -> 'a t -> unit
(** Only output the trace part of [dry_run]. *)
val generated_files : ?env:env -> 'a t -> Fpath.Set.t
(** [generated_files t] is the set of files created by [t]. Note: this might be
incomplete/incorrect in case of calls to external commands. *)