Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Env stanza in workspace files part #2 #1038

Merged
merged 8 commits into from
Jul 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ next
passing in `--root` in conjunction with `--workspace` or `--config` would not
work correctly (#997, @rgrinberg)

- Add support for customizing env nodes in workspace files. The `env` stanza is
now allowed in toplevel position in the workspace file, or for individual
contexts. This feature requires `(dune lang 1.1)` (#1038, @rgrinberg)

1.0.1 (19/07/2018)
------------------

Expand Down
11 changes: 11 additions & 0 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,13 @@ The build profile can be selected in the ``dune-workspace`` file by write a

Note that the command line option ``--profile`` has precedence over this stanza.

env
~~~

The ``env`` stanza can be used to set the base environment for all contexts in
this workspace. This environment has the lowest precedence of all other ``env``
stanzas. The syntax for this stanza is the same dune's :ref:`dune-env` stanza.

context
~~~~~~~

Expand Down Expand Up @@ -407,6 +414,10 @@ context or can be the description of an opam switch, as follows:
context. This has precedence over the command line option
``--profile``

- ``(env <env>)`` to set the environment for a particular context. This is of
higher precedence than the toplevel ``env`` stanza in the workspace file. This
field the same options as the :ref:`dune-env` stanza.

Both ``(default ...)`` and ``(opam ...)`` accept a ``targets`` field in order to
setup cross compilation. See :ref:`advanced-cross-compilation` for more
information.
Expand Down
34 changes: 24 additions & 10 deletions src/context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ module Kind = struct
])
end

module Env_nodes = struct
type t =
{ context: Dune_env.Stanza.t option
; workspace: Dune_env.Stanza.t option
}
end

type t =
{ name : string
; kind : Kind.t
Expand All @@ -26,7 +33,7 @@ type t =
; for_host : t option
; implicit : bool
; build_dir : Path.t
; env_node : Dune_env.Stanza.t option
; env_nodes : Env_nodes.t
; path : Path.t list
; toplevel_path : Path.t option
; ocaml_bin : Path.t
Expand Down Expand Up @@ -131,7 +138,7 @@ let ocamlpath_sep =
else
Bin.path_sep

let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets
let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
~profile () =
let opam_var_cache = Hashtbl.create 128 in
(match kind with
Expand Down Expand Up @@ -334,7 +341,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets
; kind
; profile
; merlin
; env_node
; env_nodes
; for_host = host
; build_dir
; path
Expand Down Expand Up @@ -410,11 +417,11 @@ let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets

let opam_config_var t var = opam_config_var ~env:t.env ~cache:t.opam_var_cache var

let default ?(merlin=true) ~env_node ~env ~targets () =
create ~kind:Default ~path:Bin.path ~env ~env_node ~name:"default"
let default ?(merlin=true) ~env_nodes ~env ~targets () =
create ~kind:Default ~path:Bin.path ~env ~env_nodes ~name:"default"
~merlin ~targets ()

let create_for_opam ?root ~env ~env_node ~targets ~profile ~switch ~name
let create_for_opam ?root ~env ~env_nodes ~targets ~profile ~switch ~name
?(merlin=false) () =
match Bin.opam with
| None -> Utils.program_not_found "opam"
Expand Down Expand Up @@ -452,16 +459,23 @@ let create_for_opam ?root ~env ~env_node ~targets ~profile ~switch ~name
| Some s -> Bin.parse_path s
in
let env = Env.extend env ~vars in
create ~kind:(Opam { root; switch }) ~profile ~targets ~path ~env ~env_node
create ~kind:(Opam { root; switch }) ~profile ~targets ~path ~env ~env_nodes
~name ~merlin ()

let create ?merlin ~env def =
let create ?merlin ?workspace_env ~env def =
let env_nodes context =
{ Env_nodes.
context
; workspace = workspace_env
}
in
match (def : Workspace.Context.t) with
| Default { targets; profile; env = env_node ; loc = _ } ->
default ~env ~env_node ~profile ~targets ?merlin ()
default ~env ~env_nodes:(env_nodes env_node) ~profile ~targets ?merlin ()
| Opam { base = { targets ; profile ; env = env_node ; loc = _ }
; name; switch; root; merlin = _ } ->
create_for_opam ?root ~env_node ~env ~profile ~switch ~name ?merlin ~targets ()
create_for_opam ?root ~env_nodes:(env_nodes env_node) ~env ~profile
~switch ~name ?merlin ~targets ()

let which t s = which ~cache:t.which_cache ~path:t.path s

Expand Down
10 changes: 9 additions & 1 deletion src/context.mli
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ module Kind : sig
type t = Default | Opam of Opam.t
end

module Env_nodes : sig
type t =
{ context: Dune_env.Stanza.t option
; workspace: Dune_env.Stanza.t option
}
end

type t =
{ name : string
; kind : Kind.t
Expand All @@ -51,7 +58,7 @@ type t =
build_dir : Path.t

; (** env node that this context was initialized with *)
env_node : Dune_env.Stanza.t option
env_nodes : Env_nodes.t

; (** [PATH] *)
path : Path.t list
Expand Down Expand Up @@ -125,6 +132,7 @@ val compare : t -> t -> Ordering.t

val create
: ?merlin:bool
-> ?workspace_env:Dune_env.Stanza.t
-> env:Env.t
-> Workspace.Context.t
-> t list Fiber.t
Expand Down
3 changes: 2 additions & 1 deletion src/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ let setup ?(log=Log.no_log)

Fiber.parallel_map workspace.contexts ~f:(fun ctx_def ->
let name = Workspace.Context.name ctx_def in
Context.create ctx_def ~env ~merlin:(workspace.merlin_context = Some name))
Context.create ?workspace_env:workspace.env
ctx_def ~env ~merlin:(workspace.merlin_context = Some name))
>>= fun contexts ->
let contexts = List.concat contexts in
List.iter contexts ~f:(fun (ctx : Context.t) ->
Expand Down
28 changes: 17 additions & 11 deletions src/super_context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -612,18 +612,24 @@ let create
}
in
let context_env_node = lazy (
let config =
match context.env_node with
| Some s -> s
| None -> { loc = Loc.none; rules = [] }
let make ~inherit_from ~config =
{ Env_node.
dir = context.build_dir
; scope = Scope.DB.find_by_dir scopes context.build_dir
; ocaml_flags = None
; inherit_from
; config
}
in
{ Env_node.
dir = context.build_dir
; inherit_from = None
; scope = Scope.DB.find_by_dir scopes context.build_dir
; config
; ocaml_flags = None
}
match context.env_nodes with
| { context = None; workspace = None } ->
make ~config:{ loc = Loc.none; rules = [] } ~inherit_from:None
| { context = Some config; workspace = None }
| { context = None; workspace = Some config } ->
make ~config ~inherit_from:None
| { context = Some context ; workspace = Some workspace } ->
make ~config:context
~inherit_from:(Some (lazy (make ~inherit_from:None ~config:workspace)))
) in
List.iter stanzas
~f:(fun { Dir_with_jbuild. ctx_dir; scope; stanzas; _ } ->
Expand Down
16 changes: 13 additions & 3 deletions src/workspace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ open Stanza.Of_sexp
for simplicity *)
let syntax = Stanza.syntax

let env_field =
field_o "env"
(Syntax.since syntax (1, 1) >>= fun () ->
Dune_env.Stanza.t)

module Context = struct
module Target = struct
type t =
Expand Down Expand Up @@ -49,7 +54,7 @@ module Context = struct
}

let t ~profile =
field_o "env" Dune_env.Stanza.t >>= fun env ->
env_field >>= fun env ->
field "targets" (list Target.t) ~default:[Target.Native]
>>= fun targets ->
field "profile" string ~default:profile
Expand Down Expand Up @@ -148,22 +153,25 @@ end
type t =
{ merlin_context : string option
; contexts : Context.t list
; env : Dune_env.Stanza.t option
}

include Versioned_file.Make(struct type t = unit end)
let () = Lang.register syntax ()

let t ?x ?profile:cmdline_profile () =
env_field >>= fun env ->
field "profile" string ~default:Config.default_build_profile
>>= fun profile ->
let profile = Option.value cmdline_profile ~default:profile in
multi_field "context" (Context.t ~profile ~x)
>>= fun contexts ->
let defined_names = ref String.Set.empty in
let { merlin_context; contexts } =
let { merlin_context; contexts; env } =
let init =
{ merlin_context = None
; contexts = []
; env
}
in
List.fold_left contexts ~init ~f:(fun t ctx ->
Expand All @@ -178,7 +186,7 @@ let t ?x ?profile:cmdline_profile () =
Loc.fail (Context.loc ctx)
"you can only have one context for merlin"
| Opam { merlin = true; _ }, None ->
{ merlin_context = Some name; contexts = ctx :: t.contexts }
{ merlin_context = Some name; contexts = ctx :: t.contexts; env = None }
| _ ->
{ t with contexts = ctx :: t.contexts })
in
Expand All @@ -200,13 +208,15 @@ let t ?x ?profile:cmdline_profile () =
return
{ merlin_context
; contexts = List.rev contexts
; env
}

let t ?x ?profile () = fields (t ?x ?profile ())

let default ?x ?profile () =
{ merlin_context = Some "default"
; contexts = [Context.default ?x ?profile ()]
; env = None
}

let load ?x ?profile p =
Expand Down
1 change: 1 addition & 0 deletions src/workspace.mli
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ end
type t =
{ merlin_context : string option
; contexts : Context.t list
; env : Dune_env.Stanza.t option
}

val load : ?x:string -> ?profile:string -> Path.t -> t
Expand Down
2 changes: 1 addition & 1 deletion test/blackbox-tests/test-cases/workspaces/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ Workspaces also allow you to set the env for a context:
Entering directory 'workspace-env'
(
(flags (-w -40 -machin))
(ocamlc_flags (-g))
(ocamlc_flags (-g -verbose))
(ocamlopt_flags (-g))
)
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(lang dune 1.0)
(lang dune 1.1)
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
(lang dune 1.0)
(lang dune 1.1)

(env
(default
(ocamlc_flags (:standard -verbose))))

(context
(default
Expand Down