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

Rewrite the conflict explanation extraction mechanism #4349

Merged
merged 15 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from 12 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
25 changes: 12 additions & 13 deletions src/client/opamClient.ml
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,13 @@ let upgrade_t
| requested, Conflicts cs ->
log "conflict!";
if not (OpamPackage.Name.Set.is_empty requested) then
(OpamConsole.msg "%s"
(OpamCudf.string_of_conflict t.packages
(OpamConsole.error "Package conflict!";
OpamConsole.errmsg "%s"
(OpamCudf.string_of_conflicts t.packages
(OpamSwitchState.unavailable_reason t) cs);
OpamStd.Sys.exit_because `No_solution);
let reasons, chains, cycles =
OpamCudf.strings_of_conflict t.packages
let reasons, cycles =
OpamCudf.conflict_explanations t.packages
(OpamSwitchState.unavailable_reason t) cs in
if cycles <> [] then begin
OpamConsole.error
Expand All @@ -292,11 +293,8 @@ let upgrade_t
OpamConsole.warning
"Upgrade is not possible because of conflicts or packages that \
are no longer available:";
OpamConsole.errmsg "%s" (OpamStd.Format.itemize (fun x -> x) reasons);
if chains <> [] then
OpamConsole.errmsg
"The following dependencies are the cause:\n%s"
(OpamStd.Format.itemize (fun x -> x) chains);
OpamConsole.errmsg "%s"
(OpamStd.Format.itemize (OpamCudf.string_of_conflict ~indent:4) reasons);
OpamConsole.errmsg
"\nYou may run \"opam upgrade --fixup\" to let opam fix the \
current state.\n"
Expand Down Expand Up @@ -476,7 +474,7 @@ let fixup t =
| _, Success _ -> true
| _, Conflicts cs ->
log "conflict: %a"
(slog (OpamCudf.string_of_conflict t.packages @@
(slog (OpamCudf.string_of_conflicts t.packages @@
OpamSwitchState.unavailable_reason t))
cs;
false
Expand Down Expand Up @@ -513,7 +511,7 @@ let fixup t =
available. Either fix their prerequisites or change them through \
'opam list --base' and 'opam switch set-base'.";
OpamConsole.errmsg "%s"
(OpamCudf.string_of_conflict t.packages
(OpamCudf.string_of_conflicts t.packages
(OpamSwitchState.unavailable_reason t) cs);
t, Conflicts cs
| Success solution ->
Expand Down Expand Up @@ -1217,8 +1215,9 @@ let install_t t ?ask ?(ignore_conflicts=false) ?(depext_only=false)
let t, solution = match solution with
| Conflicts cs ->
log "conflict!";
OpamConsole.msg "%s"
(OpamCudf.string_of_conflict t.packages
OpamConsole.error "Package conflict!";
OpamConsole.errmsg "%s"
(OpamCudf.string_of_conflicts t.packages
(OpamSwitchState.unavailable_reason t) cs);
t, if depext_only then None else Some (Conflicts cs)
| Success solution ->
Expand Down
2 changes: 1 addition & 1 deletion src/client/opamListCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ let apply_selector ~base st = function
"No solution%s for %s: %s"
(if tog.depopts then " including optional dependencies" else "")
(OpamFormula.string_of_atoms atoms)
(OpamCudf.string_of_conflict st.packages
(OpamCudf.string_of_conflicts st.packages
(OpamSwitchState.unavailable_reason st) cs))
| Pattern (psel, pat) ->
let re =
Expand Down
17 changes: 5 additions & 12 deletions src/client/opamSolution.ml
Original file line number Diff line number Diff line change
Expand Up @@ -238,22 +238,15 @@ module Json = struct
in
OpamJson.append "solution" (`A (List.rev to_proceed))
| Conflicts cs ->
let causes,_,cycles =
OpamCudf.strings_of_conflict
let causes, cycles =
OpamCudf.conflict_explanations
t.packages (OpamSwitchState.unavailable_reason t) cs
in
let chains = OpamCudf.conflict_chains t.packages cs in
let jchains =
`A (List.map (fun c ->
`A ((List.map (fun f ->
`String (OpamFormula.to_string (Atom f))) c)))
chains)
in
let causes = List.map OpamCudf.string_of_conflict causes in
let toj l = `A (List.map (fun s -> `String s) l) in
OpamJson.append "conflicts"
(`O ((if cycles <> [] then ["cycles", toj cycles] else []) @
(if causes <> [] then ["causes", toj causes] else []) @
(if chains <> [] then ["broken-deps", jchains] else [])))
(if causes <> [] then ["causes", toj causes] else [])))

let exc e =
let lmap f l = List.rev (List.rev_map f l) in
Expand Down Expand Up @@ -1196,7 +1189,7 @@ let resolve_and_apply ?ask t action ~orphans ?reinstall ~requested ?add_roots
| Conflicts cs ->
log "conflict!";
OpamConsole.msg "%s"
(OpamCudf.string_of_conflict t.packages
(OpamCudf.string_of_conflicts t.packages
(OpamSwitchState.unavailable_reason t) cs);
t, Conflicts cs
| Success solution ->
Expand Down
8 changes: 5 additions & 3 deletions src/client/opamSwitchCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,12 @@ let install_compiler ?(additional_installs=[]) ?(deps_only=false) t =
let solution = match solution with
| Success s -> s
| Conflicts cs ->
OpamConsole.error_and_exit `No_solution
"Could not resolve base install for this switch:\n%s"
(OpamCudf.string_of_conflict t.packages
OpamConsole.error
"Could not resolve base install for this switch:";
OpamConsole.errmsg "%s\n"
(OpamCudf.string_of_conflicts t.packages
(OpamSwitchState.unavailable_reason t) cs);
OpamStd.Sys.exit_because `No_solution
in
let () = match OpamSolver.stats solution with
| { s_install = _; s_reinstall = 0; s_upgrade = 0;
Expand Down
5 changes: 5 additions & 0 deletions src/format/opamFormula.mli
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ val satisfies_depends: OpamPackage.Set.t -> t -> bool
all disjunction cases) *)
val packages: OpamPackage.Set.t -> t -> OpamPackage.Set.t

val compare_nc:
(OpamPackage.Name.t * version_formula) ->
(OpamPackage.Name.t * version_formula) ->
int

(** Convert a formula to CNF *)
val cnf_of_formula: 'a formula -> 'a formula

Expand Down
Loading