Below you can find a short introduction (or primer) to the CUDF format: it should be enough to get you started in reading or writing CUDF documents. For a more in depth explaination of CUDF syntax and semantics, you would probably want to check the full specification of CUDF 2.0.
CUDF (for Common Upgradeability Description Format) is a document format meant to describe upgrade scenarios as commonly faced by package managers in Free and Open Source Software distributions.
Typically, in an upgrade scenario, there exists:
A current package universe describing all packages known to the package manager.
A current package status denoting all currently installed packages; the package status is contained in the package universe.
A user request representing the change that a user has asked the package manager to perform.
A CUDF document grasps all relevant details of the above entities, providing a common ground to describe the input of the dependency solver components found in most package managers.
package: m4 version: 3 depends: libc6 >= 8 package: openssl version: 11 depends: libc6 >= 18, libssl0.9.8 >= 8, zlib1g >= 1 conflicts: ssleay < 1 # and so on ...
CUDF is a simple plain text format, largely inspired by RFC 2822 (commonly known for being the basis of the mailbox format). Accordingly, a CUDF document is composed by several stanzas (or paragraphs), separated by an empty line.
Comments are allowed by using # on the first column, and newlines are
in the Unix style (i.e. \n or ASCII 0x0A).
Each stanza consists of a set of key/value pairs, where keys are unique
within a given stanza. A single key/value pair denotes a property and
appears in the document as a single logical line obtained by concatenating:
the key, the string ": " (without quotes, i.e. a colon and the ASCII space
0x0A), and the value.
Keys must match the regexp "^[a-z][a-z0-9-]*$" (without quotes).
package: wesnoth version: 1 depends: libc6 >= 8, libfreetype6 >= 4, libfribidi0 >= 1, libgcc1 >= 6, libsdl-image1.2 >= 2, libsdl-mixer1.2 >= 1, libsdl-net1.2, libsdl1.2debian >= 3, libstdc++6 >= 5, libx11-6 , zlib1g >= 5, wesnoth-data = 1
Each value is, in the most general case, a single line of text. Still, to make CUDF documents more readable, long values can be split over multiple lines using line continuations. Each key/value pair line can be continued by subsequent line(s) starting with a space. All such lines taken together (the first line with the key and all continuations) form a single key value pair: the key is as usual, whereas the value is obtaining by concatenating the value on the first line with all continuations, taking care of removing the leading space of each continuation.
Each value in a stanza is in fact a typed value and you cannot generally
write arbitrary strings as values, for instance writing "foo" as a package
version will lead to a parse error. CUDF supports several types and also lets
you define your own.
Generally you can ignore the gory details by just having a look at the examples below that highlight the most important types:
-2, -1, 0, 1, 2, ...1, 2, 3, ...true, false^[a-zA-Z0-9+./@()%-]+$" : libc6, libdb4.6, libc-dev, /bin/bash (as
a virtual package in some distribution), ...python-minimal: any package called python-minimallibedac1 = 1: version 1 of package libedac1libxft2 > 1: any version of libxft2 greater than 1haskell-doc <= 2: any version of haskell-doc less than or equal to 2libz-dev != 3: any version of libz-dev other than 3postfix > 2 | exim4-base: either a version of postfix greater than 2,
or any version of exim4-baseocaml-nox, libc6 >= 6: both (any version of) ocaml-nox and a
version of libc6 greater than 6php4, apache | httpd: both (any version of) php4 and one among: (any
version of) apache and (any version of) httpd:-)|") are
not allowed:
libc6: any version of libc6f2c, cpp: any version of f2c and any version of cpp python >= 10 , python-support >= 11: a version of python greater or
equal to 10 and a version of python-support greater or equal to 11For more details on available CUDF types, you should check Section 2.2.2 of the CUDF spec.
# sample CUDF document structure preamble: # documents start with an optional preamble # ... package: foo # then come several packages # ... package: bar # ... request: # and finally a mandatory request stanza # ...
The various stanzas that compose a CUDF document belong to 3 different kinds of stanzas, recognizable by the name of their first property.
A single preamble stanza (starting with the preamble property) may
appear at the beginning of the document; it is forbidden to have such a
stanza elsewhere.
Then come several consecutive package stanzas (starting with the
package property).
Finally, there must be a single and mandatory request stanza (starting
with the request property) which concludes the document.
Each kind of stanza has a property scheme that defines the set of properties allowed therein, their types, and whether they are mandatory or optional (in the latter case, a default value is specified too).
Below you can find an overview of property schemata highlighting the most important properties; further details can be found in Section 2.2.3 of the CUDF spec.
A package stanza describes a single package known to the package manager; all package stanzas in a CUDF document describe the package universe as a whole.
package: ... (mandatory; type: package name; must be the first property) version: ... (mandatory; type: positive integer) installed: ... (optional; default: false; type: boolean) depends: ... (optional; type: package formula) conflicts: ... (optional; type: package list) provides: ... (optional; type: package list)
A few important remarks on the above properties:
versions are positive integers, usual version strings like "1.2.3-4"
are not accepted (as they have no clear cross-distribution
semantics). Ideally, each set of versions in a given distribution has a total
order and can then be easily mapped to positive integers.
provides account for features (or virtual packages): packages can
depend on features, such dependencies will be considered satisfied if at
least one package providing the features is installed.
CUDF features are versioned, you can provides: httpd > 2 ; an
unversioned feature stands for providing all possible versions of that
feature.
conflicts are not implicit among different versions of the same package:
multiple versions of the same package can be installed at the same
time.
Self-conflicts are ignored. This means that you can achieve
Debian-like implicit conflicts (i.e. only one version of each package can be
installed at any given time) as follows:
package: bash version: 5 conflicts: bash # i.e. conflict with all other versions of foo
Self-conflicts are ignored for virtual packages too, so you can achieve mutual-exclusion among a set of packages providing the same feature as follows:
package: postfix version: 2 provides: mail-transport-agent conflicts: mail-transport-agent package: exim version: 3 provides: mail-transport-agent conflicts: mail-transport-agent
The trailing request stanza describes the user request, that is which change the user wants to be performed to the set of installed packages (i.e. the package status).
request: ... (mandatory; type: string; value is ignored) install: ... (optional; type: package list) remove: ... (optional; type: package list) upgrade: ... (optional; type: package list)
install, remove, upgrade are similar: they tell the solver which
packages must be, respectively, installed, removed, and upgraded. In all
cases version requirements can be specified, e.g. install: bash > 3
means that the user want to install a version of bash greater than 3.
upgrade poses additional requirements: all packages request to be upgraded:
The optional leading preamble can be used to provide document meta-information.
preamble: ... (mandatory; type: string; value is ignored) property: ... (optional; type: property declaration) univ-checksum: ... (optional; type: string)
property is used to declare extra properties that should be allowed in
package stanzas (by default they are forbidden). The actual syntax and
semantics it's a bit tricky and should be checked for in Section 2.2.2 of the
CUDF spec. Here we simply give a representative example
that:
suite property whose value must be one of: stable,
testing, unstablebugs property of integer type with a default value of
0installed-size of positive integer typedescription property of string type with default value
of no descriptionpreamble: property: suite: enum [ stable , testing , unstable ] = [ stable ] , bugs: int = [0] , installed-size: posint , description: string = ["no description"] univ-checksum: 8c6d8b4d0cf7027cd523ad095d6408b4901ac31c
univ-checksum provides a checksum of the universe: a solver receiving
two CUDF documents with the same checksum is allowed to avoid parsing /
internalizing all packages again, in case it has a cache hit for that
Note that the description of all stanzas above is not complete, more properties and details are available, but you should really refer to the CUDF spec for that.