Discussion:
Conflicts in the meta spec
Michael G. Schwern
2013-04-15 16:56:18 UTC
Permalink
TL;DR version...
IMO we only need to clarify what "conflicts" means and what actions CPAN
tools should take.

We talked in the Consensus Dome about the need for and meaning of the
"conflicts" relationship in the CPAN::Meta::Spec.
https://metacpan.org/module/CPAN::Meta::Spec#Prereq-Spec

IIRC the conclusion was...
* We need it.
* It's not clear what it means. (I don't recall what the confusion was)
* Let's see what Debian does.

I can come up with a few situations where being able to declare
conflicts with other packages would have (and will be) very useful.
Mostly in the "if you install Foo version 1.23 then your previously
installed Bar version 2.34 will break".

* Moose vs MooseX
* Test::Harness 2 and 3 broke a few modules
* Test::Builder 1.5 vs Test::Class, Test::Most, Test::Random...
* Module::Install vs its plugins

Why we need this, why you can't do it with "requires" is because this is
for modules which you do not depend on. Often they depend on you.
MooseX::Blah depends on Moose, so Moose declares conflict with versions
of MooseX::Blah it breaks.

IMO CPAN shells can take several actions on a conflict...
* Warn the user
* Upgrade the conflicting modules (if possible)
* Refuse to install the new version if non-conflicting upgrades are not
available

Debian has several fields to deal with this, "Breaks", "Conflicts" and
"Replaces".
http://www.debian.org/doc/debian-policy/ch-relationships.html#s-breaks
http://www.debian.org/doc/debian-policy/ch-relationships.html#s-conflicts
http://www.debian.org/doc/debian-policy/ch-relationships.html#s-replaces

We may not need them all. Here's a summary.

====================================================================
Breaks
------
When one binary package declares that it breaks another, dpkg will
refuse to allow the package which declares Breaks to be unpacked unless
the broken package is deconfigured first, and it will refuse to allow
the broken package to be reconfigured.

Conflicts
---------
When one binary package declares a conflict with another using a
Conflicts field, dpkg will refuse to allow them to be unpacked on the
system at the same time. This is a stronger restriction than Breaks,
which prevents the broken package from being configured while the
breaking package is in the "Unpacked" state but allows both packages to
be unpacked at the same time.

If one package is to be unpacked, the other must be removed first.

Replaces
--------
Packages can declare in their control file that they should overwrite
files in certain other packages, or completely replace other packages.
It is usually an error for a package to contain files which are on the
system in another package. However, if the overwriting package declares
that it Replaces the one containing the file being overwritten, then
dpkg will replace the file from the old package with that from the new.
Second, Replaces allows the packaging system to resolve which package
should be removed when there is a conflict. This usage only takes effect
when the two packages do conflict, so that the two usages of this field
do not interfere with each other.
===================================================================

"Breaks" vs "Conflicts" is only about at what phase they conflict. We
have that covered with prereq phases.

# Declare that Test-Simple 1.5.0 will break Test::Class <= 0.38
name: Test-Simple
version: 1.5.0
prereq:
runtime:
conflicts:
Test::Class: <= 0.38

It seems pretty clear from the Debian manual that when two things
conflict it means they cannot be installed at the same time. That to me
seems the correct reading and covers our use cases.

I don't think "Replaces" yet simply because we don't have a clear
concept of a distribution. For example, you'd use Replaces to say "LWP
replaces libwwwperl" but we don't understand that yet. It might be more
useful when we have the installed distributions database. We also have
no concept of virtual packages, which means we can't say "Apache
replaces http-server". Maybe we can do it at the package name level,
but I don't see there is a concrete need.
Mike Doherty
2013-04-15 18:02:53 UTC
Permalink
Post by Michael G. Schwern
Why we need this, why you can't do it with "requires" is because this is
for modules which you do not depend on. Often they depend on you.
MooseX::Blah depends on Moose, so Moose declares conflict with versions
of MooseX::Blah it breaks.
This requires Moose maintainers to know about all the things their
releases break. Have you considered reversing the directionality so
MooseX::Blah knows about the things which break it? That seems like a
more likely scenario to me, and lets the right maintainer control the
"conflicts" relationship.

-Mike
Jan Dubois
2013-04-15 18:21:57 UTC
Permalink
Post by Michael G. Schwern
Why we need this, why you can't do it with "requires" is because this is
for modules which you do not depend on. Often they depend on you.
MooseX::Blah depends on Moose, so Moose declares conflict with versions
of MooseX::Blah it breaks.
This requires Moose maintainers to know about all the things their releases
break. Have you considered reversing the directionality so MooseX::Blah
knows about the things which break it? That seems like a more likely
scenario to me, and lets the right maintainer control the "conflicts"
relationship.
Ideally, you would have this information in both locations, as users
can install in either sequence:

1) New install: MooseX::Blah requires Moose, so Moose will install
first. Moose cannot warn because MooseX::Blah isn't installed yet.
So MooseX::Blah needs to warn during installation.

2) Older version of Moose and latest version of MooseX::Blah already
installed. User updates Moose. Moose should warn that it will break
already installed MooseX::Blah.

I've run into this scenario with DBI and DBD::AnyData before, where
only DBI warns about the conflict, but DBD::AnyData doesn't:

https://rt.cpan.org/Public/Bug/Display.html?id=83293

Cheers,
-Jan
Michael G. Schwern
2013-04-15 18:37:21 UTC
Permalink
Post by Mike Doherty
This requires Moose maintainers to know about all the things their
releases break. Have you considered reversing the directionality so
MooseX::Blah knows about the things which break it? That seems like a
more likely scenario to me, and lets the right maintainer control the
"conflicts" relationship.
It's a good idea to reverse the relationship. In this case it doesn't
work out.

* I believe that was the confusion at the Lancaster Consensus,
that conflict was a way to express "I can use Parent >= 1.23 but not
1.69". That is already covered by the "requires" relationship and
version ranges.

requires:
Parent: >= 1.23, != 1.69

* In order to find out what modules Parent conflicts with,
necessary when installing Parent, a CPAN shell would have to
iterate through every module's metadata. [1]

* Parent can test its dependents before Parent releases, but Child
cannot. Parent has the opportunity to test and
mark its conflicts at release time so at least CPAN shells can
protect users of Child from upgrading Parent and breaking Child.
[2]


[1] It would be nice if we had a reliable meta API for that, but we
don't at the moment.

[2] This should contain the assumption "in an automated fashion". Sure,
Parent and Child can keep in close communication with each other, but
this does not scale. When you're a heavily depended on module such as
File::Spec, Test::More, Moose, DBIx::Class, Module::Build,
ExtUtils::MakeMaker or version you simply have too many dependents and
are too many levels removed.
Jens Rehsack
2013-04-15 18:06:52 UTC
Permalink
Post by Michael G. Schwern
TL;DR version...
IMO we only need to clarify what "conflicts" means and what actions CPAN
tools should take.
We talked in the Consensus Dome about the need for and meaning of the
"conflicts" relationship in the CPAN::Meta::Spec.
https://metacpan.org/module/CPAN::Meta::Spec#Prereq-Spec
IIRC the conclusion was...
* We need it.
* It's not clear what it means. (I don't recall what the confusion was)
The difference between "A conflicts with B op VER" and "A breaks B op
VER" and "A superflous B".
Post by Michael G. Schwern
* Let's see what Debian does.
Or MacPorts, HomeBrew or pkgsrc :P

Jens
Michael G. Schwern
2013-04-17 18:43:31 UTC
Permalink
Post by Jens Rehsack
Post by Michael G. Schwern
TL;DR version...
IMO we only need to clarify what "conflicts" means and what actions CPAN
tools should take.
We talked in the Consensus Dome about the need for and meaning of the
"conflicts" relationship in the CPAN::Meta::Spec.
https://metacpan.org/module/CPAN::Meta::Spec#Prereq-Spec
IIRC the conclusion was...
* We need it.
* It's not clear what it means. (I don't recall what the confusion was)
The difference between "A conflicts with B op VER" and "A breaks B op
VER" and "A superflous B".
IIRC those meant...

"A conflict B" is A and B cannot be on the machine at the same time.
For example, they're both http servers and need the same port. I can't
think of an example where CPAN has needed that for modules.

"A breaks B" is if A is installed B will break. This is what we need on
CPAN for things like Test::Builder breaks Test::Class < 0.39.

"A superfluous B" is if A is installed B is no longer necessary.
Usually called "obsoletes". This is mostly useful if you rename a
package, though I'd rather that was made more explicit in the meta data.
Most of the use cases I can think of are better handled by the
installed modules database and CPAN distribution meta data.
Post by Jens Rehsack
Post by Michael G. Schwern
* Let's see what Debian does.
Or MacPorts, HomeBrew or pkgsrc :P
Whatever packaging system I may actually use, I go to Debian first
because they extensively document this sort of thing, both the meanings
and the rationales.

Let's have a look at what the others do...

MacPorts has a conflicts tag, but I can't find the docs. The only
mention of conflicts I can find in the MacPorts manual is "variant X
conflicts Y" but there's no explanation what that means.
https://www.macports.org/guide/chunked/reference.variants.html
It's not mentioned in the dependencies section.
https://www.macports.org/guide/chunked/reference.dependencies.html

pkgsrc has CONFLICTS=Some-Name-[0-9]* essentially a regex.
http://www.netbsd.org/docs/pkgsrc/fixes.html#conflicts
All they say is the "package may conflict with other packages a user
might already have installed on his system"

Homebrew has an undocumented "conflicts_with".
https://github.com/mxcl/homebrew/blob/master/Library/Homebrew/formula.rb

rpm has "Conflicts" and "BuildConflicts" which is only defined as "where
one package conflicts with a capability provided by another" which isn't
very useful. rpm also has "Obsoletes" "where one package obsoletes
capabilities provided by another, usually used when a package changes
name and the new package obsoletes the old name".
https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-advanced-packaging.html

It doesn't shine much new light on the issue except that package
management systems agree, you need a conflict tag.
Jens Rehsack
2013-04-18 08:26:23 UTC
Permalink
Post by Michael G. Schwern
Post by Jens Rehsack
Post by Michael G. Schwern
TL;DR version...
IMO we only need to clarify what "conflicts" means and what actions CPAN
tools should take.
We talked in the Consensus Dome about the need for and meaning of the
"conflicts" relationship in the CPAN::Meta::Spec.
https://metacpan.org/module/CPAN::Meta::Spec#Prereq-Spec
IIRC the conclusion was...
* We need it.
* It's not clear what it means. (I don't recall what the confusion was)
The difference between "A conflicts with B op VER" and "A breaks B op
VER" and "A superflous B".
IIRC those meant...
"A conflict B" is A and B cannot be on the machine at the same time.
For example, they're both http servers and need the same port. I can't
think of an example where CPAN has needed that for modules.
Or - maybe - an ancient distribution (META spec is per dist)
is mis-using a module name, and my shiny-new-dist uses the same.
This might be a candidate for superfluous, but doesn't need to...
Post by Michael G. Schwern
"A breaks B" is if A is installed B will break. This is what we need on
CPAN for things like Test::Builder breaks Test::Class < 0.39.
Yes.
Post by Michael G. Schwern
"A superfluous B" is if A is installed B is no longer necessary.
Usually called "obsoletes". This is mostly useful if you rename a
package, though I'd rather that was made more explicit in the meta data.
Most of the use cases I can think of are better handled by the
installed modules database and CPAN distribution meta data.
Looking to XML-LibXML, that extra knowlegde of consequences of
splitting and remerging dists could had helped to avoid a lot
of confusion around XML::LibXML::XPathContext.
Post by Michael G. Schwern
Post by Jens Rehsack
Post by Michael G. Schwern
* Let's see what Debian does.
Or MacPorts, HomeBrew or pkgsrc :P
Whatever packaging system I may actually use, I go to Debian first
because they extensively document this sort of thing, both the meanings
and the rationales.
I don't know how Debian docs are - I see only the results ;)
Post by Michael G. Schwern
Let's have a look at what the others do...
I suggest we're asking some of the developers there ...
Post by Michael G. Schwern
pkgsrc has CONFLICTS=Some-Name-[0-9]* essentially a regex.
http://www.netbsd.org/docs/pkgsrc/fixes.html#conflicts
All they say is the "package may conflict with other packages a user
might already have installed on his system"
We also allow "patterns" like "scrnsaverproto<1.2.0".
That's why I recommended to look what "the others do" - not
what is somewhere described ;)

...

Cheers,
Jens

Loading...