Home / Alt manpages / dpkg-scansources(1)

  • dpkg-scansources(1)
  • User command
  • linux

Build a Debian Sources Index with dpkg-scansources

dpkg-scansources reads a tree of .dsc files and writes the Sources index a source repository actually needs. It matters the moment someone asks to rebuild your package from scratch. The examples use dpkg-scansources from dpkg-dev 1.22.6ubuntu6.6, which reports dpkg version 1.22.6. Allow about fifteen minutes if your .dsc files and override data are already in place.

The command reads .dsc files and writes the index to standard output. It needs no root, and it never modifies the scanned directory. You need a shell, readable source-package files, and enough space for the generated index and any compressed copy.

1. Confirm the installed command

Check the package and executable before building anything. A read-only checkpoint:

$ dpkg-query -W -f='${Package} ${Version}\n' dpkg-dev
dpkg-dev 1.22.6ubuntu6.6
$ command -v dpkg-scansources
/usr/bin/dpkg-scansources
$ dpkg-scansources --version
Debian dpkg-scansources version 1.22.6.

The synopsis is dpkg-scansources [options] binary-dir [override-file [path-prefix]] > Sources. The name binary-dir is easy to misread: it is the tree the scanner searches for source .dsc files, not the place to point it at .deb files.

2. Scan a source directory into Sources

Move to the root of the archive you intend to publish, then set a relative path to its source tree, one your normal account can already read:

$ cd /srv/debian-archive
$ SOURCE_TREE='pool'
$ dpkg-scansources "$SOURCE_TREE" > Sources

The output is a set of control-style stanzas. Each one describes a source package: its .dsc file, checksums, and every other file that .dsc lists. Stanzas are normally sorted by source package name. Inspect the result before you publish it:

$ sed -n '1,80p' Sources
Format: 3.0 (quilt)
Package: example
Binary: example
Architecture: all
Version: 1.0-1
...
$ test -s Sources && echo 'Sources is non-empty'
Sources is non-empty

An empty file usually means the tree does not actually contain readable files ending in .dsc. A command that exits cleanly with no matching source files is still not a useful repository index.

3. Add the archive path prefix

The optional path-prefix is prepended literally to every generated Directory: field. Add a trailing slash if you want it separated cleanly from the existing path. Here, an override file is passed positionally alongside an archive-level prefix:

$ dpkg-scansources "$SOURCE_TREE" /dev/null 'archive/' > Sources
$ awk '/^Directory:/{print}' Sources | head
Directory: archive/pool/main/e/example

/dev/null stands in as an empty override file here. Be deliberate about the prefix: it becomes part of the paths APT uses to find source files, so a build-time staging directory like /tmp/build/pool should never leak into a public index by accident. A relative scan path also makes the whole thing easier to reason about than an absolute temporary one.

Checkpoint

Compare one Directory: value against the path your web server or local repository will actually serve. If they do not join up to the real file location, fix the prefix and regenerate Sources.

4. Apply a binary override file when needed

An override file can add archive policy fields such as priority and section, and replace maintainer information. Its ordinary format is whitespace-separated: package, priority, section, then optional maintainer information. Create one in your repository's configuration area:

$ cat repository-override
example optional admin
$ dpkg-scansources "$SOURCE_TREE" repository-override 'archive/' > Sources

The matching binary package can then contribute Priority: optional and Section: admin to the generated stanza. The override is indexed by binary package, not source package directly. When one .dsc produces several binaries, this implementation uses the highest priority it finds for the source stanza, and the first listed binary for any maintainer override. Treat that as an implementation detail worth knowing, especially for multi-binary source packages.

Warning

Override files may be compressed, and their exact maintainer-substitution syntax lives in deb-override(5). Never put credentials or private contact data into an index destined for public serving.

5. Separate source section overrides

The -s or --source-override option selects a two-field source override file: source package name, then section:

$ cat source-override
example admin
$ dpkg-scansources --source-override source-override "$SOURCE_TREE" repository-override 'archive/' > Sources

Blank lines and comments are ignored. If a source package appears in both the binary override and this file, the source override wins for section. Supply a normal override file and skip --source-override, and dpkg-scansources looks for that same file with .src appended as the default source override name. Spell this out explicitly in scripts where reproducibility matters.

6. Choose sorting and supplementary overrides

Keep the default sorting unless another tool depends on input order. --no-sort leaves stanzas unsorted, so output tracks directory traversal instead of package name:

$ dpkg-scansources --no-sort "$SOURCE_TREE" > Sources.unsorted
$ cmp -s Sources Sources.unsorted || echo 'ordering or content differs'

The -e or --extra-override option reads supplementary overrides in the format documented by deb-extra-override(5). Use it only when archive policy genuinely calls for that extra input, and keep every override file under review, since they change metadata without touching the source package's own .dsc.

7. Prepare the index for APT

Keep the uncompressed file while checking it, then build the compressed index alongside:

$ gzip -c Sources > Sources.gz
$ gzip -t Sources.gz
$ ls -l Sources Sources.gz

APT generally expects Sources.gz for a served repository, and ignores an uncompressed Sources outside local file:// access. Compression is a separate step from dpkg-scansources itself, so a clean scan alone proves nothing about whether an APT client can fetch it.

Warning

Never overwrite a known-good index in place during a live repository update. Generate into a temporary name, validate it, then use your repository's normal atomic deployment procedure. To undo this guide's example, remove the newly generated Sources, Sources.gz, or test output, once you confirm no other repository process shares those files. The source tree and its .dsc files never change.

Common failure checks

  • No packages appear. Run find "$SOURCE_TREE" -type f -name '*.dsc' -print to check the search tree and permissions. The command wants source descriptions, not package binaries.
  • APT cannot fetch a source file. Inspect Directory: and each filename in Sources. A wrong path-prefix usually points the client at a path that is valid on the build host but not at the archive root.
  • Metadata looks wrong. Rerun without overrides, then add the ordinary, extra, and source override files one at a time, isolating policy input from the .dsc content itself.
  • Output changes between runs. Check for --no-sort, a changing scanned directory, or an input .dsc being edited underneath you. Sorted output is easier to review.
  • Permission denied. Fix ownership or read permissions on the repository tree through your normal admin process. Do not run the scanner as root just to paper over a permission problem.

Done means

  • Tool version identified. dpkg-scansources --version matches the installed dpkg-dev.
  • Sources contains the right stanzas, for the readable .dsc files you intended.
  • Every Directory: field points into the layout that will actually be served.
  • Override files stay reviewed and explicit, kept separate from source-package data.
  • Sources.gz passes gzip -t before it goes anywhere near APT.