Michael G. Schwern
2013-04-15 16:56:18 UTC
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.
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.