Debian JavaScript maintainers best practice for repacking

Sometimes you have to repack the upstream tarball to remove some stuff. There are several workflows for that, like manually editing the tarball, the git-buildpackage dfsg_clean branch, cleanup scripts ...

The best practice at the moment is to use the Files-Excluded field in debian/copyright. Here is how you do that.

1. Choose a repack suffix

The version string has this format: [epoch:]upstream_version[-debian_revision]. Repacked tarballs are denoted by adding a repack suffix to the upstream_version part of the version string. The repack suffix has this format: [repack_separator]repack_reason[repack_version]. For example +dfsg, where + is repack_separator and dfsg is repack_reason and repack_version is not specified. So a package name like node-parse-glob_3.0.4-1 becomes node-parse-glob_3.0.4+dfsg-1.

The common repack reasons are:

- dfsg (referring to the Debian Free Software Guidelines), used when non-free stuff is removed, such as a minified ?JavaScript file which triggers the source-is-missing Lintian error or the copyrighted ICC profile in a test picture.

- ds ("Debian Source"), used when embedded 3rd-party libraries or the upstream debian directory are removed.

The repack_version is a small integer, used to version the repacks as in dfsg, dfsg1, dfsg2 ...

The repack_separator is optional and only serves to improve legibility: some people like to append repack_reason[repack_version] without separator. Based on the admissible non-alphanumerics characters in the upstream_version, and excluding . - : (full stop, hyphen and colon) because they have other meanings, possible separators are + ~ (plus and tilde).

The most commonly used separator is +. If you separate the repack suffix with +, it means that you believe that whatever upstream does with the tarball for this upstream version, you'll always have to repack. You can decide to stop repacking only when upstream releases a new tarball with a new, higher upstream version (but you can always fix it with the epoch).

The ~ is special because it sorts before anything, and is commonly used for pre-releases. So the consequences of using ~ as repack_separator are:

- When a dependency on this package is specified, it has to be >= x.y.z~ as opposed to commonly used >= x.y.z.

- If upstream re-releases the same version but with the DFSG violation fixed, or if we change the rules and the offending file was now "free", then you can just drop the ~dfsg and release it again with the same upstream_version: the new version will be "higher".

In the following, let's assume the chosen repack suffix is +dfsg.

2. Mark the files to exclude

Append to the first section of debian/copyright (no newline inbetween) a single Files-Excluded field with the list of all excluded files:

Files-Excluded: non_dfsg_compliant_file.extension
Comment: reason for exclusion

The Comment field with the reason for exclusion is mandatory as per Debian Policy 12.5.

In the Files-Excluded field you can use the same simplified shell glob syntax of the Files field (see Machine-readable debian/copyright file specification), list files etc.

If more than one file/globbing pattern is required, you can use:

Files-Excluded:
    file_a
    file_b
    file_c
    ...
Comment: The following files were removed because
  file_a: Binary with no source
  file_b: non-free license
  file_c: just cruft
  ...

3. Do the actual repack

Add the chosen repack suffix to debian/watch params, for example:

repacksuffix=+dfsg,\
repack,compression=xz,\

Note: xz offers better compression. Seean example watch file.

Remove the packagename_X.Y.Z.orig.tar.gz tarball and do

uscan --force-download

Thanks to the magic of uscan, this command will download the upstream tarball, remove the files are save it as packagename_x.y.x+dfsg.orig.tar.gz. No need to edit the ...orig.tar, remove the file and save it manually as ...+dfsg.orig.tar.gz.

Now set aside the uncommitted changes to the git repo (git stash) and import the repacked tarball:

gbp import-orig --pristine-tar ../packagename_X.Y.Z+dfsg.orig.tar.gz

Now restore the changes to debian/copyight and debian/watch (git stash apply) and edit the changelog - the version in the 1st line should read:

packagename (X.Y.Z+dfsg-1) unstable; urgency=low

Finally commit your changes with:

git commit -am 'repack to ...'

You can also see node-levn and node-loose-envify as examples.

Sources

- Based on a tip from Jérémy Lal, with contributions by Pirate Praveen, Ross Gammon and Jonas Smedegaard.

- https://pkg-perl.alioth.debian.org/howto/repacking.html

- https://wiki.debian.org/Diaspora/Packaging/origsource