package jenga

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

The jenga monad. It has two pieces to it:

  • an implicit accumulator of dependencies, that Dep.path and all the functions that return a unit t add to. The final value of this accumulator is the dependencies of the action in Rule.create and Dep.action, and what gets built in the case of Rule.alias
  • a monad and other usual combinators, which allows to write computation that ask jenga to build something and wait for the result (and to rebuild if that input changes). Because of this, functions should not be side-effecting.

To make clear the distinction between the two, take:

val path : Path.t -> unit t val contents : Path.t -> string t

path simply says that the surrounding Rule.create (for instance) will read the contents of that file. contents allows to create different action depending on the contents of the file.

It's highly recommended to use parallel combinators like both and all in preference to bind. Using bind is inherently sequential, whereas usually work in a build system can be done in parallel.

type 'a t
val sexp_of_t : ('a -> Ppx_sexp_conv_lib.Sexp.t) -> 'a t -> Ppx_sexp_conv_lib.Sexp.t
val return : 'a -> 'a t
val bind : 'a t -> f:('a -> 'b t) -> 'b t
val map : 'a t -> ('a -> 'b) -> 'b t
val both : 'a t -> 'b t -> ('a * 'b) t
val all : 'a t list -> 'a list t
val all_unit : unit t list -> unit t
val cutoff : equal:('a -> 'a -> bool) -> 'a t -> 'a t
val deferred : (unit -> 'a Async.Deferred.t) -> 'a t
val memoize : name:string -> 'a t -> 'a t

let v = memoize ~name t behaves like t, except with caching: using v in several computations will not result in duplicate evaluations of t. name is used in displayed in errors, or in the case of dependency cycles.

val action : Action.t t -> unit t
val action_stdout : Action.t t -> string t
val alias : Alias.t -> unit t
val path : Path.t -> unit t
val getenv : 'a Var.t -> 'a t

getenv v provides access to a registered environment variable, responding to changes notified to jenga via the setenv RPC/command-line.

val group_dependencies : 'a t -> 'a t

group_dependencies t is equivalent to t, however jenga will be careful to avoid duplicating the set of dependencies that have been declared. This is best used under an alias, as the alias will allow to share the computation as well.

val source_if_it_exists : Path.t -> unit t

source_if_it_exists Dont treat path as a goal (i.e. don't force it to be built) Just depend on its contents, if it exists. It's ok if it doesn't exist.

val contents : Path.t -> string t
val contents_cutoff : Path.t -> string t
val glob_listing : Glob.t -> Path.t list t

The semantics of glob_listing and glob_change includes files which exist on the file-system AND files which are buildable by some jenga rule. Therefore it is an error (dependency cycle) to glob a directory while generating the scheme for that same directory. Use Scheme.glob instead.

val glob_change : Glob.t -> unit t
val fs_glob_listing : Glob.t -> Path.t list t

Versions with old semantics: only includes files on the file-system.

val fs_glob_change : Glob.t -> unit t
val subdirs : dir:Path.t -> Path.t list t

file_exists makes the information about file existence available to the rules, but does not declare it as an action dependency.

val file_exists : Path.t -> bool t

file_exists makes the information about file existence available to the rules, but does not declare it as an action dependency.

file_existence declares an action dependency on file existence

val file_existence : Path.t -> unit t

file_existence declares an action dependency on file existence

module List : sig ... end
val buildable_targets : dir:Path.t -> Path.t list t
val source_files : dir:Path.t -> Path.t list t

source_files ~dir is files_on_filesystem ~dir \ buildable_targets ~dir