Imprimir post Imprimir post

How to write a good debian/watch easily

Posted by Eriberto on out 7, 2013 in Debian, Sistema Operacional |

Short URL:



  • Updated the output of the watch command to a new format.


  • Added a section about ‘fake watches’.
  • Changed all versions from ‘version=3’ to ‘version=4’.


  • Added a section about ‘merging uversionmangle and dversionmangle’.

Writing a good watch file for a Debian package is simple. However, several maintainers don’t know how to make watches for non trivial sites as Google Pages or Github. Then, my objective is  teach a bit about debian/watch.

A conventional debian/watch has two lines: version and site watcher. An example for a simple and trivial site:


The first line is compulsory and says to Debian watch system (in Debian official project sites) what is the used version and how to behave. Currently, this line is always “version=4”. Then, forget this. The last line (site watcher) is responsible for scan the site, searching for versions of the codes (tarballs). This line was made using a simple observation and regular expressions (Perl regular expressions). So, in the upstream site (, we can point a download shortcut to see the file URL. Please, see the picture below that shows this situation:


PS: to get a summary about Perl regular expressions, go to the site

Is possible to see the web link and we will try to use it. We should change the version from 0.7.3 to (.+). In Perl regular expressions, .+ is treated as anything, except newline, one or more times. Then, we want monitor pcapfix-ANYTHING.tar.gz. The brackets are used to alert the watch system that we are considering as version what can be seen among them. The final situation is\.tar\.gz. Note that the last part (after the last slash) has a regexp and the points was protected by backslashes to avoid an interpretation as any character.

PS: Some people like to use (.*). However, in regular expressions, this is treated as nothing or anything. Then,*)\.tar\.gz will match with pcapfix-.tar.gz and you should avoid this.

To test a watch file, we need run ‘uscan command’ from upstream code place (outside of the debian directory, but it must exist; debian/changelog and debian/watch are fundamental to test because uscan will get the local version from the first and compare with results generated by the last).

$ uscan --verbose --report

The result:

uscan info: uscan (version 2.21.4) See uscan(1) for help
uscan info: Scan watch files in .
uscan info: Check debian/watch and debian/changelog in .
[...] (0.7.3) index=0.7.3-1 (0.7.3) index=0.7.3-1 (0.7.2) index=0.7.2-1 (0.7.2) index=0.7.2-1 (0.7.1) index=0.7.1-1 (0.7.1) index=0.7.1-1 (0.7) index=0.7-1 (0.7) index=0.7-1 (0.6) index=0.6-1 (0.6) index=0.6-1 (0.5) index=0.5-1 (0.5) index=0.5-1 (0.4) index=0.4-1 (0.4) index=0.4-1 (0.3) index=0.3-1 (0.3) index=0.3-1 (0.2-real) index=0.2-real-1 (0.2-real) index=0.2-real-1 (0.1) index=0.1-1 (0.1) index=0.1-1 
uscan info: Newest version of pcapfix on remote site is 0.7.3, local version is 0.7.3
uscan info: => Package is up to date from:
uscan info: Scan finished

How you can see, all versions were shown and the package is updated. This was a very easy work. However, we can use another technique, which is more sophisticated. This technique is useful for sites more complex as Google Pages and Github.

The site shown in the last picture has web links and we can collect these web links. To do it, initially, we must use the URL of the site that has the links and (.*). Note that, this time, (.*) will be used to a temporary action only. An example:

version=4 (.*)

After the uscan command, the output was:

eriberto@canopus:/tmp/pcapfix-0.7.3$ uscan --verbose --report
uscan info: Scan watch files in .
uscan info: Check debian/watch and debian/changelog in .
uscan info: Found the following matching hrefs on the web page (newest first):
[...] (pcapfix-0.7.tar.gz) index=pcapfix-0.7.tar.gz-1 (pcapfix-0.7.tar.gz) index=pcapfix-0.7.tar.gz-1 (pcapfix-0.7.3.tar.gz) index=pcapfix-0.7.3.tar.gz-1 (pcapfix-0.7.3.tar.gz) index=pcapfix-0.7.3.tar.gz-1 ( ( (pcapfix-0.7.2.tar.gz) index=pcapfix-0.7.2.tar.gz-1 (pcapfix-0.7.2.tar.gz) index=pcapfix-0.7.2.tar.gz-1 ( ( (pcapfix-0.7.1.tar.gz) index=pcapfix-0.7.1.tar.gz-1 (pcapfix-0.7.1.tar.gz) index=pcapfix-0.7.1.tar.gz-1 ( ( ( ( (pcapfix-0.6.tar.gz) index=pcapfix-0.6.tar.gz-1 (pcapfix-0.6.tar.gz) index=pcapfix-0.6.tar.gz-1 ( ( (pcapfix-0.5.tar.gz) index=pcapfix-0.5.tar.gz-1 (pcapfix-0.5.tar.gz) index=pcapfix-0.5.tar.gz-1 ( ( (pcapfix-0.4.tar.gz) index=pcapfix-0.4.tar.gz-1 (pcapfix-0.4.tar.gz) index=pcapfix-0.4.tar.gz-1 (pcapfix-0.4.png) index=pcapfix-0.4.png-0 (pcapfix-0.4.png) index=pcapfix-0.4.png-0 ( ( (pcapfix-0.3.tar.gz) index=pcapfix-0.3.tar.gz-1 (pcapfix-0.3.tar.gz) index=pcapfix-0.3.tar.gz-1 (pcapfix-0.2-real.tar.gz) index=pcapfix-0.2-real.tar.gz-1 (pcapfix-0.2-real.tar.gz) index=pcapfix-0.2-real.tar.gz-1 (pcapfix-0.1.tar.gz) index=pcapfix-0.1.tar.gz-1 (pcapfix-0.1.tar.gz) index=pcapfix-0.1.tar.gz-1

Note that all web links in the page are shown. Then, we can use another format in debian/watch to filter the result:

<URL> <expression to grep>

Yes! You can ‘grep’ the result (and apply Perl regexp). The valid data was shown in brackets. Then, you may use (observe the space between URL and the regexp):

version=4 pcapfix-(.+)\.tar\.gz

See the result:

[...] (0.7.3) index=0.7.3-1 (0.7.3) index=0.7.3-1 (0.7.2) index=0.7.2-1 (0.7.2) index=0.7.2-1 (0.7.1) index=0.7.1-1 (0.7.1) index=0.7.1-1 (0.7) index=0.7-1 (0.7) index=0.7-1 (0.6) index=0.6-1 (0.6) index=0.6-1 (0.5) index=0.5-1 (0.5) index=0.5-1 (0.4) index=0.4-1 (0.4) index=0.4-1 (0.3) index=0.3-1 (0.3) index=0.3-1 (0.2-real) index=0.2-real-1 (0.2-real) index=0.2-real-1 (0.1) index=0.1-1 (0.1) index=0.1-1

Another example. Please, see the site, that provides the game Pacman for Console (pacman4console in Debian). The picture below shows a link in the site:


The first idea is to use something like this:




But the results are:

eriberto@canopus:/tmp/pacman4console-1.2$ uscan --verbose --report
uscan info: Requesting URL:
uscan info: Matching pattern:
uscan warn: In debian/watch no matching files for watch line\.tar\.gz\?attredirects=0
uscan info: Scan finished


eriberto@canopus:/tmp/pacman4console-1.2$ uscan --verbose --report
uscan info: Requesting URL:
uscan info: Matching pattern:
uscan warn: In debian/watch no matching files for watch line\.tar\.gz.*
uscan info: Scan finished

Then, we must use the URL scan method. In a first time use:

version=4 (.*)

The output:

eriberto@canopus:/tmp/pacman4console-1.2$ uscan --verbose --report
[...] (pacman-1.2.tar.gz?attredirects=0) index=pacman-1.2.tar.gz?attredirects=0-1 (pacman-1.2.tar.gz?attredirects=0) index=pacman-1.2.tar.gz?attredirects=0-1 (pacman-1.2.ebuild?attredirects=0) index=pacman-1.2.ebuild?attredirects=0-0 (pacman-1.2.ebuild?attredirects=0) index=pacman-1.2.ebuild?attredirects=0-0 (pacman-1.1.tar.gz?attredirects=0) index=pacman-1.1.tar.gz?attredirects=0-1 (pacman-1.1.tar.gz?attredirects=0) index=pacman-1.1.tar.gz?attredirects=0-1 (pacman-1.0.tar.gz?attredirects=0) index=pacman-1.0.tar.gz?attredirects=0-1 (pacman-1.0.tar.gz?attredirects=0) index=pacman-1.0.tar.gz?attredirects=0-1 (pacman-1-1.png?attredirects=0) index=pacman-1-1.png?attredirects=0-0 (pacman-1-1.png?attredirects=0) index=pacman-1-1.png?attredirects=0-0

Now we can make a ‘grep’ based in or, simply, .*pacman-1.2.tar.gz.* (it is a grep, man!). Four solutions, among others, are:



version=4 .*/pacman-(.+)\.tar\.gz.*

version=4 .*pacman-(.+)\.tar\.gz.*

For me, the last option is the best.

PS: all examples are available in plain text at

See the result when using a solution:

eriberto@canopus:/tmp/pacman4console-1.2$ uscan --verbose --report
[...] (1.2) index=1.2-1 (1.2) index=1.2-1 (1.1) index=1.1-1 (1.1) index=1.1-1 (1.0) index=1.0-1 (1.0) index=1.0-1

To Github, I will use as example the project homed at In Github there is a link named release. See the picture below.


If you click over release link, a new page will open and it will show Realeases and Tags links; both have web links that refers to the versions of the releases as, e.g., v0.16. Then, you can use:

version=4 archive/refs/tags/v(.+)\.tar\.gz

PS: remember that you must use ‘ (.*)’ for initial scan.

The result:

eriberto@canopus:netmate-0.16$ uscan --verbose --report
[...] (0.16) index=0.16-1 (0.16) index=0.16-1 (0.2.0) index=0.2.0-1 (0.2.0) index=0.2.0-1 (0.1.9) index=0.1.9-1 (0.1.9) index=0.1.9-1 (0.1.8) index=0.1.8-1 (0.1.8) index=0.1.8-1 (0.1.7) index=0.1.7-1 (0.1.7) index=0.1.7-1 
uscan info: Looking at $base = with
$filepattern = archive/refs/tags/v(.+)\.tar\.gz found
$newfile =
$newversion = 0.16
$lastversion = 0.16
uscan info: Matching target for downloadurlmangle:
uscan info: Upstream URL(+tag) to download is identified as
uscan info: Filename (filenamemangled) for downloaded file: v0.16.tar.gz
uscan info: Newest version of netmate on remote site is 0.16, local version is 0.16
uscan info: => Package is up to date from:
uscan info: Scan finished

As a new example, go to the site Consider that you need to check all Linux versions and they are using tar.bz2, tar.gz and tar.xz extensions. Thus, you need to create a rule with a non-capturing group (?:) feature. You can see an example of this below.

version=4 myprogram-(.+)\.tar\.(?:bz2|gz|xz)

Note that (?:bz2|gz|xz) can be used to match lines that have bz2 or gz or xz, but it must be ignored in result. Another solution to this case is:


If needed, you can select between two or more possibilities. Please, see There are two name patterns to the versions. The respective watch is:

version=4 .*/(?:diskscan-)?(\d\S+)\.tar\.(?:bz2|gz|xz)

Note that was used (?:diskscan-)? to make diskscan- optional in results. The \d mean ‘one digit’, as 0-9. The \S is any chracter different of space. See the site about Perl RegEx.

Another resource available is the uversionmangle and dversionmangle. These words can be used to modify the vision of the system over the file names. The uversionmangle (u=upstream) is used for upstream site and dversionmangle (d=Debian) is for local file. As an example, consider again the site and local names using ‘+dfsg-1’ suffix, being that ‘-1’ can be another number as ‘-2.3’. Then, a initial idea of the watch is:

version=4 myprogram-(.+)\.tar\.(?:bz2|gz)

The result:

Newest version on remote site is 2.0, local version is 1.0.2-1+dfsg
 => Newer version available from
-- Scan finished

As shown, the local version is being composed by upstream version and ‘+dfsg’. We can use dversionmangle to apply a ‘sed’ command to extract ‘+dfsg’. The final solution is:

opts=dversionmangle=s/-\d\+dfsg// \ myprogram-(.+)\.tar\.(?:bz2|gz)

See the output:

Newest version on remote site is 2.0, local version is 1.0.2-1+dfsg
 (mangled local version number 1.0.2)
 => Newer version available from
-- Scan finished

Now that you understood how to works debian/watch, is the moment to say that the best combination, in general cases, is (\d\S+), instead of (.+). The \d means a digit (0-9). The \S is any non-whitespace character. Then, using (\d\S+), we will have a digit and, at least, a character as a digit, dot etc. Other best practice is accept a possible change of the file extension by the upstream. Then, is good to use \.tar\.(?:bz2|gz|xz) instead of \.tar\.bz2 or \.tar\.gz or similar. See below some examples:

version=4 .*/pacman-(\d\S+)\.tar\.(?:bz2|gz|xz).*
version=4 myprogram-(\d\S+)\.tar\.(?:bz2|gz|xz)

In version 4 of the uscan commans were introduced special strings as @ANY_VERSION@ that substitutes [-_]?(\d[\-+\.:\~\da-zA-Z]*). Please see the manpage (man uscan) for details. I will put an example below:

version=4 myprogram@ANY_VERSION@@ARCHIVE_EXT@

The uscan manpage also has several examples and explanations. There are some important information at too. The post explains about non-capturing group feature in Perl regular expressions. Another example of this is at A good tip is the URL, where you can test the results of the your Perl regular expression. Alternatively, there is but I prefer the previous link. Note that Perl RegExp is different from Posix RegExp.

I hope this help someone to write his debian/watch files.

Merging uversionmangle and dversionmangle

If needed, you can combine uversionmangle and dversionmangle using a comma as separator. See an example:

opts=uversionmangle=s/-src//,dversionmangle=s/\+dfsg// \

Another possibility is concatenate two actions into uversionmangle or dversionmangle using a semicolon. Look at this example:

opts=uversionmangle=s/-src//;s/-versao/-version/ \

Changing the subject, considering that debian/watch uses Perl regular expressions, you can take advantage of the group capture resource. Please, consider the files at There are:


The first problem is that a program version can not start with a alphabetic character. See an example using an initial debian/watch:

version=4 myprogram2-(.+)\.tar\.(?:bz2|gz|xz)

see the result:

$ uscan
[...] (beta-0.1) index=beta-0.1-1 (beta-0.1) index=beta-0.1-1 (alpha-0.1) index=alpha-0.1-1 (alpha-0.1) index=alpha-0.1-1 (0.2-beta) index=0.2-beta-1 (0.2-beta) index=0.2-beta-1 (0.2) index=0.2-1 (0.2) index=0.2-1 (0.1) index=0.1-1 (0.1) index=0.1-1

So, the right upstream version must be 0.1-alpha or 0.1-beta, instead of alpha-0.1 or beta-0.1. The second problem is for Debian 0.1 < 0.1-beta. You can analyse this fact using ‘dpkg –compare-versions’ command. Look at this example (gt = greater than; lt = less than):

$ dpkg --compare-versions 0.1-beta gt 0.1 && echo true

In Debian world, the versions can use ‘~’ or ‘+’ to establish a right hierarchy:

0.1~beta < 0.1 < 0.1+beta

So, we need to use 0.1~alpha, 0.1~beta, etc. To change the order of the upstream versions, you can use:

opts=uversionmangle=s/(alpha|beta)-([\d\.]+)/$2~$1/;s/([\d\.]+)-(alpha|beta)/$1~$2/ \ myprogram2-(.+)\.tar\.(?:bz2|gz|xz)

In s/(alpha|beta)-([\d\.]+)/$2~$1/ statement, each group delimited by brackets can be represented by $<number>. So, ‘(alpha|beta) = $1’ and ‘([\d\.]+) = $2’. Using $1 and $2, we can invert the order, putting a tilde between the groups. Try to understand the second part of the line, that is, s/([\d\.]+)-(alpha|beta)/$1~$2/. This part will act over 0.2-beta. The final result is:

[...] (0.2) index=0.2-1 (0.2) index=0.2-1 (0.2~beta) index=0.2~beta-1 (0.2~beta) index=0.2~beta-1 (0.1) index=0.1-1 (0.1) index=0.1-1 (0.1~beta) index=0.1~beta-1 (0.1~beta) index=0.1~beta-1 (0.1~alpha) index=0.1~alpha-1 (0.1~alpha) index=0.1~alpha-1

Using fake packages to provide a useful debian/watch

Fake watches can be used to avoid a false impression that you ignored the watch file by laziness and to inform an actual upstream status. This is not a Debian original resource; it was my own creation. I created three fake packages. These packages say if there no upstream site, if there no release in upstream site or if the upstream site there a package but doesn’t allow track it (using a JavaScript to block it, for example).

Fake watches are very easy to use. You can see how to use my fake watches here. There are some comments here.

That’s all. Enjoy!

Locations of visitors to this page

Tags:, , , , , , , , , , , , , , , , , , , , , , ,


Fernando Ike
out 10, 2013 at 9:27 am

It’s had another option to use watch, also to use a debian service know Githubredir. Githubredir is repository redirect of Github. I think that is unnecessary because your text is excelente. If somebody want use, it’s cool. For example, my fortune-marios package.

$cat debian/watch


out 10, 2013 at 12:32 pm

Thanks Fike!!!!

Ben Finney
jan 26, 2014 at 3:36 am

Thanks for this article.

Please note that the regex pattern “(.*)” matches the empty string; so, a pattern like “pcapfix-(.*)\.tar\.gz” will match the string “pcapfix-.tar.gz”. That’s not desirable.

Fortunately, the solution is simple: in the pattern, instead of zero or more characters, require one or more: “pcapfix-(.+)\.tar\.gz”.

The ‘uscan(1)’ manpage and other documentation avoids “.*” and similar patterns for exactly this reason.

Can you please update your article to avoid “(.*)” and instead use “(.+)” in the patterns? Thank you for helping maintainers use the tools correctly!

fev 2, 2014 at 9:54 am

Thanks a lot Ben.

You are right. Since I wrote this article I changed my concepts and I use \d\S+ now. I will update the article soon.

fev 4, 2014 at 3:27 pm

Hi all. I made a general review in the post now. Thanks!



Reload Image

Copyright © 2023 Eriberto Blog All rights reserved.
desk-mess-mirrored v theme from