Skip to content

Commit

Permalink
Add support for %{bin-available:...} (#4995)
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremie Dimino <[email protected]>
  • Loading branch information
jeremiedimino authored Oct 13, 2021
1 parent 0bdb213 commit c12f803
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ Unreleased
- Add support for `(empty_module_interface_if_absent)` in executable and library
stanzas. (#4955, @nojb)

- Add support for `%{bin-available:...}` (#4995, @jeremiedimino)

2.9.1 (07/09/2021)
------------------

Expand Down
2 changes: 2 additions & 0 deletions doc/concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ In addition, ``(action ...)`` fields support the following special variables:
%{bin:program} ...)`` and ``(run program ...)`` behave in the same
way. ``%{bin:...}`` is only necessary when you are using ``(bash
...)`` or ``(system ...)``
- ``bin-available:<program>`` expands to ``true`` or ``false`` depending
on whether ``<program>`` is available or not.
- ``lib:<public-library-name>:<file>`` expands to the installation path of
the file ``<file>`` in the library ``<public-library-name>``. If
``<public-library-name>`` is available in the current workspace, the local
Expand Down
7 changes: 7 additions & 0 deletions src/dune_engine/pform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ module Macro = struct
; lib_private : bool
}
| Lib_available
| Bin_available
| Version
| Read
| Read_strings
Expand Down Expand Up @@ -165,6 +166,9 @@ module Macro = struct
| Lib_available, Lib_available -> Eq
| Lib_available, _ -> Lt
| _, Lib_available -> Gt
| Bin_available, Bin_available -> Eq
| Bin_available, _ -> Lt
| _, Bin_available -> Gt
| Version, Version -> Eq
| Version, _ -> Lt
| _, Version -> Gt
Expand Down Expand Up @@ -200,6 +204,7 @@ module Macro = struct
[ ("lib_exec", bool lib_exec); ("lib_private", bool lib_private) ]
]
| Lib_available -> string "Lib_available"
| Bin_available -> string "Bin_available"
| Version -> string "Version"
| Read -> string "Read"
| Read_strings -> string "Read_strings"
Expand Down Expand Up @@ -302,6 +307,7 @@ let encode_to_latest_dune_lang_version t =
| Lib { lib_exec = false; lib_private = true } -> Some "lib-private"
| Lib { lib_exec = true; lib_private = true } -> Some "libexec-private"
| Lib_available -> Some "lib-available"
| Bin_available -> Some "bin-available"
| Version -> Some "version"
| Read -> Some "read"
| Read_strings -> Some "read-strings"
Expand Down Expand Up @@ -388,6 +394,7 @@ module Env = struct
, since ~version:(2, 1)
(Macro.Lib { lib_exec = true; lib_private = true }) )
; ("lib-available", macro Lib_available)
; ("bin-available", since ~version:(3, 0) Macro.Bin_available)
; ("version", macro Version)
; ("read", macro Read)
; ("read-lines", macro Read_lines)
Expand Down
1 change: 1 addition & 0 deletions src/dune_engine/pform.mli
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ module Macro : sig
; lib_private : bool
}
| Lib_available
| Bin_available
| Version
| Read
| Read_strings
Expand Down
12 changes: 12 additions & 0 deletions src/dune_rules/artifacts.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ module Bin = struct
(let context = t.context.name in
Action.Prog.Not_found.create ~program:name ?hint ~context ~loc ()))

let binary_available t name =
if not (Filename.is_relative name) then
let p = Path.of_filename_relative_to_initial_cwd name in
Fs_memo.path_exists p
else
match String.Map.find t.local_bins name with
| Some _ -> Memo.Build.return true
| None -> (
t.context.which name >>| function
| Some _ -> true
| None -> false)

let add_binaries t ~dir l =
let local_bins =
List.fold_left l ~init:t.local_bins ~f:(fun acc fb ->
Expand Down
2 changes: 2 additions & 0 deletions src/dune_rules/artifacts.mli
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ module Bin : sig
-> string
-> Action.Prog.t Memo.Build.t

val binary_available : t -> string -> bool Memo.Build.t

val add_binaries : t -> dir:Path.Build.t -> File_binding.Expanded.t list -> t
end

Expand Down
7 changes: 7 additions & 0 deletions src/dune_rules/expander.ml
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,13 @@ let expand_pform_gen ~(context : Context.t) ~bindings ~dir ~source
let open Memo.Build.O in
let+ available = Lib.DB.available (Scope.libs t.scope) lib in
available |> string_of_bool |> string))
| Bin_available ->
Need_full_expander
(fun t ->
Without
(let open Memo.Build.O in
let+ b = Artifacts.Bin.binary_available t.bin_artifacts_host s in
b |> string_of_bool |> string))
| Read ->
let path = relative ~source dir s in
Direct
Expand Down
23 changes: 23 additions & 0 deletions test/blackbox-tests/test-cases/bin-available.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Test for %{bin-available:...}

$ cat >dune-project <<"EOF"
> (lang dune 3.0)
> (package (name foo))
> EOF
$ cat >dune<<"EOF"
> (rule
> (alias default)
> (action
> (progn
> (echo "dune: %{bin-available:dune}\n")
> (echo "local program foo: %{bin-available:foo}\n")
> (echo "non existant program: %{bin-available:*}\n"))))
>
> (executable (public_name foo))
> EOF
$ touch foo.ml

$ dune build
dune: true
local program foo: true
non existant program: false

0 comments on commit c12f803

Please sign in to comment.