Differences between revisions 13 and 38 (spanning 25 versions)
Revision 13 as of 2009-12-18 15:00:01
Size: 3708
Editor: ?MikeHommey
Comment:
Revision 38 as of 2020-04-04 16:06:11
Size: 6429
Editor: eriberto
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
## page was renamed from Renaming_a_Package
<<TableOfContents()>>
Line 2: Line 5:
Line 3: Line 7:

== Transition package method ==
Line 6: Line 12:
== Method A ==
Assume that the last upstream version of the old package "oldPkg" was 1.5 and the package was renamed to "newPkg" for version 2.0.
Assume that the last upstream version of the old package "oldname" was 1.5 and the package was renamed to "newname" for version 2.0.
Line 12: Line 17:
 Package: oldPkg
 Depends: newPkg
 Package: oldname
 Depends: newname, ${misc:Depends}
Line 15: Line 20:
 Description: transitional dummy package  Priority: optional
 Section: oldlibs
 Description: transitional package
  This is a transitional package. It can safely be removed.
Line 17: Line 25:
This entry defines the binary dummy package. It will get version 2.0-1 and automatically be pulled in by an {{{apt-get dist-upgrade}}} if an earlier version of oldPkg was already installed.
Line 19: Line 26:
The package only installs the mandatory files in /usr/share/doc/oldPkg. This entry defines the binary dummy package. It will get version 2.0-1 and automatically be pulled in by an {{{apt-get dist-upgrade}}} if an earlier version of oldname was already installed. Be sure to use the term "transitional package" in the long description as various tools (DebianPkg:lintian, DebianPkg:deborphan, DebianPkg:debfoster, etc.) look for exactly those two words.
Line 21: Line 28:
Since it depends on newPkg, it also installs the new package. The package only installs the mandatory files in /usr/share/doc/oldname
and possibly some compatibility symlinks, see below.
Line 23: Line 31:
Note that the package does not contain any architecture specific files anymore and therefore the Architecture is set to "All", even if it was "Any" before. Since it depends on newname, it also installs the new package.

Note that the package does not contain any architecture specific files anymore and therefore the Architecture is set to '''all''', even if it was '''any''' before.

If you set the section of the dummy package to oldlibs, tools like DebianPkg:deborphan will suggest removal of the package once there aren't any more reverse-dependencies installed. All transitional, including non-library, packages should be put in this section, even though it's pretty much a misnomer, but there is currently no better section for this (see https://lintian.debian.org/tags/transitional-package-should-be-oldlibs-optional.html).
Line 28: Line 40:
 Package: newPkg
 Provid
es: oldPkg
 Replaces: oldPkg (<< 2.0-1)
 Conflicts: oldPkg (<< 2.0-1)
 Package: newname
 Replaces: oldname (<< 2.0-1~)
 Breaks: oldname (<< 2.0-1~)
 …
Line 33: Line 45:
The {{{Provides:}}} entry makes sure that reverse dependencies do net get broken so that other packages which depend on the old unversioned package name can still be installed.
Line 35: Line 46:
Please make sure not to forget the Debian-revision of the first renamed version which entered/will enter the archive in the Replaces: and Conflicts: line unless you want to stumble across bugs like [[DebianBug:397993|#397993]]. You can also add a versioned {{{Provides:}}} entry if it is appropriate (for example when all interfaces are provided), which will help to satisfy any versioned reverse dependencies, and will allow users to remove the transitional package.
Line 37: Line 48:
== Method B (NOT CURRENTLY APPLICABLE) ==
There is an even more elegant way which installs less files and effectively provides a real replacement mechanism.
Please make sure that you use the proper version to break against. You must make sure that you break against all versions which still have the files in the old package. Especially if you split it between two Debian revisions, you must add a Debian revision and not only conflict against older upstream versions. (Or you will stumble across bugs like [[DebianBug:397993|#397993]]).
Line 40: Line 50:
The dummy package is defined like this in {{{debian/control}}}: Rationale: from "conflicts-with-version" Lintian tag: breaks is a weaker requirement that provides the package manager more leeway to find a valid upgrade path. Conflicts should only be used if two packages can never be unpacked at the same time, or for some situations involving virtual packages (where a version clause is not appropriate). In particular, when moving files between packages, use Breaks plus Replaces, not Conflicts plus Replaces.
Line 42: Line 52:
{{{
 Package: oldPkg
 Depends: newPkg
 Architecture: all
 Description: transitional dummy package
}}}
The dummy package only installs a link (and nothing else!) like {{{/usr/share/doc/oldPkg -> /usr/share/doc/newPkg}}}, for example with the dh_link debhelper script.
=== Compatibility symlinks ===
Line 50: Line 54:
The new package is defined like this in {{{debian/control}}}: If your new package also changes some filename-based interfaces to users or other packages, for example the package name changed because the program name changed, you might want to add compatibility symlinks. Those can either be placed in the old or the new package. If the symlink is there to stay, place it in the new package (so users can remove the transitional package and still have it). If the symlink is supposed to go away, placing it in the old package has the advantage that users can choose to have it or not (of course make sure to give the old package a proper description stating that it contains that compatibility) and that there is an easy way to see which other packages still need to change (things depending on the old name may need the compatibility symlink, while things depending on the new name must call it with the new name). As packages that have been in a release will need to have the transitional package in the next release, that extra information is especially useful if
the package never released so the transitional package can be removed soon or if there are chances the transition to the new name will take more than one release to have all reverse-dependencies fixed).
Line 52: Line 57:
{{{
 Package: newPkg
 Provides: oldPkg
 Replaces: oldPkg
 Conflicts: oldPkg (<< 2.0)
}}}
The new package installs all its necessary files, '''and the same link as the dummy package''', {{{/usr/share/doc/oldPkg -> /usr/share/doc/newPkg}}}
== Clean slate method ==
Line 60: Line 59:
Now, when an earlier version of the oldPkg is installed and the system is upgraded with {{{apt-get dist-upgrade}}}, the new version of the dummy package is installed which pulls in the new package newPkg. The link is then taken over by newPkg, so that no installed files remain for the old dummy package oldPkg. {{{dpkg}}} is aware of this situation and notices that oldPkg is now completely replaced. This method consists in switching to the new name without using a transitional package. It can imply renaming the binary package within the existing source (and possibly renaming the source package) or creating a new source package (which would require a request removal of the old source package). And let the new package '''Provides''', '''Replaces''' and '''Conflicts''' the old package, ideally by using versioned Provides to fulfill versioned dependencies when targeting >= Debian Stretch.
Line 62: Line 61:
However, through a bug in dpkg, it tries to configure the old dummy package at a later time, which fails because the package was already removed. '''Thus, at least for etch, this approach can not be used'''. (Still doesn't work for sid as of today -- 2008-01-12. GregorHerrmann ; It seems to be working properly since at least Lenny -- 2009-12-18. MikeHommey) This should be used for example for any non-leaf packages that are only ever installed by other packages depending on it. Because in that case the only thing needed will be for the reverse-dependencies to start depending on the new package.

But this method has disadvantages:

 * Cannot be used for packages that are used in build dependencies, as several build tools (like DebianPkg:sbuild) do not support virtual packages in those dependencies by design, to guarantee deterministic builds.
 * Most package managers (including APT, as of 2011-02-21) do not know to replace the old with the new one and will only use the new package if it is installed for some other reason.

== Disappearing package method ==

This page used to describe a method trying to get rid of the transitional package automatically by removing all it files. If you are interested why this does not work at all (yet?), take a look at the history of this page.
Line 65: Line 73:
 . CategoryDeveloper
CategoryDeveloper CategoryPackaging

Why?

Sometimes, it is necessary for a package to get a new name. Although this should rather seldom be the case, there are some situations when it makes sense, for example when the name of the upstream application changes. Of course an apt-get dist-upgrade should still seamlessly upgrade the package, best by completely removing the old package and installing the new one as a replacement.

Transition package method

Basically, the solution is to define a binary dummy package with the same name as the old package in the control file of the new package. The new source package takes over the binary dummy package, and the old source package, which is then binaryless, will be cleaned up by rene, an archive cleanup tool.

Assume that the last upstream version of the old package "oldname" was 1.5 and the package was renamed to "newname" for version 2.0.

Then, the dummy package is defined like this in debian/control:

 Package: oldname
 Depends: newname, ${misc:Depends}
 Architecture: all
 Priority: optional
 Section: oldlibs
 Description: transitional package
  This is a transitional package. It can safely be removed.

This entry defines the binary dummy package. It will get version 2.0-1 and automatically be pulled in by an apt-get dist-upgrade if an earlier version of oldname was already installed. Be sure to use the term "transitional package" in the long description as various tools (lintian, deborphan, debfoster, etc.) look for exactly those two words.

The package only installs the mandatory files in /usr/share/doc/oldname and possibly some compatibility symlinks, see below.

Since it depends on newname, it also installs the new package.

Note that the package does not contain any architecture specific files anymore and therefore the Architecture is set to all, even if it was any before.

If you set the section of the dummy package to oldlibs, tools like deborphan will suggest removal of the package once there aren't any more reverse-dependencies installed. All transitional, including non-library, packages should be put in this section, even though it's pretty much a misnomer, but there is currently no better section for this (see https://lintian.debian.org/tags/transitional-package-should-be-oldlibs-optional.html).

The new package is defined like this:

 Package: newname
 Replaces: oldname (<< 2.0-1~)
 Breaks: oldname (<< 2.0-1~)

You can also add a versioned Provides: entry if it is appropriate (for example when all interfaces are provided), which will help to satisfy any versioned reverse dependencies, and will allow users to remove the transitional package.

Please make sure that you use the proper version to break against. You must make sure that you break against all versions which still have the files in the old package. Especially if you split it between two Debian revisions, you must add a Debian revision and not only conflict against older upstream versions. (Or you will stumble across bugs like #397993).

Rationale: from "conflicts-with-version" Lintian tag: breaks is a weaker requirement that provides the package manager more leeway to find a valid upgrade path. Conflicts should only be used if two packages can never be unpacked at the same time, or for some situations involving virtual packages (where a version clause is not appropriate). In particular, when moving files between packages, use Breaks plus Replaces, not Conflicts plus Replaces.

If your new package also changes some filename-based interfaces to users or other packages, for example the package name changed because the program name changed, you might want to add compatibility symlinks. Those can either be placed in the old or the new package. If the symlink is there to stay, place it in the new package (so users can remove the transitional package and still have it). If the symlink is supposed to go away, placing it in the old package has the advantage that users can choose to have it or not (of course make sure to give the old package a proper description stating that it contains that compatibility) and that there is an easy way to see which other packages still need to change (things depending on the old name may need the compatibility symlink, while things depending on the new name must call it with the new name). As packages that have been in a release will need to have the transitional package in the next release, that extra information is especially useful if the package never released so the transitional package can be removed soon or if there are chances the transition to the new name will take more than one release to have all reverse-dependencies fixed).

Clean slate method

This method consists in switching to the new name without using a transitional package. It can imply renaming the binary package within the existing source (and possibly renaming the source package) or creating a new source package (which would require a request removal of the old source package). And let the new package Provides, Replaces and Conflicts the old package, ideally by using versioned Provides to fulfill versioned dependencies when targeting >= Debian Stretch.

This should be used for example for any non-leaf packages that are only ever installed by other packages depending on it. Because in that case the only thing needed will be for the reverse-dependencies to start depending on the new package.

But this method has disadvantages:

  • Cannot be used for packages that are used in build dependencies, as several build tools (like sbuild) do not support virtual packages in those dependencies by design, to guarantee deterministic builds.

  • Most package managers (including APT, as of 2011-02-21) do not know to replace the old with the new one and will only use the new package if it is installed for some other reason.

Disappearing package method

This page used to describe a method trying to get rid of the transitional package automatically by removing all it files. If you are interested why this does not work at all (yet?), take a look at the history of this page.


CategoryDeveloper CategoryPackaging