Skip to content

Commit 70ccd34

Browse files
committed
Add support for the OPAMAUTOANSWER environment variable (for internal use only)
1 parent 072e1c9 commit 70ccd34

File tree

12 files changed

+72
-28
lines changed

12 files changed

+72
-28
lines changed

master_changes.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ users)
1616

1717
## Global CLI
1818
* Add cli version 2.5 [#6709 @kit-ty-kate]
19+
* Add mechanism for the `OPAMAUTOANSWER` environment variable (for internal use only) [#6709 @kit-ty-kate]
1920

2021
## Plugins
2122

@@ -190,6 +191,7 @@ users)
190191

191192
# API updates
192193
## opam-client
194+
* `OpamClientConfig.opam_init`: now takes an optional `auto_answer` argument [#6709 @kit-ty-kate]
193195

194196
## opam-repository
195197
* `OpamLocal.rsync_*`: Change the return type from `OpamFilename.*` to `unit` [#6658 @kit-ty-kate]
@@ -209,7 +211,10 @@ users)
209211
* `OpamVariable.variable_contents_equal`: was added [#6644 @kit-ty-kate]
210212

211213
## opam-core
214+
* `OpamConsole.confirm`: now takes an optional `name` argument [#6709 @kit-ty-kate]
212215
* `OpamConsole.log`: does not keep log messages before initialization if the code is ran through a library [#6487 @kit-ty-kate]
216+
* `OpamCoreConfig.auto_answer`: field and arguments were added [#6709 @kit-ty-kate]
217+
* `OpamCoreConfig.{answer,anwser_is,answer_is_yes}`: now take a `name` labeled argument [#6709 @kit-ty-kate]
213218
* `OpamCoreConfig.in_opam`: was added [#6487 @kit-ty-kate]
214219
* `OpamSystem.cpu_count`: now uses a C binding instead of system utilities to get the number of cores of the current machine [#6634 @kit-ty-kate]
215220
* `OpamSystem.is_reg_dir`: is now exposed, which returns `true` only if its parameter is a directory, exists and is not a symlink. It returns `false` otherwise [#6450 @kit-ty-kate]
@@ -221,6 +226,7 @@ users)
221226
* `OpamCompat.String.{starts_with,ends_with,for_all,fold_left}`: were added [#6442 @kit-ty-kate]
222227
* `OpamHash.check_string`: was added [#6661 @kit-ty-kate]
223228
* `OpamHash.equal_kind`: was added [#6644 @kit-ty-kate]
229+
* `OpamStd.Config.auto_answer`: was added [#6709 @kit-ty-kate]
224230
* `OpamStd.List.fold_left_map`: was moved to `OpamCompat.List.fold_left_map` [#6442 @kit-ty-kate]
225231
* `OpamStd.List.{cons,find_opt,filter_map}`: were removed. Use `Stdlib.List` instead. [#6442 @kit-ty-kate]
226232
* `OpamStd.List.mem`: was added, having as argument the equality function [#6644 @kit-ty-kate]

src/client/opamArg.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ let environment_variables =
8787
let open OpamStd.Config in
8888
let core =
8989
let open OpamCoreConfig.E in [
90+
"AUTOANSWER", cli_from cli2_5, (fun v -> AUTOANSWER (auto_answer v)),
91+
"internal use only.";
9092
"COLOR", cli_original, (fun v -> COLOR (env_when v)),
9193
"when set to $(i,always) or $(i,never), sets a default value for the \
9294
`--color' option.";

src/client/opamClientConfig.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ type 'a options_fun =
8181
?assume_depexts:bool ->
8282
?cli:OpamCLIVersion.t ->
8383
?scrubbed_environment_variables:string list ->
84-
?verbose_on:OpamTypes.name_set ->
84+
?verbose_on:OpamTypes.name_set ->
8585
'a
8686
(* constraint 'a = 'b -> 'c *)
8787

@@ -153,6 +153,7 @@ val opam_init:
153153
?retries:int ->
154154
?force_checksums:bool option ->
155155
?repo_tarring:bool ->
156+
?auto_answer:(string * OpamStd.Config.answer) list ->
156157
?debug_level:int ->
157158
?debug_sections:OpamStd.Config.sections ->
158159
?verbose_level:OpamStd.Config.level ->

src/client/opamSolution.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ let dry_run state solution =
10911091
(* Ask confirmation whenever the packages to modify are not exactly
10921092
the packages in the user request *)
10931093
let confirmation ?ask requested solution =
1094-
OpamCoreConfig.answer_is_yes () ||
1094+
OpamCoreConfig.answer_is_yes ~name:None () ||
10951095
ask = Some false ||
10961096
let solution_packages =
10971097
OpamPackage.names_of_packages (OpamSolver.all_packages solution)
@@ -1319,7 +1319,7 @@ let install_sys_packages_t ~propagate_st ~map_sysmap ~confirm env config
13191319
"You can retry with '--assume-depexts' to skip this check, or run 'opam \
13201320
option depext=false' to permanently disable handling of system \
13211321
packages.\n%s"
1322-
(if OpamStd.Sys.tty_in || OpamCoreConfig.answer_is `unsafe_yes then ""
1322+
(if OpamStd.Sys.tty_in || OpamCoreConfig.answer_is ~name:None `unsafe_yes then ""
13231323
else "Running the system package manager non-interactively requires \
13241324
'--confirm-level=unsafe-yes'.\n")
13251325
and give_up () =

src/core/opamConsole.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -786,19 +786,19 @@ let pause fmt =
786786
else
787787
Printf.ifprintf () fmt
788788

789-
let confirm ?(require_unsafe_yes=false) ?(default=true) fmt =
789+
let confirm ?(require_unsafe_yes=false) ?(default=true) ?name fmt =
790790
Printf.ksprintf (fun s ->
791791
if OpamCoreConfig.(!r.safe_mode) then false else
792792
let prompt =
793793
Printf.ksprintf OpamStd.Format.reformat "%s [%s/%s] " s
794794
(colorise `blue (if default then "Y" else "y"))
795795
(colorise `blue (if default then "n" else "N"))
796796
in
797-
if OpamCoreConfig.answer_is `unsafe_yes ||
798-
not require_unsafe_yes && OpamCoreConfig.answer_is_yes ()
797+
if OpamCoreConfig.answer_is ~name `unsafe_yes ||
798+
not require_unsafe_yes && OpamCoreConfig.answer_is_yes ~name ()
799799
then
800800
(formatted_msg "%sy\n" prompt; true)
801-
else if OpamCoreConfig.answer_is `all_no ||
801+
else if OpamCoreConfig.answer_is ~name `all_no ||
802802
OpamStd.Sys.(not tty_in)
803803
then
804804
(formatted_msg "%sn\n" prompt; false)
@@ -814,7 +814,7 @@ let confirm ?(require_unsafe_yes=false) ?(default=true) fmt =
814814
let read fmt =
815815
Printf.ksprintf (fun s ->
816816
formatted_msg "%s " s;
817-
if OpamCoreConfig.(answer_is `ask && not !r.safe_mode) then (
817+
if OpamCoreConfig.(answer_is ~name:None `ask && not !r.safe_mode) then (
818818
try match read_line () with
819819
| "" -> None
820820
| s -> Some s
@@ -983,7 +983,7 @@ let menu ?default ?unsafe_yes ?yes ~no ~options fmt =
983983
let default_s = OpamStd.(List.assoc Compare.equal default options_nums) in
984984
let no_s = OpamStd.(List.assoc Compare.equal no options_nums) in
985985
if OpamCoreConfig.(!r.safe_mode) then no else
986-
match OpamCoreConfig.answer(), unsafe_yes, yes with
986+
match OpamCoreConfig.answer ~name:None (), unsafe_yes, yes with
987987
| `unsafe_yes, Some a, _ -> print_string prompt; select a
988988
| #OpamStd.Config.yes_answer, _, Some a -> print_string prompt; select a
989989
| `all_no, _, _ -> print_string prompt; select no

src/core/opamConsole.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ val pause: ('a, unit, string, unit) format4 -> 'a
125125
prompt and wait user input if it is set [`all_yes] (interactive). Its
126126
default is false. *)
127127
val confirm:
128-
?require_unsafe_yes:bool -> ?default:bool ->
128+
?require_unsafe_yes:bool -> ?default:bool -> ?name:string ->
129129
('a, unit, string, bool) format4 -> 'a
130130

131131
(** Prompts the user with multiple numbered choices [(answer, message)].

src/core/opamCoreConfig.ml

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
module E = struct
1212

1313
type OpamStd.Config.E.t +=
14+
| AUTOANSWER of (string * OpamStd.Config.answer) list option
1415
| COLOR of OpamStd.Config.when_ option
1516
| CONFIRMLEVEL of OpamStd.Config.answer option
1617
| DEBUG of int option
@@ -29,6 +30,7 @@ module E = struct
2930
| YES of bool option
3031

3132
open OpamStd.Config.E
33+
let autoanswer = value (function AUTOANSWER l -> l | _ -> None)
3234
let color = value (function COLOR c -> c | _ -> None)
3335
let confirmlevel = value (function CONFIRMLEVEL c -> c | _ -> None)
3436
let debug = value (function DEBUG i -> i | _ -> None)
@@ -49,6 +51,7 @@ module E = struct
4951
end
5052

5153
type t = {
54+
auto_answer: (string * OpamStd.Config.answer) list;
5255
debug_level: int;
5356
debug_sections: OpamStd.Config.sections;
5457
verbose_level: OpamStd.Config.level;
@@ -71,6 +74,7 @@ type t = {
7174
}
7275

7376
type 'a options_fun =
77+
?auto_answer:(string * OpamStd.Config.answer) list ->
7478
?debug_level:int ->
7579
?debug_sections:OpamStd.Config.sections ->
7680
?verbose_level:OpamStd.Config.level ->
@@ -90,6 +94,7 @@ type 'a options_fun =
9094
'a
9195

9296
let default = {
97+
auto_answer = [];
9398
debug_level = 0;
9499
debug_sections = OpamStd.String.Map.empty;
95100
verbose_level = 0;
@@ -114,6 +119,7 @@ let default = {
114119
}
115120

116121
let setk k t
122+
?auto_answer
117123
?debug_level
118124
?debug_sections
119125
?verbose_level
@@ -133,6 +139,7 @@ let setk k t
133139
=
134140
let (+) x opt = match opt with Some x -> x | None -> x in
135141
k {
142+
auto_answer = t.auto_answer + auto_answer;
136143
debug_level = t.debug_level + debug_level;
137144
debug_sections = t.debug_sections + debug_sections;
138145
verbose_level = t.verbose_level + verbose_level;
@@ -179,6 +186,7 @@ let initk k =
179186
| _, _ -> None
180187
in
181188
(setk (setk (fun c -> r := c; k)) !r)
189+
?auto_answer:(E.autoanswer ())
182190
?debug_level:(E.debug ())
183191
?debug_sections:(E.debugsections ())
184192
?verbose_level:(E.verbose ())
@@ -198,19 +206,26 @@ let initk k =
198206

199207
let init ?noop:_ = initk (fun () -> ())
200208

201-
let answer () =
202-
match !r.confirm_level, !r.yes with
203-
| #OpamStd.Config.answer as c, _ -> c
204-
| _, Some true -> `all_yes
205-
| _, Some false -> `all_no
206-
| _ -> `ask
207-
208-
let answer_is =
209-
let answer = lazy (answer ()) in
210-
fun a -> Lazy.force answer = a
211-
212-
let answer_is_yes () =
213-
match answer () with
209+
let answer ~name () =
210+
let fallback () =
211+
match !r.confirm_level, !r.yes with
212+
| #OpamStd.Config.answer as c, _ -> c
213+
| _, Some true -> `all_yes
214+
| _, Some false -> `all_no
215+
| _ -> `ask
216+
in
217+
match !r.auto_answer, name with
218+
| _::_ as l, Some name ->
219+
(match OpamStd.List.assoc_opt String.equal name l with
220+
| Some a -> a
221+
| None -> fallback ())
222+
| [], _ | _, None -> fallback ()
223+
224+
let answer_is ~name a =
225+
answer ~name () = a
226+
227+
let answer_is_yes ~name () =
228+
match answer ~name () with
214229
| #OpamStd.Config.yes_answer -> true
215230
| _ -> false
216231

src/core/opamCoreConfig.mli

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
module E : sig
1515
type OpamStd.Config.E.t +=
16+
| AUTOANSWER of (string * OpamStd.Config.answer) list option
1617
| COLOR of OpamStd.Config.when_ option
1718
| CONFIRMLEVEL of OpamStd.Config.answer option
1819
| DEBUG of int option
@@ -37,6 +38,11 @@ module E : sig
3738
end
3839

3940
type t = private {
41+
auto_answer : (string * OpamStd.Config.answer) list;
42+
(** Controls the answer of specific interactive questions.
43+
It maps names to its wanted answer and takes precedence
44+
over [yes] and [confirm_level] for the questions linked
45+
to the specific names listed. *)
4046
debug_level : int;
4147
(** Controls debug messages, 0 to disable *)
4248
debug_sections : OpamStd.Config.sections;
@@ -83,6 +89,7 @@ type t = private {
8389
}
8490

8591
type 'a options_fun =
92+
?auto_answer:(string * OpamStd.Config.answer) list ->
8693
?debug_level:int ->
8794
?debug_sections:OpamStd.Config.sections ->
8895
?verbose_level:OpamStd.Config.level ->
@@ -132,9 +139,9 @@ val initk: 'a -> 'a options_fun
132139
[answer_is] and [answer_is_yes] computes the answer lazily, use [answer] in
133140
case of config update.
134141
*)
135-
val answer_is: OpamStd.Config.answer -> bool
136-
val answer_is_yes : unit -> bool
137-
val answer: unit -> OpamStd.Config.answer
142+
val answer_is: name:string option -> OpamStd.Config.answer -> bool
143+
val answer_is_yes : name:string option -> unit -> bool
144+
val answer: name:string option -> unit -> OpamStd.Config.answer
138145

139146
(** [true] if OPAM was compiled in developer mode *)
140147
val developer : bool

src/core/opamStd.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,17 @@ module Config = struct
17521752
try if bool s then `all_yes else `all_no
17531753
with Failure _ -> answer s)
17541754

1755+
let auto_answer =
1756+
env (fun s ->
1757+
List.filter_map (fun s ->
1758+
match OpamString.cut_at s '=' with
1759+
| Some (k, x) ->
1760+
(match answer x with
1761+
| x -> Some (k, x)
1762+
| exception Failure _ -> None)
1763+
| None -> None)
1764+
(String.split_on_char ':' s))
1765+
17551766

17561767
module E = struct
17571768
type t = ..

src/core/opamStd.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,8 @@ module Config : sig
680680

681681
val env_answer: env_var -> answer option
682682

683+
val auto_answer: env_var -> (string * answer) list option
684+
683685
module type Sig = sig
684686

685687
(** Read-only record type containing the lib's configuration options *)

0 commit comments

Comments
 (0)