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

Switch defaults configuration file #2930

Closed
wants to merge 3 commits into from
Closed
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
81 changes: 77 additions & 4 deletions src/client/opamCommands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ let init =
get_init_config ~no_sandboxing
~no_default_config_file:no_config_file ~add_config_file:config_file
in
let switch_defaults =
OpamFile.InitConfig.switch_defaults init_config
|> OpamStd.Option.default OpamInitDefaults.switch_defaults
in
let repo =
OpamStd.Option.map (fun url ->
let repo_url = OpamUrl.parse ?backend:repo_kind url in
Expand All @@ -384,7 +388,8 @@ let init =
OpamConsole.header_msg "Creating initial switch (%s)"
(OpamFormula.string_of_atoms packages);
OpamSwitchCommand.install
gt ~rt ~packages ~update_config:true (OpamSwitch.of_string comp)
gt ~rt ~packages ~update_config:true ~switch_defaults
(OpamSwitch.of_string comp)
|> ignore
| _ as nocomp ->
if nocomp <> None then
Expand All @@ -406,7 +411,7 @@ let init =
OpamConsole.header_msg "Creating initial switch (%s)"
(OpamFormula.string_of_atoms packages);
OpamSwitchCommand.install
gt ~rt ~packages ~update_config:true
gt ~rt ~packages ~update_config:true ~switch_defaults
(OpamSwitch.of_string "default")
|> ignore
| None ->
Expand Down Expand Up @@ -2065,15 +2070,58 @@ let switch =
mk_flag ["no-autoinstall"]
"This option is deprecated."
in
let config_file =
mk_opt_all ["config"] "FILE"
"Use the given init config file. If repeated, latest has the highest \
priority ($(b,i.e.) each field gets its value from where it was defined \
latest). Specifying a URL pointing to a config file instead is \
allowed."
OpamArg.url
in
let no_config_file =
mk_flag ["no-opamrc"]
(Printf.sprintf
"Don't read `/etc/opamrc' or `~%s.opamrc': use the default settings and \
the files specified through $(b,--config) only" Filename.dir_sep)
in
let switch
global_options build_options command print_short
no_switch packages empty descr full no_install deps_only repos
d_alias_of d_no_autoinstall params =
d_alias_of d_no_autoinstall config_file no_config_file params =
OpamArg.deprecated_option d_alias_of None
"alias-of" (Some "opam switch <switch-name> <compiler>");
OpamArg.deprecated_option d_no_autoinstall false "no-autoinstall" None;
apply_global_options global_options;
apply_build_options build_options;
let config_files =
let principal_config_files =
if no_config_file then []
else
let f f =
if OpamFile.exists f then
Some (OpamFile.to_string f |> OpamFilename.of_string, `InitConfig)
else
None
in
OpamStd.List.filter_map f (OpamPath.init_config_files ())
in
principal_config_files
@ List.map (fun url ->
match OpamUrl.local_file url with
| Some f -> (f, `SwitchDefaults)
| None ->
let f = OpamFilename.of_string (OpamSystem.temp_file "conf") in
OpamProcess.Job.run (OpamDownload.download_as ~overwrite:false url f);
let hash = OpamHash.compute ~kind:`SHA256 (OpamFilename.to_string f) in
if OpamConsole.confirm
"Using configuration file from %s. \
Please verify the following SHA256:\n %s\n\
Is this correct ?"
(OpamUrl.to_string url) (OpamHash.contents hash)
then (f, `SwitchDefaults)
else OpamStd.Sys.exit_because `Aborted
) config_file
in
let packages =
match packages, empty with
| None, true -> Some []
Expand Down Expand Up @@ -2152,6 +2200,29 @@ let switch =
compilers;
`Ok ()
| Some `install, switch_arg::params ->
let switch_defaults =
try
OpamConsole.note "Will configure switch from built-in defaults%s."
(OpamStd.List.concat_map ~nil:"" ~left:", " ", "
(fun (f, _) -> OpamFilename.to_string f) config_files);
List.fold_left (fun acc (f, kind) ->
let config =
match kind with
| `InitConfig ->
OpamFile.InitConfig.read (OpamFile.make f) |> OpamFile.InitConfig.switch_defaults
| `SwitchDefaults ->
Some (OpamFile.SwitchDefaults.read (OpamFile.make f))
in
OpamStd.Option.map_default (OpamFile.SwitchDefaults.add acc) acc config)
OpamInitDefaults.switch_defaults
config_files
with e ->
OpamConsole.error
"Error in configuration file, fix it, use '--no-opamrc', or check \
your '--config FILE' arguments:";
OpamConsole.errmsg "%s\n" (Printexc.to_string e);
OpamStd.Sys.exit_because `Configuration_error
in
OpamGlobalState.with_ `Lock_write @@ fun gt ->
with_repos_rt gt repos @@ fun (repos, rt) ->
let switch = OpamSwitch.of_string switch_arg in
Expand All @@ -2163,6 +2234,7 @@ let switch =
?synopsis:descr ?repos
~update_config:(not no_switch)
~packages
~switch_defaults
~local_compiler
switch
in
Expand Down Expand Up @@ -2323,7 +2395,8 @@ let switch =
$print_short_flag
$no_switch
$packages $empty $descr $full $no_install $deps_only
$repos $d_alias_of $d_no_autoinstall $params)),
$repos $d_alias_of $d_no_autoinstall $config_file $no_config_file
$params)),
term_info "switch" ~doc ~man

(* PIN *)
Expand Down
6 changes: 5 additions & 1 deletion src/client/opamInitDefaults.ml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ module I = OpamFile.InitConfig

let (@|) g f = OpamStd.Op.(g @* f) ()

let switch_defaults =
OpamFile.SwitchDefaults.empty

let init_config ?(sandboxing=true) () =
I.empty |>
I.with_repositories
Expand All @@ -137,4 +140,5 @@ let init_config ?(sandboxing=true) () =
I.with_recommended_tools @| recommended_tools |>
I.with_required_tools @| required_tools ~sandboxing |>
I.with_init_scripts @| init_scripts |>
I.with_dl_tool @| dl_tool
I.with_dl_tool @| dl_tool |>
I.with_switch_defaults switch_defaults
4 changes: 4 additions & 0 deletions src/client/opamInitDefaults.mli
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ val default_compiler: formula

val eval_variables: (OpamVariable.t * string list * string) list

(** Default switch defaults configuration file (also embedded in
{!init_config}). *)
val switch_defaults: OpamFile.SwitchDefaults.t

(** Default initial configuration file for use by [opam init] if nothing is
supplied. *)
val init_config: ?sandboxing:bool -> unit -> OpamFile.InitConfig.t
51 changes: 49 additions & 2 deletions src/client/opamSwitchCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ let install_compiler_packages t atoms =
(Success result);
t

let install gt ~rt ?synopsis ?repos ~update_config ~packages ?(local_compiler=false) switch =
let install gt ~rt ?synopsis ?repos ~update_config ~packages ~switch_defaults
?(local_compiler=false) switch =
let update_config = update_config && not (OpamSwitch.is_external switch) in
let old_switch_opt = OpamFile.Config.switch gt.config in
let comp_dir = OpamPath.Switch.root gt.root switch in
Expand All @@ -285,7 +286,53 @@ let install gt ~rt ?synopsis ?repos ~update_config ~packages ?(local_compiler=fa
let gt, st =
if not (OpamStateConfig.(!r.dryrun) || OpamClientConfig.(!r.show)) then
let gt =
OpamSwitchAction.create_empty_switch gt ?synopsis ?repos switch
let env full_var =
let open OpamVariable.Full in
match scope full_var with
| Global ->
OpamPackageVar.resolve_global gt full_var
| Self ->
None
| Package name ->
match variable full_var |> OpamVariable.to_string with
| "installed" ->
let f (package, _) =
OpamPackage.Name.compare name package = 0
in
Some (B (List.exists f packages))
| _ ->
None
in
let configure_switch conf =
let variables =
(* XXX Should be able to use description in the same way as for
eval_variables *)
let f ((name, value, _description), filter) =
let eval = OpamFilter.eval_to_bool ~default:false env in
let expand = OpamFilter.expand_string (OpamPackageVar.resolve_global gt) in
if OpamStd.Option.map_default eval true filter then
let value =
match value with
| B _ ->
value
| S value ->
S (expand value)
| L values ->
L (List.map expand values)
in
Some (name, value)
else
None
in
let switch_variables =
OpamFile.SwitchDefaults.switch_variables switch_defaults
in
OpamFile.Switch_config.(conf.variables)
@ OpamStd.List.filter_map f switch_variables
in
{conf with OpamFile.Switch_config.variables}
in
OpamSwitchAction.create_empty_switch gt ?synopsis ?repos ~configure_switch switch
in
if update_config then
gt, OpamSwitchAction.set_current_switch `Lock_write gt ~rt switch
Expand Down
1 change: 1 addition & 0 deletions src/client/opamSwitchCommand.mli
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ val install:
?repos:repository_name list ->
update_config:bool ->
packages:atom conjunction ->
switch_defaults: OpamFile.SwitchDefaults.t ->
?local_compiler:bool ->
switch ->
unlocked global_state * rw switch_state
Expand Down
76 changes: 75 additions & 1 deletion src/format/opamFile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,69 @@ module Config = struct
include SyntaxFile(ConfigSyntax)
end

module SwitchDefaultsSyntax = struct
let internal = "switch-defaults"

type t = {
opam_version : opam_version;
switch_variables :
((variable * variable_contents * string) * filter option) list;
}

let opam_version t = t.opam_version
let switch_variables t = t.switch_variables

let with_opam_version opam_version t = {t with opam_version}
let with_switch_variables switch_variables t = {t with switch_variables}

let empty = {
opam_version = OpamVersion.current_nopatch;
switch_variables = [];
}

let fields =
[
"switch-variables", Pp.ppacc
with_switch_variables switch_variables
(Pp.V.map_list ~depth:2
(Pp.V.map_option
(Pp.V.map_triple
(Pp.V.ident -| Pp.of_module "variable" (module OpamVariable))
Pp.V.variable_contents
Pp.V.string)
(Pp.opt Pp.V.filter)));
]

let pp_contents =
let name = internal in
Pp.I.fields ~name ~empty fields
-| Pp.I.show_errors ~name ~strict:true ()

let pp =
let name = internal in
let fields =
("opam-version", Pp.ppacc
with_opam_version opam_version
(Pp.V.string
-| Pp.of_module "opam-version" (module OpamVersion));)::fields
in
Pp.I.map_file @@
Pp.I.fields ~name ~empty fields -|
Pp.I.show_errors ~name ~strict:true ()

let add t1 t2 =
let list = function [] -> fun l -> l | l -> fun _ -> l in
{
opam_version = t2.opam_version;
switch_variables = list t2.switch_variables t1.switch_variables;
}

end
module SwitchDefaults = struct
include SwitchDefaultsSyntax
include SyntaxFile(SwitchDefaultsSyntax)
end

module InitConfigSyntax = struct
let internal = "init-config"

Expand All @@ -1228,6 +1291,7 @@ module InitConfigSyntax = struct
recommended_tools : (string list * string option * filter option) list;
required_tools : (string list * string option * filter option) list;
init_scripts : ((string * string) * filter option) list;
switch_defaults : SwitchDefaults.t option;
}

let opam_version t = t.opam_version
Expand All @@ -1245,6 +1309,7 @@ module InitConfigSyntax = struct
let recommended_tools t = t.recommended_tools
let required_tools t = t.required_tools
let init_scripts t = t.init_scripts
let switch_defaults t = t.switch_defaults

let with_opam_version opam_version t = {t with opam_version}
let with_repositories repositories t = {t with repositories}
Expand All @@ -1261,6 +1326,8 @@ module InitConfigSyntax = struct
let with_recommended_tools recommended_tools t = {t with recommended_tools}
let with_required_tools required_tools t = {t with required_tools}
let with_init_scripts init_scripts t = {t with init_scripts}
let with_switch_defaults switch_defaults t =
{t with switch_defaults = Some switch_defaults}

let criterion kind t =
try Some (List.assoc kind t.solver_criteria)
Expand All @@ -1286,6 +1353,7 @@ module InitConfigSyntax = struct
recommended_tools = [];
required_tools = [];
init_scripts = [];
switch_defaults = None;
}

let pp_repository_def =
Expand Down Expand Up @@ -1387,11 +1455,16 @@ module InitConfigSyntax = struct
(fun (fld, ppacc) -> fld, Pp.embed with_wrappers wrappers ppacc)
Wrappers.fields

let sections = [
"switch-defaults",
Pp.ppacc_opt with_switch_defaults switch_defaults
(Pp.I.anonymous_section SwitchDefaults.pp_contents);
]

let pp =
let name = internal in
Pp.I.map_file @@
Pp.I.fields ~name ~empty fields -|
Pp.I.fields ~name ~empty ~sections fields -|
Pp.I.show_errors ~name ~strict:true ()

let add t1 t2 =
Expand Down Expand Up @@ -1420,6 +1493,7 @@ module InitConfigSyntax = struct
recommended_tools = list t2.recommended_tools t1.recommended_tools;
required_tools = list t2.required_tools t1.required_tools;
init_scripts = list t2.init_scripts t1.init_scripts;
switch_defaults = opt t2.switch_defaults t1.switch_defaults;
}

end
Expand Down
Loading