diff --git a/doc/changes/11863.md b/doc/changes/11863.md new file mode 100644 index 00000000000..f130b98fa0d --- /dev/null +++ b/doc/changes/11863.md @@ -0,0 +1,4 @@ +- Introduce `%{os}`,`%{os_version}`, `%{os_distribution}`, and `%{os_family}` + percent forms. These have the same values as their opam counterparts. + (#11863, @rgrinberg) + diff --git a/src/dune_lang/pform.ml b/src/dune_lang/pform.ml index ba75d1d55c5..7a7ef002b04 100644 --- a/src/dune_lang/pform.ml +++ b/src/dune_lang/pform.ml @@ -2,6 +2,25 @@ open Import module Payload = Template.Pform.Payload module Var = struct + module Os = struct + type t = + | Os + | Os_version + | Os_distribution + | Os_family + + let all = [ Os; Os_version; Os_distribution; Os_family ] + + let to_string = function + | Os -> "os" + | Os_version -> "os_version" + | Os_distribution -> "os_distribution" + | Os_family -> "os_family" + ;; + + let to_dyn t = Dyn.variant (to_string t) [] + end + module Pkg = struct module Section = struct type t = @@ -42,10 +61,7 @@ module Var = struct type t = | Switch - | Os - | Os_version - | Os_distribution - | Os_family + | Os of Os.t | Build | Prefix | User @@ -58,11 +74,8 @@ module Var = struct let compare = Poly.compare let encode_to_latest_dune_lang_version = function + | Os s -> Os.to_string s | Switch -> "switch" - | Os -> "os" - | Os_version -> "os_version" - | Os_distribution -> "os_distribution" - | Os_family -> "os_family" | Build -> "build" | Prefix -> "prefix" | User -> "user" @@ -107,6 +120,7 @@ module Var = struct | Profile | Context_name | Os_type + | Os of Os.t | Architecture | Arch_sixtyfour | System @@ -174,6 +188,7 @@ module Var = struct | Corrected_suffix -> variant "Corrected_suffix" [] | Inline_tests -> variant "Inline_tests" [] | Toolchain -> variant "Toolchain" [] + | Os os -> Os.to_dyn os | Pkg pkg -> Pkg.to_dyn pkg) ;; @@ -184,10 +199,10 @@ module Var = struct (match name with | "make" -> Some Make | "switch" -> Some (Pkg Switch) - | "os" -> Some (Pkg Os) - | "os-version" -> Some (Pkg Os_version) - | "os-distribution" -> Some (Pkg Os_distribution) - | "os-family" -> Some (Pkg Os_family) + | "os" -> Some (Pkg (Os Os)) + | "os-version" -> Some (Pkg (Os Os_version)) + | "os-distribution" -> Some (Pkg (Os Os_distribution)) + | "os-family" -> Some (Pkg (Os Os_family)) | "build" -> Some (Pkg Build) | "prefix" -> Some (Pkg Prefix) | "user" -> Some (Pkg User) @@ -484,6 +499,7 @@ let encode_to_latest_dune_lang_version t = | Corrected_suffix -> Some "corrected-suffix" | Inline_tests -> Some "inline_tests" | Toolchain -> Some "toolchain" + | Os os -> Some (Var.Os.to_string os) | Pkg pkg -> Some (Var.Pkg.encode_to_latest_dune_lang_version pkg) with | None -> Pform_was_deleted @@ -554,10 +570,10 @@ module Env = struct let vars = let pkg = [ "switch", Var.Pkg.Switch - ; "os", Os - ; "os_version", Os_version - ; "os_distribution", Os_distribution - ; "os_family", Os_family + ; "os", Os Os + ; "os_version", Os Os_version + ; "os_distribution", Os Os_distribution + ; "os_family", Os Os_family ; "build", Build ; "prefix", Prefix ; "user", User @@ -685,7 +701,11 @@ module Env = struct ; "toolchains", since ~version:(3, 0) Var.Toolchain ] in - String.Map.of_list_exn (List.concat [ lowercased; uppercased; other ]) + let os = + List.map Var.Os.all ~f:(fun v -> + Var.Os.to_string v, since ~version:(3, 20) (Var.Os v)) + in + String.Map.of_list_exn (List.concat [ lowercased; uppercased; other; os ]) in fun syntax_version -> { syntax_version; vars; macros } ;; diff --git a/src/dune_lang/pform.mli b/src/dune_lang/pform.mli index b9df09e3ecd..c4d680b11e9 100644 --- a/src/dune_lang/pform.mli +++ b/src/dune_lang/pform.mli @@ -2,6 +2,14 @@ open Import module Payload = Template.Pform.Payload module Var : sig + module Os : sig + type t = + | Os + | Os_version + | Os_distribution + | Os_family + end + module Pkg : sig module Section : sig type t = @@ -21,10 +29,7 @@ module Var : sig type t = | Switch - | Os - | Os_version - | Os_distribution - | Os_family + | Os of Os.t | Build | Prefix | User @@ -69,6 +74,7 @@ module Var : sig | Profile | Context_name | Os_type + | Os of Os.t | Architecture | Arch_sixtyfour | System diff --git a/src/dune_rules/expander.ml b/src/dune_rules/expander.ml index c7b44ae8805..f777feabdeb 100644 --- a/src/dune_rules/expander.ml +++ b/src/dune_rules/expander.ml @@ -516,6 +516,10 @@ let expand_pform_var (context : Context.t) ~dir ~source (var : Pform.Var.t) = (let+ ocaml = ocaml in lib_config_var var ocaml.lib_config) |> static + | Os v -> + static + (let+ v = Lock_dir.Sys_vars.(os poll v) in + [ Value.String (Option.value v ~default:"") ]) | Ext_exe | Cpp | Pa_cpp diff --git a/src/dune_rules/lock_dir.ml b/src/dune_rules/lock_dir.ml index 59371068e95..d0866ce32cd 100644 --- a/src/dune_rules/lock_dir.ml +++ b/src/dune_rules/lock_dir.ml @@ -13,6 +13,15 @@ module Sys_vars = struct ; sys_ocaml_version : string option Memo.Lazy.t } + let os t (v : Dune_lang.Pform.Var.Os.t) = + Memo.Lazy.force + (match v with + | Os -> t.os + | Os_version -> t.os_version + | Os_distribution -> t.os_distribution + | Os_family -> t.os_family) + ;; + let poll = let vars = lazy diff --git a/src/dune_rules/lock_dir.mli b/src/dune_rules/lock_dir.mli index 285dd5d2b44..a9d94957895 100644 --- a/src/dune_rules/lock_dir.mli +++ b/src/dune_rules/lock_dir.mli @@ -20,6 +20,7 @@ module Sys_vars : sig ; sys_ocaml_version : string option Memo.Lazy.t } + val os : t -> Dune_lang.Pform.Var.Os.t -> string option Memo.t val poll : t val solver_env : unit -> Dune_pkg.Solver_env.t Memo.t end diff --git a/src/dune_rules/pkg_rules.ml b/src/dune_rules/pkg_rules.ml index df68213470a..90bc4bde9c6 100644 --- a/src/dune_rules/pkg_rules.ml +++ b/src/dune_rules/pkg_rules.ml @@ -3,7 +3,6 @@ open Memo.O include struct open Dune_pkg - module Sys_poll = Sys_poll module Package_variable = Package_variable module Substs = Substs module Checksum = Checksum @@ -642,10 +641,10 @@ module Action_expander = struct let expand_pkg (paths : Path.t Paths.t) (pform : Pform.Var.Pkg.t) = match pform with | Switch -> Memo.return [ Value.String "dune" ] - | Os -> sys_poll_var (fun { os; _ } -> os) - | Os_version -> sys_poll_var (fun { os_version; _ } -> os_version) - | Os_distribution -> sys_poll_var (fun { os_distribution; _ } -> os_distribution) - | Os_family -> sys_poll_var (fun { os_family; _ } -> os_family) + | Os Os -> sys_poll_var (fun { os; _ } -> os) + | Os Os_version -> sys_poll_var (fun { os_version; _ } -> os_version) + | Os Os_distribution -> sys_poll_var (fun { os_distribution; _ } -> os_distribution) + | Os Os_family -> sys_poll_var (fun { os_family; _ } -> os_family) | Sys_ocaml_version -> sys_poll_var (fun { sys_ocaml_version; _ } -> sys_ocaml_version) | Build -> Memo.return [ Value.Dir paths.source_dir ] diff --git a/test/blackbox-tests/test-cases/os-variables.t b/test/blackbox-tests/test-cases/os-variables.t new file mode 100644 index 00000000000..f5d83c92fc7 --- /dev/null +++ b/test/blackbox-tests/test-cases/os-variables.t @@ -0,0 +1,16 @@ +Demonstrate the following variables: %{os}, %{os_version}, %{os_distribution}, %{os_family} + + $ cat >dune-project < (lang dune 3.20) + > EOF + + $ cat >dune < (rule (write-file out "%{os}\n%{os_version}\n%{os_distribution}\n%{os_family}\n")) + > EOF + + $ dune build out + +The values are not going to be portable, so we just count how many we get: + + $ grep -c '.' _build/default/out + 4