Skip to content

Commit 49f87e4

Browse files
committed
env: add '--bindings' flag to output as environment variable bindings
1 parent eec1cc4 commit 49f87e4

File tree

5 files changed

+85
-32
lines changed

5 files changed

+85
-32
lines changed

master_changes.md

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ users)
6969
## Clean
7070

7171
## Env
72+
* [NEW] Add `--bindings` option to output env as environment variable binding, useful for CI environment populating [#6316 @rjbou - fix #5791]
7273

7374
## Opamfile
7475

src/client/opamCommands.ml

+18-11
Original file line numberDiff line numberDiff line change
@@ -1302,9 +1302,15 @@ let option cli =
13021302
$global_options cli $fieldvalue $global cli)
13031303

13041304
module Common_config_flags = struct
1305-
let sexp cli =
1306-
mk_flag ~cli cli_original ["sexp"]
1307-
"Print environment as an s-expression rather than in shell format"
1305+
let env_format cli =
1306+
mk_vflag ~cli None [
1307+
cli_original, Some `sexp, ["sexp"],
1308+
"Print environment as an s-expression rather than in shell format";
1309+
cli_from cli2_4, Some `bindingss, ["bindingss"],
1310+
"Print environment as variable bindings rather than in shell format.\
1311+
Useful to populate CI environment."
1312+
]
1313+
13081314

13091315
let inplace_path cli =
13101316
mk_flag ~cli cli_original ["inplace-path"]
@@ -1402,7 +1408,7 @@ let config cli =
14021408
let open Common_config_flags in
14031409

14041410
let config global_options
1405-
command shell sexp inplace_path
1411+
command shell env_format inplace_path
14061412
set_opamroot set_opamswitch params () =
14071413
apply_global_options cli global_options;
14081414
let shell = match shell with
@@ -1418,7 +1424,7 @@ let config cli =
14181424
| Some sw ->
14191425
`Ok (OpamConfigCommand.env gt sw
14201426
~set_opamroot ~set_opamswitch
1421-
~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish)
1427+
~csh:(shell=SH_csh) ~env_format ~fish:(shell=SH_fish)
14221428
~pwsh ~cmd:(shell=SH_cmd)
14231429
~inplace_path))
14241430
| Some `revert_env, [] ->
@@ -1428,7 +1434,7 @@ let config cli =
14281434
| Some sw ->
14291435
`Ok (OpamConfigCommand.ensure_env gt sw;
14301436
OpamConfigCommand.print_eval_env
1431-
~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish)
1437+
~csh:(shell=SH_csh) ~env_format ~fish:(shell=SH_fish)
14321438
~pwsh ~cmd:(shell=SH_cmd)
14331439
(OpamEnv.add [] [])))
14341440
| Some `list, [] ->
@@ -1640,7 +1646,8 @@ let config cli =
16401646

16411647
mk_command_ret ~cli cli_original "config" ~doc ~man
16421648
Term.(const config
1643-
$global_options cli $command $shell_opt cli cli_original $sexp cli
1649+
$global_options cli $command $shell_opt cli cli_original
1650+
$env_format cli
16441651
$inplace_path cli
16451652
$set_opamroot cli $set_opamswitch cli
16461653
$params)
@@ -1711,7 +1718,7 @@ let env cli =
17111718
after printing the list of not up-to-date variables."
17121719
in
17131720
let env
1714-
global_options shell sexp inplace_path set_opamroot set_opamswitch
1721+
global_options shell env_format inplace_path set_opamroot set_opamswitch
17151722
revert check () =
17161723
apply_global_options cli global_options;
17171724
if check then
@@ -1733,19 +1740,19 @@ let env cli =
17331740
| Some sw ->
17341741
OpamConfigCommand.env gt sw
17351742
~set_opamroot ~set_opamswitch
1736-
~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish)
1743+
~csh:(shell=SH_csh) ~env_format ~fish:(shell=SH_fish)
17371744
~pwsh ~cmd:(shell=SH_cmd)
17381745
~inplace_path);
17391746
| true ->
17401747
OpamConfigCommand.print_eval_env
1741-
~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish)
1748+
~csh:(shell=SH_csh) ~env_format ~fish:(shell=SH_fish)
17421749
~pwsh ~cmd:(shell=SH_cmd)
17431750
(OpamEnv.add [] [])
17441751
in
17451752
let open Common_config_flags in
17461753
mk_command ~cli cli_original "env" ~doc ~man
17471754
Term.(const env
1748-
$global_options cli $shell_opt cli cli_original $sexp cli
1755+
$global_options cli $shell_opt cli cli_original $env_format cli
17491756
$inplace_path cli $set_opamroot cli $set_opamswitch cli
17501757
$revert $check)
17511758

src/client/opamConfigCommand.ml

+28-14
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ let print_sexp_env output env =
131131
aux env;
132132
output ")\n"
133133

134+
let print_bindingss_env output env =
135+
let rec aux = function
136+
| [] -> ()
137+
| (k, v, _) :: r ->
138+
if not (List.exists (fun (k1, _, _) -> k = k1) r) then
139+
Printf.ksprintf output "%s=%s\n" k v;
140+
aux r
141+
in
142+
aux env
143+
134144
let rec print_fish_env output env =
135145
let set_arr_cmd ?(modf=fun x -> x) k v =
136146
let v = modf @@ OpamStd.String.split v ':' in
@@ -183,7 +193,7 @@ let print_without_cr s =
183193
output_string stdout s;
184194
flush stdout
185195

186-
let print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd env =
196+
let print_eval_env ~csh ~env_format ~fish ~pwsh ~cmd env =
187197
let env = (env : OpamTypes.env :> (string * string * string option) list) in
188198
let output_normally = OpamConsole.msg "%s" in
189199
let never_with_cr =
@@ -192,18 +202,22 @@ let print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd env =
192202
else
193203
output_normally
194204
in
195-
if sexp then
205+
match env_format with
206+
| Some `sexp ->
196207
print_sexp_env output_normally env
197-
else if csh then
198-
print_csh_env never_with_cr env
199-
else if fish then
200-
print_fish_env never_with_cr env
201-
else if pwsh then
202-
print_pwsh_env output_normally env
203-
else if cmd then
204-
print_cmd_env output_normally env
205-
else
206-
print_env never_with_cr env
208+
| Some `bindingss ->
209+
print_bindingss_env output_normally env
210+
| None ->
211+
if csh then
212+
print_csh_env never_with_cr env
213+
else if fish then
214+
print_fish_env never_with_cr env
215+
else if pwsh then
216+
print_pwsh_env output_normally env
217+
else if cmd then
218+
print_cmd_env output_normally env
219+
else
220+
print_env never_with_cr env
207221

208222
let check_writeable l =
209223
let map_writeable ({OpamTypes.envu_op; _} as update) =
@@ -331,7 +345,7 @@ let ensure_env gt switch =
331345
ignore (ensure_env_aux gt switch)
332346

333347
let env gt switch ?(set_opamroot=false) ?(set_opamswitch=false)
334-
~csh ~sexp ~fish ~pwsh ~cmd ~inplace_path =
348+
~csh ~env_format ~fish ~pwsh ~cmd ~inplace_path =
335349
log "config-env";
336350
let opamroot_not_current =
337351
let current = gt.root in
@@ -371,7 +385,7 @@ let env gt switch ?(set_opamroot=false) ?(set_opamswitch=false)
371385
let env =
372386
ensure_env_aux ~set_opamroot ~set_opamswitch ~force_path gt switch
373387
in
374-
print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd env
388+
print_eval_env ~csh ~env_format ~fish ~pwsh ~cmd env
375389
[@@ocaml.warning "-16"]
376390

377391
let subst gt fs =

src/client/opamConfigCommand.mli

+12-7
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,28 @@ open OpamStateTypes
1616

1717
(** {2 `opam config` subcommand and their associated commands } *)
1818

19-
(** Display the current environment. Booleans csh, sexp and fish set an
20-
alternative output (unspecified if more than one is true, sh-style by
21-
default). [inplace_path] changes how the PATH variable is updated when there
22-
is already an opam entry: either at the same rank, or pushed in front. *)
19+
(** Display the current environment. Booleans [csh], [env_format] and [fish]
20+
set an alternative output (unspecified if more than one is true, sh-style
21+
by default). [inplace_path] changes how the PATH variable is updated when
22+
there is already an opam entry: either at the same rank, or pushed in
23+
front. *)
2324
val env:
2425
'a global_state -> switch ->
2526
?set_opamroot:bool -> ?set_opamswitch:bool ->
26-
csh:bool -> sexp:bool -> fish:bool -> pwsh:bool -> cmd:bool ->
27-
inplace_path:bool -> unit
27+
csh:bool -> env_format:[< `sexp | `bindingss ] option -> fish:bool ->
28+
pwsh:bool -> cmd:bool -> inplace_path:bool ->
29+
unit
2830

2931
(** Ensures that the environment file exists in the given switch, regenerating
3032
it, if necessary. *)
3133
val ensure_env: 'a global_state -> switch -> unit
3234

3335
(** Like [env] but allows one to specify the precise env to print rather than
3436
compute it from a switch state *)
35-
val print_eval_env: csh:bool -> sexp:bool -> fish:bool -> pwsh:bool -> cmd:bool -> env -> unit
37+
val print_eval_env:
38+
csh:bool -> env_format:[< `sexp | `bindingss ] option -> fish:bool -> pwsh:bool ->
39+
cmd:bool -> env
40+
-> unit
3641

3742
(** Display the content of all available packages variables *)
3843
val list: 'a switch_state -> name list -> unit

tests/reftests/env.test

+26
Original file line numberDiff line numberDiff line change
@@ -651,3 +651,29 @@ OPAM_PACKAGE_NAME=another-package
651651
OPAM_PACKAGE_VERSION=another-version
652652
OPAM_SWITCH_PREFIX=${BASEDIR}/OPAM/bd
653653
PATH=${BASEDIR}/OPAM/bd/bin:another-path
654+
### : opam env outputs :
655+
### opam switch create outputs --empty
656+
### <pkg:op.1>
657+
opam-version: "2.0"
658+
setenv: [ PKGVAR = "piou"]
659+
### opam install op -y
660+
The following actions will be performed:
661+
=== install 1 package
662+
- install op 1
663+
664+
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
665+
-> installed op.1
666+
Done.
667+
### opam exec -- opam env --sexp | grep -v "OPAM_LAST_ENV|MANPATH|PATH"
668+
(
669+
("OPAM_SWITCH_PREFIX" "${BASEDIR}/OPAM/outputs")
670+
("PKGVAR" "piou")
671+
)
672+
### opam exec -- opam env --bindingss | grep -v "OPAM_LAST_ENV|MANPATH|PATH"
673+
OPAM_SWITCH_PREFIX=${BASEDIR}/OPAM/outputs
674+
PKGVAR=piou
675+
### opam exec -- opam env --bindingss --sexp
676+
opam: options '--sexp' and '--bindingss' cannot be present at the same time
677+
Usage: opam env [OPTION]…
678+
Try 'opam env --help' or 'opam --help' for more information.
679+
# Return code 2 #

0 commit comments

Comments
 (0)