ocaml / opam

opam is a source-based package manager. It supports multiple simultaneous compiler installations, flexible package constraints, and a Git-friendly development workflow.
https://opam.ocaml.org
Other
1.24k stars 353 forks source link

conflicts: field accepts only conjunctions? #2246

Closed edwintorok closed 9 years ago

edwintorok commented 9 years ago

I was trying to turn depopts version constraints into conflicts: I thought the equivalent of"fileutils" {(>= "2.0.0") & (< "3.0")} in conflicts would be its negation: "fileutils" {(>= "3.0") | (< "2.0.0")}, but I get an error (and no install/remove works in opam until I fix the constraint):

[ERROR] fileutils ((>= 3.0) | (< 2.0.0)) is not a valid conjunction

If I replace the | with & I get the behaviour I want ("fileutils" {(>= "3.0") & (< "2.0.0")}), however you can no longer evaluate the version constraint the "obvious" way (i.e. put your current version into the formula and evaluate it as a boolean formula): ((x >= "3.0") & (x < "2.0.0") is always false.

Do I understand it correctly the semantics of this constraint:

conflicts: [
 "package1" { (>= "3.0") & (< "1.0") } 
 "package2" { (>= "4.0") } 
] 

to mean that: there is a conflict when version(package1) >= 3.0 and there is a conflict when version(package1) < 1.0 and there is a conflict when version(package2) >= 4.0, however the and in this sentence is not a logical and, there is a conflict when any of the statements is true. The formula to express when there is a conflict would actually be: version(package1) >= 3.0 | version(package2) < 1.0 | version(package2) >= 4.0.

Chris00 commented 9 years ago

a conflict when version(package1) >= 3.0 and there is a conflict when version(package1) < 1.0 and there is a conflict when version(package2) >= 4.0

If this is the right interpretation, that also means that the <version-constraint> do not have the same meaning depending on the section the appear in, which is not very nice...

samoht commented 9 years ago

See the CUDF manual, page 24:

conflicts indicate which packages cannot be co-installed, in any given installation, together with a given package. Note that the language to express conflicts is more limited than that used to express dependencies: it consists of plain lists of possibly versioned package names, rather than CNF formulae.

opam uses the same semantics. You should not see this field as a formula, just as a list of possible conflicts.

edwintorok commented 9 years ago

OK, so I probably shouldn't use the formula syntax for something that isn't a formula. Am I correct to just list a package multiple times with different version constraints? conflicts: [ "fileutils" {< "2.0"} "fileutils" {>= "3.0"} ]

Chris00 commented 9 years ago

On page 16, one reads:

Versioned package names: VPkg ::= PkgName ( Sp + VConstr )? VConstr ::= RelOp Sp + Ver RelOp ::= "=" | "!=" | ">=" | ">" | "<=" | "<" Sp ::= U+0020 (i.e. space) | U+0009 (i.e. tab) Ver ::= PosInt

@samoht So the & is an addition by OPAM? If so, isn't | more coherent with the meaning of constraint formulas?

samoht commented 9 years ago

yea, I believe the & is an addition of opam, and I agree that this is confusing (and are the error messages). things could probably be improved there.

AltGr commented 9 years ago

Yes, I noticed this weird semantics a while ago and wanted to change them, but was afraid of breaking existing packages by doing this in a minor version. The formula "fileutils" {>= "3.0" | < "2.0.0"} is indeed correct, but current opam instead expects & to mean "conflicts with A and with B". I am sure I reported it somewhere but can't find the issue again. I was expecting to fix this in 1.3 with a proper check (and rewrite, if necessary) of packages.