Sugar Network/Recipe Specification


0sugar.info file

The 0sugar.info specification file is an analog of scenario files in regular GNU/Linux distributions, like .spec files in RPM. It is the cornerstone of Zero Sugar workflows, everything depends on the 0sugar.info spec file.

For activities, activity.info, a deprecated spec file name, is supported.

[DEFAULT]

Common options. Options from this section will be accessible from all other sections. It may be useful to store options that are common for all sections.

import = <filename> [; ...]

Import another spec file. Makes sense only within the [DEFAULT] section itself.

repos = <name> <prefix> [; ...]

Add new or reset existed repositories.

Common options

Options that are common for all sections except [DEFAULT].

inherit = <section-name> [; ...]

Include options from another section.

merge = <section-name> [; ...]

The same behaviour as inherit, but merges values for list type options, i.e., the final values will consist of the base-section values with addtional child-section values. List options are:

  • category
  • requires
  • binding
  • include
  • exclude
  • langs
  • packaged

[Package]

This is a required section (but could be replaced by [Activity]). It describes the main package.

slug = <package-slug>

The string used as identifier in cases like 0install feed urls or native package names. Only lower alphabetic, numeric, "_", "+" or "-" symbols are allowed.

name = <package-name>

Package name, in free form, equals to slug, by default.

summary = <one-line-description>

Short descriptive line.

description = <multi-line-description>

Long descriptive text. To wrap long text, all lines after the second, should start with spaces. This field is equal to summary by default.

license = <licence-name>

Package license. Short licence names from Fedora naming scheme are welcome.

homepage = <url>

Packaged project home page.

icon = <icon-file-name>

Relative (from Zero Sugar based project) path to icon file.

category = <category> [; ...]

A classification for the package using values defined by freedesktop.org menu specification.

age = <age-number>

Simple number that will be used as a major number for version, see versioning scheme for details.

version = <version-number>

Current version of the package using 0install version format. If age option was set, versioning is a bit different.

stability = <stability-level>

Stability level of current version. Values conform to 0install stability levels and could be:

  • insecure
  • buggy
  • developer
  • testing
  • stable
requires = <dependency> [(=|>=|<) <version>] [; ...]

List of dependencies that should exist before using the package.

slots[<dependency>] = <first-dependency-version> [; ...], <last-dependency-verison>

To specify dependency slots.

binding = [prepend|append|replace] <variable-name> [<insert-text-to-prepend-variable-value>] [; ...]

The environment variables 0install should export to the process that uses this package. This makes sense only for multiple-activity-serving dependencies (like libraries), not for the activity itself.

main = <path-to-exec-file>

For applications, the relative (from Zero Sugar based project) path to exec file. Doesn't make sense for packages like libraries.

exec = <shell-command>

Instead of using an executable program from the main option, 0sugar can bundle a script to run an arbitrary shell command.

exec[<script-name>] = <shell-command>

Also, 0sugar can bundle arbitrary shell scripts. It may be useful for a 0install distribution, e.g., to pass a path to an already-bundled command instead of using this command directly:

 binding = replace VALADIR, PATH
 exec[valac] = exec "$VALADIR"/bin/valac --vapidir "$VALADIR"/share/vala/vapi "$@"
include = <glob-pattern> [; ...]

Glob pattern for files to include to package. By default, all files are assumed.

exclude = <glob-pattern> [; ...]

Glob pattern for files to exclude from package. In additional, various temporary files will be excluded like .bak or .pyc.

langs = <lang-name> [; ...]
include[<lang-name>] = <glob-pattern> [; ...]
exclude[<lang-name>] = <glob-pattern> [; ...]

A special form of include/exclude options that are intended to create separate, per locale, (sub)packages. If language is mentioned in langs list but doesn't have include[]/exclude[] options, include/exclude will be used (in that case, using special LANG variable makes sense).

root = <path>

Could be used in conjunction with include/exclude to specify a new root path within a directory of files that will be included in the package.

arch = <arch>

Makes sense only for binary (sub)packages, and can contain:

  • * for noarch (by default)
  • build for binaries to use the current architecture
packaged = <distro-name> <package-name> [; ...]

If package could be installed from an official GNU/Linux distributions repository (i.e., not from packages generated from 0sugar.info spec file on OBS), use this option to let 0install know what package names are on the particular GNU/Linux distribution.

Distribution names could be:

  • rpm for all rpm-based distros
  • debian for deb-based distros
  • gentoo for ebuild-based distros
  • slack for Slackware
  • ports for FreeBSD Ports

[Activity]

This section should be present only for activities (or for applications that could be used also as Activities, e.g., GCompris is a regular application but could be launched in Sugar mode).

Section uses the same options as [Package] with these additions:

activity_version

Option is deprecated, version should be used instead.

bundle_id = <bundle-id>

See activity.info file specification. Option will be deprecated after implementing 0sugar in glucose and switching to identifying activities by urls (like 0install feeds).

icon = <icon-file-name-wo-suffix>

Behaviour from activity.info is supported (value should not have ".svg" suffix, and icon file could be found only in activity subdirectory) but deprecated. Regular icon behaviour from [Package] section should be used instead.

exec = <shell-command>

Sugar will pass additional command line arguments to this command.

mime_types = <mime-type> [; ...]

List of mime types supported by the activity. It's used when opening a file from the web or to present to the user a list of activities which can open a certain Journal object.

tags = <tag> [; ...]

Tags give more context in which to group the activity. This is used to allow users to find activities more easily in the Journal, the Home view, etc.

[Source]

Section makes sense only while packaging 3rd-party applications.

source = <url>

Url to download sources tarball.

patch = <path-to-patch> [patch-level] [; ...]

Patch downloaded tarball.

[Buid]

How to build binaries. If package contains binary implementations, this section should be present to describe the building process.

requires = <dependency-name> [(=|>=|<) <version>] [; ...]

What packages should be present before building this one from sources. Similar to requires option from [Package].

build = <shell-command>

How to build binaries.

Its value is a shell command, executed inside the build directory $BUILDDIR. It must compile the source in $SRCDIR, putting the final result (ready for distribution) in $DISTDIR. If this command starts to get complicated, you should move it to a script (either inside the main source archive or in a separate dependency) and just set this attribute to the command to run the script.

NOTE This command will be executed not only in the developer's environment but also in the user's, if a proper binary wasn't found; so do not use here any development-related commands like autogen.sh

install = <shell-command>

How to install package.

[Maintain]

Various options that make sense only in the package-developer's environment.

exec = <shell-command>

How to bundle package. By default, 0sugar just bundles the entire root directory excluding temporary files.

requires = <dependency> [(=|>=|<) <version>] [; ...]

The packages that should be present before invoking the exec command. For example, if the exec command generates .c files from .vala, the vala dependency should be mentioned in the requires option.

Package names

Zero Sugar spec file options, like requires, contain links to another packages. Followed link formats are supported:

  • current package to upload to target repository (instead of direct slug value, to make spec file more robust, move slug option to [DEFAULT] section and use %(slug)s interpolation),
<slug-option-value>[/<sub-package>]
  • package from default repository,
<package-name>[/<sub-package>]
  • package from particular repository,
<package-name>[/<sub-package>]:<repository>
  • direct 0install link.
<0install-feed-url>

At the end, all links will be transfered to 0install feed urls. Repository is just a Web url prefix like http://packages.sugarlabs.org/, the final 0install url will be composed by concatenating repository prefix and package name. Repositories might be:

  • target, the repository current package will be uploaded to, equals to default repository;

Spec option repos can add new repositories or reset predefined ones.

Versioning

Versioning scheme for Zero packages could be arbitrary, since version spec option supports 0install version format. But in some cases, e.g. libraries, more strict versioning could be useful. In that case age spec option could be used.

Spec option age is intended to support, mostly, library packages API breakages. Not ABI, because tracking ABI is not trivial within sugar ecosystem (possible hugeness of code base of different quality) and useless since packages could be all time rebuild from sources.

Using age option is simple, on every API breakage of library package, increment age value. Final package version will be:

<age-option>.<version-option>

Glob patterns

A pattern could be of two types:

  • doesn't contain / or ** substrings, will be applied only to file names (not names of sub-directories within parent directory)
  • contains / or ** substring, will be applied to the full file path (relative to the root), thus could affect several directory levels

Only these pattern symbols are allowed:

  • * matches everything, except directory separator
  • ? matches any single character, except directory separator
  • ** matches everything, including directory separator

Sub packages

By default, package is the singular and will be composed using [Package] or/and [Activity] sections. But the service can have sub-packages, as well, in that case, spec file should contain additional sections (per sub feed) in the form:

 [Package/<sub-package>]

Format of sub sections is identical to [Package] section. Sub packages could make sense, e.g., for combining non-arch data and pure binaries, or to separate runtime and buildtime data.

Other packages can mention sub packages by format:

<package>/<sub-package>

The good practise is using followed names for sub packages:

  • data for non-arch sub packages,
  • devel for sub packages with buildtime data like C header files,
  • python for Python binding.

Recipes

In some cases, e.g., to save storage space or bandwidth, it is useful to split a packaged application into several parts when some parts will be common. The most usual case is having any-arch data and binaries sub-packages, i.e., the final service will depend on a data sub-package (one implementation per application release) and sub-packages with binaries (implementations per arch per application release). But it's not possible to always use sub-packages. Applications could assume that data is placed in a particular relative path from the launched binaries, and if there is no way to set data location via environment bindings, sub-packages are useless and recipes will help.

Use the recipe option to declare a (sub)package(s) as a recipe:

 [Package]
 recipe = <component-name> [; ...]

and declare sections that contain components:

 [<component-name>]
 ...

Being a recipe, the package section cannot contain files-related options (since package itself does not contain any tarballs directly, only via recipe components), these options could be set only in components:

  • root
  • langs
  • arch
  • include
  • exclude
  • main
  • exec
  • slots

The same component could be a part of different recipes. In that case, different package implementations will contain the same recipe component tarball.

The final package implementation will contain a tarball per component. All these tarballs will be unpacked to the same root directory. For example, having the following lines and invoking 0sugar build on two platforms - x86 and x86_64 platforms, two (per-arch) implementations will be created and they will use three tarballs - x86 and x86_64 tarballs from the [binary] section, and one common [data] tarball for both implementations.

[Package]
recipe = data, binary

[data]
include = share/**

[binary]
include = bin/**, lib/**
main = bin/launch
arch = build

Slots

Slots make sense only for binary services when they could be built against several compatibility ranges for their dependencies and these dependencies could be installed from native packages.

Assume that a service requires cairo, and that the source code uses a cairo feature that appeared only in v1.8, but the source code can fallback to previous cairo versions, as well. If cairo can be installed from 0install feeds, then there is no need for slots, since the service can declared as a "cairo >= 1.8" dependency, and so cairo will be installed from 0install feeds. But if cairo could be installed from native packages, there is no way to know in advance which cairo version will be present, and the service should have two implementations, one for cairo < 1.8 and one for cairo >= 1.8. In this case, slots will be useful.

To declare slots for a package dependency, slots and appropriate requires options should be placed in the [Service] section that uses the dependency:

 requires = <dependency>
 slots[<dependency>] = <versions-range>

Option slots will declare compatibility ranges for a particular dependency. Only one, closed from both sides, range can be used. For example, in the cairo case, it could be:

 1.0, 1.8, 2.0

The 1.0 (it could be 0.0 as well) restricts the version range from the left and the 2.0 (most likely v2.0 will not be backwards compatible with v1.x) from the right; so only two ranges can be chosen, 1.0 >= x < 1.8, 1.8 >= x < 2.0. While building binaries for the 0sugar build command, 0sugar will detect what the current cairo version is (the service that it is building/linking against), and will choose the proper slot or fail, otherwise.

Predefined options

  • BUILDDIR where the build happens
  • SRCDIR path to directory with sources; for a custom (via 0compile) build, BUILDDIR and SRCDIR are different, while building on OBS, they are the same
  • DISTDIR temporary path to place installed files before bundling them
  • PREFIX prefix path for installed files, e.g., /usr
  • DATADIR data files directory, e.g., /usr/share
  • DOCDIR doc files directory, e.g., /usr/share/doc
  • BINDIR bin files directory, e.g., /usr/bin
  • INCLUDEDIR include files directory, e.g., /usr/include
  • LIBDIR lib files directory, e.g., /usr/lib
  • PYTHON_SITEDIR python files directory, e.g., /usr/lib/python2.6/site-packages
  • CFLAGS default gcc CFLAGS
  • CXXFLAGS default gcc CXXFLAGS

In sections that contain langs option:

  • LANG current language while building per language implementation

Also, during the 0sugar build command invocation, 0sugar exports the environment variables that should be used in exec options, for example, to implement a conditional build.

  • ZSUGAR_<argument-in-upper-case> map 0sugar long command line arguments
  • SECTION_<section-name-in-upper-case> for every spec file section that will be processed

Examples

Python activity

Python-based activity with standard Sugar Platform dependencies.

[Activity]
slug      = cartoon-builder
name      = Cartoon Builder
summary   = Create your own cell-animation sequences
license   = GPLv2+
homepage  = http://wiki.sugarlabs.org/go/Activities/Cartoon_Builder
icon      = activity/activity-cartoonbuilder.svg
category  = Games;Education
version   = 11.4.9-pre3
stability = testing
exec      = sugar-activity activity.CartoonBuilderActivity

Python library

Package python-based library that could be used as is, or as an activity dependency.

[Package]
slug      = journal
summary   = Hight level library to create your own Journal-like activity
license   = GPLv3+
homepage  = http://wiki.sugarlabs.org/go/Activity_Team/Services/Journal
version   = 1
stability = testing
requires  = toolkit/python
binding   = PYTHONPATH

Vala library

Binary library with generating C files from Vala sources, creating library package, and devel, python binding sub-packages.

[DEFAULT]
slug      = env
summary   = Access to various sugar environment settings.
license   = LGPLv3+
homepage  = http://wiki.sugarlabs.org/go/Activity_Team/Services/Env
version   = 0.9
stability = testing

[Package]
requires  = glib; gconf; libgee >= 0.5
binding   = LD_LIBRARY_PATH lib
include   = *.so.*
arch      = build

[Package/devel]
requires  = glib/devel; gconf/devel; libgee/devel
            %(slug)s
binding   = LD_LIBRARY_PATH lib
            PKG_CONFIG_PATH lib/pkgconfig
            VAPIDIR share/vala/vapi
exclude   = %(PYTHON_SITEDIR)s/**
            *.so.*
arch      = build

[Package/python]
requires  = python; %(slug)s
binding   = PYTHONPATH python
include   = %(PYTHON_SITEDIR)s/**
arch      = build
slots[python] = 2.5; 2.6; 2.7; 3.0

[Build]
requires  = glib/devel; gconf/devel; libgee/devel
            pkgconfig; cmake; make; gcc-c
build     = cmake -DCMAKE_INSTALL_PREFIX=%(PREFIX)s
                  -DPYTHON_SITEDIR=%(PYTHON_SITEDIR)s
                  -DCOMPONENTS="env"
                  -DBINDING=python
                  -DCMAKE_C_FLAGS:STRING="%(CFLAGS)s"
                  %(SRCDIR)s &&
            make
install   = make DESTDIR=%(DISTDIR)s install

[Maintain]
requires  = vala
exec      = make dist