Difference between revisions of "Platform Team/Guide/Sweets Packaging"

m
 
(69 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{TOCright}}
+
== Summary ==
[[Category:Zero Sugar]]
 
  
== Writing spec files ==
+
This guide describes how to prepare software projects to be distributed via Sugar Labs' Packaging Management System, Sweets.
  
=== Package names ===
+
Make sure that you read the [[Platform_Team/Sweets|introduction page]] and [[Platform_Team/Guide/Sweets_Usage|Usage guide]]. To understand conceptual ideas, read the [[Platform_Team/Sweets/Glossary|Glossary]].
  
Within spec files, Zero packages might be identified by several methods:
+
== Prepare the environment ==
  
* current package (instead of a direct slug value, to make the spec file more robust, move the ''slug'' option to the [DEFAULT] section and use {{Code|%(slug)s}} interpolation),
+
Using the [[Platform_Team/Guide/Sweets_Usage#Installation|Usage guide]]'s instructions, install the Sweets. In addition, Sweets might be used from sources:
<current-slug>[/<nowiki><sub-package></nowiki>]
 
  
* package from default repository - http://build.sugarlabs.org,
+
git clone git://git.sugarlabs.org/sdk/sweets.git
  <package-slug>[/<nowiki><sub-package></nowiki>]
+
cd sweets
 +
git submodule init
 +
git submodule update
 +
  ./sweets upgrade
  
* direct 0install link.
+
The command {{Code|./sweets upgrade}} might require relogin from the X session to take into account the new PATH value.
<0install-feed-url>
 
  
At the end, all links will be transfered to 0install feed urls. For default repository, the final 0install url will be composed by concatenating http://packages.sugarlabs.org/ prefix and package slug.
+
== Recipe files ==
  
=== Versioning ===
+
The recipe specification file is an analog of scenario files in regular GNU/Linux distributions, like {{Code|.spec}} files in RPM. It is the cornerstone of Sweets, everything on the sweet project level depends on the recipe file. For activities, {{Code|activity/activity.info}}, an inherited recipe file name, is supported.
  
The versioning scheme for Zero packages can be arbitrary, since the ''version'' spec option supports [http://0install.net/interface-spec.html#id4016582 0install version format]. But in some cases, e.g., libraries, stricter versioning could be useful. In that case, the ''age'' spec option should be used.
+
On a logical level, the entire Sweets infrastructure might be treated as a set of distribution bundles with sources that contain recipe files. Software projects are identified as Zero Install ''interfaces'' that contain information about which distribution bundle needs to be downloaded in order to launch a particular software version. That's not the full picture (there are binary bundles created based on sources), but it is useful for this topic's purpose. Read the [[#Development with Sweets|Development with Sweets]] section to learn about the available usage scenarios.
  
The spec option ''age'' is intended to support, mostly, API breakages of library packages. But not ABI, because tracking an ABI is not trivial within the Sugar ecosystem (due to the enormous potential code base of varying quality) and of little utility, since packages may at any time rebuild from sources and multiple library versions may be installed (thanks to 0install).
+
A recipe file is an [http://docs.python.org/library/configparser.html ini] format configuration file that might consist of several sections:
  
Using the ''age'' option is simple, on every API breakage for the library package, increment the ''age'' value. Final package version will be:
+
* One or more [[Platform_Team/Recipe_Specification#Use case sections|use case sections]].
<age-option>.<version-option>
+
* Optional [[Platform_Team/Recipe_Specification#Archive sections|archive sections]].
 +
* Optional [[Platform_Team/Recipe_Specification#Auxiliary sections|auxiliary sections]].
 +
* Optional {{Code|[DEFAULT]}} section with common options that are accessible from all other sections.
  
=== Glob patterns ===
+
These files need to be placed in the root sources directory with names {{Code|sweets.recipe}} or {{Code|activity/activity.info}} for Sugar activities.
  
A pattern could be of two types:
+
=== Writing recipes ===
  
* doesn't contain ''/'' or ''**'' substrings, will be applied only to file names (not names of sub-directories within parent directory)
+
In sources directory, create a recipe file, e.g., using {{Code|sweets init}} command. Recipe file should contain at least one [[Platform_Team/Recipe_Specification#Use case sections|use case]] section. There are several types of use case sections:
* 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:
+
* ''Activity'' for Sugar activities,
 +
* ''Application'' for stand alone applications,
 +
* ''Library'' for libraries.
  
* ''*'' matches everything, except directory separator
+
Make sure that all required options were set. The ''implement'' option has a special meaning, it is an [[Platform_Team/Sweets/Glossary#Implemented_interfaces|identifier]] of the sweet.
* ''?'' matches any single character, except directory separator
 
* ''**'' matches everything, including directory separator
 
  
=== Sub packages ===
+
By default, the entirely sources directory will be packaged into sources tarball. In case if sources list needs to be restricted, add [[Platform_Team/Recipe_Specification#.5BBuild.5D|Source]] section with appropriate ''include'' and/or ''exclude'' options.
  
By default, package is the singular and will be composed using ''[Package]'' or/and ''[Activity]'' sections. But if the package contains several logical components, it might have sub packages. In that case, the spec file should contain additional sections (per sub package) in the form:
+
If the sweet needs to be built, add [[Platform_Team/Recipe_Specification#.5BBuild.5D|Build]] section.
  
  [Package/<nowiki><sub-package></nowiki>]
+
If built files are platform dependent, add [[Platform_Team/Recipe_Specification#Archive_sections|Archive]] section with ''arch=any'' option.
  
Format of sub sections is identical to ''[Package]'' section. Sub packages could make sense, e.g., for packaging additional content, or to separate library and its script language binding.
+
=== Interfaces ===
  
Other packages can mention sub packages by the format:
+
The ''implement'', ''associate'' and ''requires'' (optionally) options contain [[Platform_Team/Sweets/Glossary#Short_form_for_sweet_interfaces|short interfaces]]. These values have two meanings:
  
<package>/<nowiki><sub-package></nowiki>
+
* suffixes for final ''interface''s, e.g., {{Code|http://sweets.sugarlabs.org/''<value>''}},
 +
* the name of project/package on [[Platform_Team/Open_Build_Service|OBS]] that will be used to host released sweet.
  
Good practise is using the following names for sub packages:
+
In the 2nd case, the last slash separated part is a package, and the rest is a project, e.g., for ''sdk/sugar'', ''sdk'' is a project and ''sugar'' is a package in the ''sdk'' project.
 +
It is possible to have interface values without slashes, in that case, project and package names are the same.
  
* ''python'' for Python binding,
+
In the [[Platform_Team/Open_Build_Service|OBS]], there is a special project named ''base''. This project contains sweets that all time will be represented only by native packages. In other words, if you need to make sure that your sweet needs to depend only on native packages, use dependencies from the ''base'' project.
* ''activity'' if package might be used as regular application and in Sugar activity mode.
 
  
=== Recipes ===
+
The ''base'' project is also useful for [[Platform_Team/Sweets/Glossary#Associated_interfaces|associated]] interfaces set in ''associate'' recipe option. For example, if your sweet needs ''pygame=2'' dependency that is not yet widespread, create ''~user/pygame'' temporary sweet with ''2'' version only, and use ''~user/pygame'' as a dependency in your sweet. If ''base/pygame'' will be added as associated interface to the ''~user/pygame'', users that have ''>=2'' version in native packages will reuse them instead of ''~user/pygame'''s one.
  
In some cases, e.g., to save storage space or bandwidth, it is useful to split a packaged application into several tarballs when some tarballs will contain any-arch data, that are common for all platforms, and other will contain binaries for particular platform. Thus, if an application supports several platforms and any-arch data is big (various media, text, etc. files), there will not be duplicate tarballs.
+
See OBS [https://packages.sugarlabs.org/project/list_public projects] for all existed sweets.
  
The key differences between recipes and sub packages:
+
=== Dependencies ===
* Sub packages are logically independent parts of the package;
 
* Each sub package is identified by unique 0install url, all recipe components are identified by recipe url;
 
* Tarballs for different sub packages will be extracted to different directories, recipe component tarballs, within the same recipe, will be extracted to the same directory.
 
  
Use the ''recipe'' option to declare a (sub)package(s) as a recipe:
+
Dependencies might be used in the ''requires'' and ''suggests'' options in recipes files to declare that the current sweet depends on another sweet/s.
  
  [Package]
+
The format of a dependency string is:
  recipe = <component-name> [; ...]
 
  
and declare sections that contain components:
+
<interface> [(=|>=|<) <version>]
  
  [<component-name>]
+
The ''interface'' value supports all interface [[#Interfaces|forms]]. The limited set of version conditions depends on Zero Install [http://0install.net/interface-spec.html specification] when the {{Code|<nowiki>=</nowiki>}} condition is a high level one and will be described in {{Code|<nowiki>>=</nowiki>}} and {{Code|<}} terms.
  ...
 
  
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:
+
Dependencies may be optional. In that case, they need to be wrapped in square brackets. Optional dependencies will be used ''only'' if there is an [[Platform_Team/Sweets/Glossary#implementation|implementation]] to choose, otherwise they will be discarded without errors.
  
* langs
+
=== Stability status ===
* arch
 
* include
 
* exclude
 
* 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.
+
Sweets should have stability status:
  
=== Slots ===
+
* ''stable'', final stable release,
 +
* ''testing'', let people interested in testing try latest changes that are not yet stable,
 +
* ''developer'', just a more extreme version of ''testing'',
  
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.
+
This is a useful Zero Install feature that let developers share not yet stable version among the community. Since by default, only stable versions are being used, people, who are interested in helping developers in polishing not yet stable versions, need to explicitly choose not stable versions.
  
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.
+
=== Glob patterns ===
  
To declare slots for a package dependency, ''slots'' and appropriate ''requires'' options should be placed in the ''[Service]'' section that uses the dependency:
+
The ''include'' and ''exclude'' options contain file patterns. A pattern could be of two types:
  
  requires = <dependency>
+
* doesn't contain ''/'' or ''**'' substrings, will be applied only to file names
  slots[<dependency>] = <versions-range>
+
* contains ''/'' or ''**'' substring, will be applied to the full file path (relative to the root), thus could affect several directory levels
  
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:
+
Only these pattern symbols are allowed:
  
  1.0, 1.8, 2.0
+
* ''*'' matches everything, except directory separator
 +
* ''?'' matches any single character, except directory separator
 +
* ''**'' matches everything, including directory separator
 +
 
 +
=== Examples ===
  
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.
+
A list of recipe examples. Additionally, see {{Code|sugar*}} repositories in the [http://git.sugarlabs.org/sdk Gitorious sdk] repository, all of them are sweets.
  
== Pitfalls ==
+
'''Python activity'''
  
=== Devel packages ===
+
Python-based activity with standard Sugar Platform dependencies.
 +
 
 +
[Activity]
 +
implement = cartoon-builder
 +
name      = Cartoon Builder
 +
summary  = Create your own cell-animation sequences
 +
license  = GPLv2+
 +
homepage  = http://wiki.sugarlabs.org/go/Activities/Cartoon_Builder
 +
 +
version  = %(activity_version)s
 +
stability = stable
 +
 +
icon      = activity-cartoonbuilder
 +
exec      = sugar-activity activity.CartoonBuilderActivity
 +
 +
# Backwards compatibility of original activity.info options
 +
bundle_id = com.ywwg.CartoonBuilderActivity
 +
activity_version = 7
 +
 
 +
'''Python library'''
  
It is common practice in binary-based GNU/Linux distributions to use satellite devel packages to collect various build-time files like C headers or pkg-config files. In the 0install environment, this doesn't work, because every package is stored in a separate directory hierarchy, e.g., *.so symlinks, from devel package, will point to nothing, since all *.so.* files from the library package live in a separate directory.
+
A python-based library that could be used as is, or as an activity dependency.
  
Keep all build-time files in the runtime package.
+
[Library]
 +
implement = libjournal
 +
name      = libjournal
 +
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
 +
binding  = PYTHONPATH
  
 +
'''C-based library'''
  
<!--
+
[DEFAULT]
 +
depends  = base/glib; base/gconf; base/libgee >= 0.5; base/gtk+ >= 2.12
 +
            base/pango >= 1.20; base/librsvg
 +
 +
[Library]
 +
implement = polyol
 +
name      = polyol
 +
summary  = Intermediate level GObject based libraries for Sugar
 +
description = Polyol is a set of libraries that are written in Vala.
 +
            Libraries are intended to provide high-level C API to basic Sugar
 +
            features including Gtk based user interface. Applications that are
 +
            linked against Polyol, interact with sugar processes
 +
            (like shell, datastore, etc.) via DBus.
 +
license  = LGPLv3+
 +
homepage  = http://wiki.sugarlabs.org/go/Activity_Team/Polyol
 +
 +
version  = 1
 +
stability = developer
 +
 +
binding  = LD_LIBRARY_PATH lib
 +
            PKG_CONFIG_PATH lib/pkgconfig
 +
            VAPIDIR share/vala/vapi
 +
requires  = %(depends)s
 +
 +
[Archive]
 +
arch      = any
 +
 +
[Build]
 +
requires  = %(depends)s; pkg-config; cmake; make; gcc-c
 +
configure = cmake -D CMAKE_INSTALL_PREFIX=%(PREFIX)s
 +
                  -D PYTHON_SITEDIR=%(PREFIX)s/python
 +
                  -D COMPONENTS="collab;ds;env;gui;shell;toolkit"
 +
                  -D BINDING=python
 +
                  -D CMAKE_C_FLAGS:STRING="%(CFLAGS)s"
 +
                  .
 +
make      = make
 +
install  = make DESTDIR=%(DESTDIR)s install
  
== Introduction ==
+
== Releasing ==
  
The purpose of this Guide is to describe how to deploy your code via [[Activity_Team/Services|Sugar Services]] and let other people [[Documentation_Team/Services/Activity_Developers_Guide|use]] it in simple and convenient way.
+
In Sweets, releasing means uploading a sources tarball with a release (though, that [[#Stability_status|doesn't only mean]] stable versions) to the Sugar Labs [[Platform_Team/Open_Build_Service|instance]] of the [http://openbuildservice.org/ Open Build Service] (OBS). Before releasing, make sure that you have a Sugar Labs [[Service/Account#Sugar_Labs_Central_Login|account]]. A login with password will be required the first time or when your cookie is missing.
  
If you are looking for a method to install some software from native packages, see [[Documentation_Team/Services/Wrap native packages HOWTO| native packages HOWTO]].
+
Before releasing, make sure that your recipe conforms to the OBS [[Platform_Team/Open_Build_Service/Policy|Policy]]. While releasing, sweet sources will be uploaded to an OBS project/package according to the [[#Interfaces|implement]] recipe option. If a particular project or package don't exist, they will be created (upon user's confirmation for project creation).
  
If the service is not just a [[Documentation_Team/Services/Native_packages_usage|wrapper]] for an upstream project, please consider the possibility of creating a service page using [[Activity Team/Services/Template|template]].
+
To initiate releasing, enter from the sweet sources directory:
  
== Detailed description ==
+
sweets commit
  
The resulting service development process will consist of regular 0install files that are placed in a subdirectory on http://services.sugarlabs.org/ with a name that is the identity for the service in the rest of the 0sugar infrastructure. The Service's subdirectory will contain:
+
The {{Code|sweets}} command will ask for a commit message, i.e., release notes. The same notes might be passed to {{Code|commit}} command via the {{Code|--message}} command-line argument.
  
* Several .xml files that are regular 0install feeds. service.xml is the main feed for the service, other feed files are optional and represent sub services, e.g., [http://download.sugarlabs.org/services/toolkit/].
+
If the releasing sweet is binary based, only the most recent stable version will be built on the OBS side, other versions will be built on the client side.
  
* A bunch of tarballs with sources and binaries. Feed files contain links to these files.
+
== Development with Sweets ==
  
See the 0install [http://0install.net/interface-spec.html documentation] to learn more about feeds.
+
Source bundles might be used on the client side not only indirectly, via {{Code|sweets}} command for example, but also explicitly. Sources might be bundled, emailed, etc. In this case, it is just like {{Code|.xo}} files. To make sources useful within Sweets, the local directory with sources might be employed in several ways:
  
Services could be identified using two methods:
+
* Applications might be launched from sources, {{Code|sweets ''<path-to-sources>''}};
 +
* To reuse sources as dependencies for other sweets, the source directory needs to be registered in Sweets, {{Code|sweets checkout ''<path-to-sources>''}}; applications might be checked out as well.
  
* by name in the 0sugar environment
+
Checking out will register a ''sweet'' in the local ''Sweets'' instance as a single ''implementation'' for the ''interfaces'' it ''implements''. This feature is especially useful for libraries, for example, if the sugar-toolkit sources, which implement the {{Code|sdk/sugar-toolkit}} ''interface'', were cloned to the {{Code|~/src/sugar-toolkit}} directory, then, while running a {{Code|sdk/sugar}} ''sweet'', it would become possible to reuse local sugar-toolkit sources as a regular ''implementation'' of the {{Code|sdk/sugar-toolkit}} dependency of {{Code|sdk/sugar}}.
<service>
 
<service>/<subservice>
 
  
* as regular 0install identifiers in the 0install environment
+
=== Sugar sweets ===
http://services.sugarlabs.org/<service>
 
http://services.sugarlabs.org/<service>/<subservice>.xml
 
  
To start the Sugar Services developing process:
+
There are [[Platform_Team/Guide/Sweets_Usage#Sugar_via_Sweets|sdk/sugar]] sweets that might be used as an example how to support sweets. Sweets Sugar sources are always rebased [http://git.sugarlabs.org/sdk forks] of upstream projects with added {{Code|sweets.recipe}} files and lightweight patches that make the original code useful via Sweets.
* Install the [[Documentation_Team/Services/0sugar|0sugar]] tool.
 
* Read ''service.info'' file.
 
[[Documentation_Team/Services/Service.info_Specification|specification]]
 
and follow the rest of this document instruction about development details.
 
  
== Stability status ==
+
Checkout sources from:
  
One of the core differences from the Sucrose development process is having not stable "releases" (here, release is a result of ``0sugar push`` command). So, services need stability status. Internally, each service release will have one of 0install's stability [http://0install.net/interface-spec.html#id4091477 statuses]:
+
* http://git.sugarlabs.org/sdk/sugar-base
 +
* http://git.sugarlabs.org/sdk/sugar-toolkit
 +
* http://git.sugarlabs.org/sdk/sugar-artwork
 +
* http://git.sugarlabs.org/sdk/sugar
  
* ''stable'', final stable release,
+
and see its {{Code|sweets.recipe}} files.
* ''testing'', let people interested in testing try latest changes that are not yet stable,
 
* ''developer'', just a more extreme version of ''testing'',
 
* ''buggy'', already-released versions (of any status) could be [[#Bugfix_releases|marked]] as buggy after a while to force people to upgrade to a new bugfix version,
 
* ''insecure'', an extreme version of ''buggy''.
 
  
''0sugar push'' w/o arguments will push local changes as is. If you want to push with a particular stability status, use ''0sugar push <status>''.
+
== Developing activities ==
  
By default, all users will use only ''stable'' versions and won't upgrade to new versions, even if there are stable ones. To force people to upgrade from buggy versions, see the [[#Bugfix_releases|bugfix releases]] workflow.
+
How Sweets might be useful while developing activities.
  
== Development workflows ==
+
=== Manage sources ===
  
A Service developer can follow one of several step-by-step scenarios:
+
The traditional development related routine for activity sources is to run the {{Code|setup.py}} script located in the root activity directory. With Sweets, these routines might be accomplished with the {{Code|sweets}} command. Here is some background information:
  
* [[Documentation Team/Services/Activity specific Services HOWTO|Activity specific Services HOWTO]] - if your activity uses its own binaries,
+
* A downside of using Sweets is that running {{Code|setup.py}} requires being in the Sugar session (in order to have all the libraries that {{Code|setup.py}} injects);
* [[Documentation Team/Services/Binary-less Services HOWTO|Binary-less Services HOWTO]] - to make any architecture service, e.g., python based,
+
* Sweets is designed to support multiple software versions at the same time. So to avoid having to login to different Sugar sessions for creating source tarballs, for example, it makes more sense to have a standalone utility;
* [[Documentation Team/Services/Binary Services HOWTO|Binary Services HOWTO]] - for services that contain binaries,
+
* The {{Code|sweets}} command already contains development related functionality; it is useful to keep all development related functions in one utility.
* [[Documentation Team/Services/Upstream Services HOWTO|Upstream Services HOWTO]] - if your activity or service uses a project which is not part of Sugar Platform, follow this howto to create a wrapper around the upstream project, and just add its name to the ''requires'' section of .info file,
 
* [[Documentation Team/Services/Wrap native packages HOWTO|Wrap native packages HOWTO]] - this is a special one, if some project is already well packaged in various GNU/Linux distributions, but is not a Sugar Platform component, just create a "fake" service.
 
  
== Release workflows ==
+
Sweets support the following {{Code|setup.py}}'s commands:
  
'''Having only stable releases'''
+
* {{Code|build}}, build generated files, e.g., {{Code|locale/}} directory;
 +
* {{Code|dist_xo}}, create a .xo with activity sources;
 +
* {{Code|dist_source}}, create activity sources tarball;
 +
* {{Code|genpot}}, generate the gettext pot file.
  
All releases of your services will have ''stable'' stability status.
+
And doesn't support the following:
  
* when your code is ready to release,
+
* {{Code|dev}} - seems to be a needlessly exaggerated function that creates a symbolic link in the {{Code|~/Activities}} directory to activity sources. The same might be done using the {{Code|ln -s}} command to avoid having derived functionality, or better, place sources directly in the {{Code|~/Activities}} directory;
* ''0sugar dist*'' to make bundles,
+
* {{Code|fix_manifest}} - function creates {{Code|MANIFEST}} file. Not having this file is not a failure, and Sweets is designed to have include/exclude rules in recipe files instead;
* ''0sugar push stable'' to rsync bundles to the server,
+
* {{Code|install}} - function installs the activity to the root system.  Sweets avoid, by design, any global changes during its regular behaviour.
* if it was the wrong time to release and you want to re-release it, repeat the previous steps to rewrite the wrong release.
 
  
'''Bugfix releases'''
+
As regular {{Code|sweets}}'s commands, these commands need to be executed from the activity directory (or in any of its sub-directories, not just in the root), or the path to activity sources might be specified after the command name, e.g.:
  
Services assume a simple versioning scheme, if you found bugs in the stable version,
+
sweets build [PATH]
  
* either ''0sugar push stable'' the release once more (users will not mess this new copy of release with previous ones),
+
=== Launch activity ===
* or ''0sugar push stable'' the release with incremented ''version'' field.
 
* If bugs are critical, mark the previous release as ''buggy'' or ''insecure'' to force users to upgrade their old releases. If you re-pushed release w/o incrementing ''version'' number, you should use revision number.
 
  
0sugar push {buggy|insecure} {version[-revision]}
+
Before starting Sugar Shell, place your activity's sources directory under the {{Code|~/Activities/}} directory, or place there a symbolic link to the activity sources. After running Sugar Shell, the new activity will appear in the Home view (if it's absent in the Favorites view, switch to the List view).
  
''' Development releases '''
+
== Good practices ==
  
If you want to test your new version among interested people,
+
=== Devel packages ===
  
* do all the steps mentioned in the previous workflows,
+
It is common practice in binary-based GNU/Linux distributions to use satellite devel packages to collect various build-time files like C headers or pkg-config files. In the Zero Install environment, this doesn't work, because every package is stored in a separate directory hierarchy, e.g., *.so symlinks, from devel package, will point to nothing, since all *.so.* files from the library package live in a separate directory.
* but use either the ''testing'' or ''developer'' status for the ''push'' command.
 
* Users interested in testing (with testing mode enabled) will get your new development version.
 
* You don't have to change the ''version'' every time for micro releases, ''0sugar'' will implicitly change the revision of new pushes, and users will download the latest changes.
 
  
== Tips ==
+
Keep all build-time files in the sweet with runtime files.
  
* Via ''binding'' variables, a service's root directory will be accessible for service users, so for python services (for example), it is better to use a subdirectory for a service's import modules, like [http://git.sugarlabs.org/projects/toolkit/repos/mainline/trees/master Toolkit] does - there is a ''toolkit'' subdirectory in Toolkit's root.
+
=== Transparent behaviour ===
  
* Be careful with machine architecture, especially in making binaries in VMs, e.g., the XO-1 arch is i586, but built-in XO VM, binaries could have i686 and thus, won't start (0install won't allow) on XO-1. Use --arch 0sugar's argument to set targeted architecture explicitly.
+
Library sweets that are associated with native packages ({{Code|base/*}} sweets), should use regular environment variables for binding, such as {{Code|LD_LIBRARY_PATH}}. The idea is that it should be possible to replace them with native packages transparently and avoid changes in sweets that use these libraries.
  
== Documentation ==
+
== Feedback ==
  
* [http://0install.net/injector-packagers.html Packaging guide] for 0install packages
+
{{:Platform_Team/Sweets/Feedback}}
* [http://0install.net/interface-spec.html Feed file format specification]
 
* [http://0install.net/0compile.html 0compile] [http://0install.net/0compile-dev.html guide]
 
-->
 

Latest revision as of 00:30, 23 September 2012

Summary

This guide describes how to prepare software projects to be distributed via Sugar Labs' Packaging Management System, Sweets.

Make sure that you read the introduction page and Usage guide. To understand conceptual ideas, read the Glossary.

Prepare the environment

Using the Usage guide's instructions, install the Sweets. In addition, Sweets might be used from sources:

git clone git://git.sugarlabs.org/sdk/sweets.git
cd sweets
git submodule init
git submodule update
./sweets upgrade

The command ./sweets upgrade might require relogin from the X session to take into account the new PATH value.

Recipe files

The recipe specification file is an analog of scenario files in regular GNU/Linux distributions, like .spec files in RPM. It is the cornerstone of Sweets, everything on the sweet project level depends on the recipe file. For activities, activity/activity.info, an inherited recipe file name, is supported.

On a logical level, the entire Sweets infrastructure might be treated as a set of distribution bundles with sources that contain recipe files. Software projects are identified as Zero Install interfaces that contain information about which distribution bundle needs to be downloaded in order to launch a particular software version. That's not the full picture (there are binary bundles created based on sources), but it is useful for this topic's purpose. Read the Development with Sweets section to learn about the available usage scenarios.

A recipe file is an ini format configuration file that might consist of several sections:

These files need to be placed in the root sources directory with names sweets.recipe or activity/activity.info for Sugar activities.

Writing recipes

In sources directory, create a recipe file, e.g., using sweets init command. Recipe file should contain at least one use case section. There are several types of use case sections:

  • Activity for Sugar activities,
  • Application for stand alone applications,
  • Library for libraries.

Make sure that all required options were set. The implement option has a special meaning, it is an identifier of the sweet.

By default, the entirely sources directory will be packaged into sources tarball. In case if sources list needs to be restricted, add Source section with appropriate include and/or exclude options.

If the sweet needs to be built, add Build section.

If built files are platform dependent, add Archive section with arch=any option.

Interfaces

The implement, associate and requires (optionally) options contain short interfaces. These values have two meanings:

In the 2nd case, the last slash separated part is a package, and the rest is a project, e.g., for sdk/sugar, sdk is a project and sugar is a package in the sdk project. It is possible to have interface values without slashes, in that case, project and package names are the same.

In the OBS, there is a special project named base. This project contains sweets that all time will be represented only by native packages. In other words, if you need to make sure that your sweet needs to depend only on native packages, use dependencies from the base project.

The base project is also useful for associated interfaces set in associate recipe option. For example, if your sweet needs pygame=2 dependency that is not yet widespread, create ~user/pygame temporary sweet with 2 version only, and use ~user/pygame as a dependency in your sweet. If base/pygame will be added as associated interface to the ~user/pygame, users that have >=2 version in native packages will reuse them instead of ~user/pygame's one.

See OBS projects for all existed sweets.

Dependencies

Dependencies might be used in the requires and suggests options in recipes files to declare that the current sweet depends on another sweet/s.

The format of a dependency string is:

<interface> [(=|>=|<) <version>]

The interface value supports all interface forms. The limited set of version conditions depends on Zero Install specification when the = condition is a high level one and will be described in >= and < terms.

Dependencies may be optional. In that case, they need to be wrapped in square brackets. Optional dependencies will be used only if there is an implementation to choose, otherwise they will be discarded without errors.

Stability status

Sweets should have stability status:

  • stable, final stable release,
  • testing, let people interested in testing try latest changes that are not yet stable,
  • developer, just a more extreme version of testing,

This is a useful Zero Install feature that let developers share not yet stable version among the community. Since by default, only stable versions are being used, people, who are interested in helping developers in polishing not yet stable versions, need to explicitly choose not stable versions.

Glob patterns

The include and exclude options contain file patterns. A pattern could be of two types:

  • doesn't contain / or ** substrings, will be applied only to file names
  • 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

Examples

A list of recipe examples. Additionally, see sugar* repositories in the Gitorious sdk repository, all of them are sweets.

Python activity

Python-based activity with standard Sugar Platform dependencies.

[Activity]
implement = cartoon-builder
name      = Cartoon Builder
summary   = Create your own cell-animation sequences
license   = GPLv2+
homepage  = http://wiki.sugarlabs.org/go/Activities/Cartoon_Builder

version   = %(activity_version)s
stability = stable

icon      = activity-cartoonbuilder
exec      = sugar-activity activity.CartoonBuilderActivity

# Backwards compatibility of original activity.info options
bundle_id = com.ywwg.CartoonBuilderActivity
activity_version = 7

Python library

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

[Library]
implement = libjournal
name      = libjournal
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
binding   = PYTHONPATH

C-based library

[DEFAULT]
depends   = base/glib; base/gconf; base/libgee >= 0.5; base/gtk+ >= 2.12
            base/pango >= 1.20; base/librsvg

[Library]
implement = polyol
name      = polyol
summary   = Intermediate level GObject based libraries for Sugar
description = Polyol is a set of libraries that are written in Vala.
            Libraries are intended to provide high-level C API to basic Sugar
            features including Gtk based user interface. Applications that are
            linked against Polyol, interact with sugar processes
            (like shell, datastore, etc.) via DBus.
license   = LGPLv3+
homepage  = http://wiki.sugarlabs.org/go/Activity_Team/Polyol

version   = 1
stability = developer

binding   = LD_LIBRARY_PATH lib
            PKG_CONFIG_PATH lib/pkgconfig
            VAPIDIR share/vala/vapi
requires  = %(depends)s

[Archive]
arch      = any

[Build]
requires  = %(depends)s; pkg-config; cmake; make; gcc-c
configure = cmake -D CMAKE_INSTALL_PREFIX=%(PREFIX)s
                  -D PYTHON_SITEDIR=%(PREFIX)s/python
                  -D COMPONENTS="collab;ds;env;gui;shell;toolkit"
                  -D BINDING=python
                  -D CMAKE_C_FLAGS:STRING="%(CFLAGS)s"
                  .
make      = make
install   = make DESTDIR=%(DESTDIR)s install

Releasing

In Sweets, releasing means uploading a sources tarball with a release (though, that doesn't only mean stable versions) to the Sugar Labs instance of the Open Build Service (OBS). Before releasing, make sure that you have a Sugar Labs account. A login with password will be required the first time or when your cookie is missing.

Before releasing, make sure that your recipe conforms to the OBS Policy. While releasing, sweet sources will be uploaded to an OBS project/package according to the implement recipe option. If a particular project or package don't exist, they will be created (upon user's confirmation for project creation).

To initiate releasing, enter from the sweet sources directory:

sweets commit

The sweets command will ask for a commit message, i.e., release notes. The same notes might be passed to commit command via the --message command-line argument.

If the releasing sweet is binary based, only the most recent stable version will be built on the OBS side, other versions will be built on the client side.

Development with Sweets

Source bundles might be used on the client side not only indirectly, via sweets command for example, but also explicitly. Sources might be bundled, emailed, etc. In this case, it is just like .xo files. To make sources useful within Sweets, the local directory with sources might be employed in several ways:

  • Applications might be launched from sources, sweets <path-to-sources>;
  • To reuse sources as dependencies for other sweets, the source directory needs to be registered in Sweets, sweets checkout <path-to-sources>; applications might be checked out as well.

Checking out will register a sweet in the local Sweets instance as a single implementation for the interfaces it implements. This feature is especially useful for libraries, for example, if the sugar-toolkit sources, which implement the sdk/sugar-toolkit interface, were cloned to the ~/src/sugar-toolkit directory, then, while running a sdk/sugar sweet, it would become possible to reuse local sugar-toolkit sources as a regular implementation of the sdk/sugar-toolkit dependency of sdk/sugar.

Sugar sweets

There are sdk/sugar sweets that might be used as an example how to support sweets. Sweets Sugar sources are always rebased forks of upstream projects with added sweets.recipe files and lightweight patches that make the original code useful via Sweets.

Checkout sources from:

and see its sweets.recipe files.

Developing activities

How Sweets might be useful while developing activities.

Manage sources

The traditional development related routine for activity sources is to run the setup.py script located in the root activity directory. With Sweets, these routines might be accomplished with the sweets command. Here is some background information:

  • A downside of using Sweets is that running setup.py requires being in the Sugar session (in order to have all the libraries that setup.py injects);
  • Sweets is designed to support multiple software versions at the same time. So to avoid having to login to different Sugar sessions for creating source tarballs, for example, it makes more sense to have a standalone utility;
  • The sweets command already contains development related functionality; it is useful to keep all development related functions in one utility.

Sweets support the following setup.py's commands:

  • build, build generated files, e.g., locale/ directory;
  • dist_xo, create a .xo with activity sources;
  • dist_source, create activity sources tarball;
  • genpot, generate the gettext pot file.

And doesn't support the following:

  • dev - seems to be a needlessly exaggerated function that creates a symbolic link in the ~/Activities directory to activity sources. The same might be done using the ln -s command to avoid having derived functionality, or better, place sources directly in the ~/Activities directory;
  • fix_manifest - function creates MANIFEST file. Not having this file is not a failure, and Sweets is designed to have include/exclude rules in recipe files instead;
  • install - function installs the activity to the root system. Sweets avoid, by design, any global changes during its regular behaviour.

As regular sweets's commands, these commands need to be executed from the activity directory (or in any of its sub-directories, not just in the root), or the path to activity sources might be specified after the command name, e.g.:

sweets build [PATH]

Launch activity

Before starting Sugar Shell, place your activity's sources directory under the ~/Activities/ directory, or place there a symbolic link to the activity sources. After running Sugar Shell, the new activity will appear in the Home view (if it's absent in the Favorites view, switch to the List view).

Good practices

Devel packages

It is common practice in binary-based GNU/Linux distributions to use satellite devel packages to collect various build-time files like C headers or pkg-config files. In the Zero Install environment, this doesn't work, because every package is stored in a separate directory hierarchy, e.g., *.so symlinks, from devel package, will point to nothing, since all *.so.* files from the library package live in a separate directory.

Keep all build-time files in the sweet with runtime files.

Transparent behaviour

Library sweets that are associated with native packages (base/* sweets), should use regular environment variables for binding, such as LD_LIBRARY_PATH. The idea is that it should be possible to replace them with native packages transparently and avoid changes in sweets that use these libraries.

Feedback

  • Submit your bug report or feature request.
  • Subscribe to the sugar-devel mailing list and email with the subject prefixed with [SWEETS].
  • Ask your question on IRC channels, #sugar (not logged) or #sugar-newbies (logged).