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

From Sugar Labs
Jump to navigation Jump to search
m
 
(92 intermediate revisions by 5 users not shown)
Line 1: Line 1:
<noinclude>{{GoogleTrans-en}}{{TOCright}}
+
== Summary ==
[[Category:Activity Team]]
 
</noinclude>
 
  
== Introduction ==
+
This guide describes how to prepare software projects to be distributed via Sugar Labs' Packaging Management System, Sweets.
  
The purpose of this Guide is describing how to get benefits of [[Activity_Team/Services|Sugar Services]] for your library/application, simplify support fork flows and let your users(developers) [[Documentation_Team/Services/Activity_Developers_Guide|use]] your code in simple and convenient way.
+
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]].
  
This guide is about how to package your code to services, if you are looking for method how to install some software from native packages, see [[Documentation_Team/Services/Native_packages_usage|Native packages usage]] guide.
+
== Prepare the environment ==
  
If service is not [[Documentation_Team/Services/Native_packages_usage|wrapper]] for native package and could be used by other developers, please consider possibility to create service page using [[Activity Team/Services/Template|template]].
+
Using the [[Platform_Team/Guide/Sweets_Usage#Installation|Usage guide]]'s instructions, install the Sweets. In addition, Sweets might be used from sources:
  
== Detailed description ==
+
git clone git://git.sugarlabs.org/sdk/sweets.git
 +
cd sweets
 +
git submodule init
 +
git submodule update
 +
./sweets upgrade
  
The result for service development process will be regular 0install files that are placed to subdirectory on http://download.sugarlabs.org/services/ with name which is identity for the service in the rest of 0sugar infrastructure. Service's subdirectory will contain:
+
The command {{Code|./sweets upgrade}} might require relogin from the X session to take into account the new PATH value.
  
* [http://download.sugarlabs.org/services/toolkit/runtime.xml runtime.xml], regular 0install feed file which will be used as a runtime dependency
+
== Recipe files ==
* [http://download.sugarlabs.org/services/toolkit/buildtime.xml buildtime.xml], regular 0install feed file which will be used as a buildtime dependency
 
* bunch of tarballs with sources and binaries, feed files contain links to these files
 
  
Feed files, in addition to several information fields, contain tags that describe implementations of the service(i.e. releases). At the same time, feed file contains implementations for various service versions and the same version could be represented by several implementations:
+
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.
  
* source implementation in ''<implementation>'' tag with attribute ''arch'' == ''*-src'', with links to source tarball and instructions how to build it
+
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.
* no arch implementation in ''<implementation>'' tag with attribute ''arch'' == ''*-*'', which can be used as-is on different platforms e.g. pure python services
 
* one or several binary implementations in ''<implementation>'' tags, that contain binaries of the same source implementation but for various architectures(attribute ''arch'')
 
* package implementation in ''<package-implementation>'' tag, to reuse native packages, see [[Documentation_Team/Services/Native_packages_usage|Native packages usage]] for more info.
 
  
== service.info file ==
+
A recipe file is an [http://docs.python.org/library/configparser.html ini] format configuration file that might consist of several sections:
  
Service publishing workflow is similar to activities. There is an info file, here ''service/service.info'', which describes current status(not history) of development process. All these fields, finally, go to feed file while publishing new version.
+
* One or more [[Platform_Team/Recipe_Specification#Use case sections|use case sections]].
 +
* 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.
  
=== [Service] section ===
+
These files need to be placed in the root sources directory with names {{Code|sweets.recipe}} or {{Code|activity/activity.info}} for Sugar activities.
  
File ''service.info' should contain at least ''[Service]'' section:
+
=== Writing recipes ===
  
* ''name'', the identity of service, this field defines name of feed's root directory on the server http://download.sugarlabs.org/services/ as well
+
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:
* ''summary'', short descriptive line
 
* ''description'', long descriptive line, to wrap long text, all lines after second, should start with spaces<br>could be omited to reuse ''summary'' field
 
* ''license'', in 0install, typically a Trove category, as used on freshmeat.net, but could be [http://fedoraproject.org/wiki/Licensing#Good_Licenses fedora names], since the rest of sugar uses them
 
* ''homepage'' web link to project home page
 
  
=== [Runtime] section ===
+
* ''Activity'' for Sugar activities,
 +
* ''Application'' for stand alone applications,
 +
* ''Library'' for libraries.
  
This section describes parameters that should be taken into account only if service has 0install implementations(including source implementations) in contrast with [[Documentation Team/Services/Native packages usage|pure]] wrappers around native packages.
+
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.
  
Section contains:
+
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.
  
* ''version'', used only for services with [[#Native_versions|native]] versioning scheme
+
If the sweet needs to be built, add [[Platform_Team/Recipe_Specification#.5BBuild.5D|Build]] section.
* ''binding'', what environment variables, 0install should export to session which uses this service
 
binding = [prepend|append|replace] ''<variable-name>'' [''<insert-text-to-prepand-variable-value>''] [; ...]
 
* ''main'', for applications, path to exec file from service root directory
 
* ''requires'', for any arch and binary implementations, list of runtime services that should exist before using service
 
requires = <service-name> [<not-before-version>[-<before-version>]] [; ...]
 
* exec, command how to make bundle for ''dist'' command, ''0sugar'' will pick up newly created file in service root directory<br>Shell command, executed from service root directory. If this command starts to get complicated, you should move it to a script and just set this attribute to the command to run the script.<br>By default ''0sugar'' just bundle entirely service directory excluding temporary files.
 
exec = make distcheck
 
  
=== [Library] section ===
+
If built files are platform dependent, add [[Platform_Team/Recipe_Specification#Archive_sections|Archive]] section with ''arch=any'' option.
  
Adds additional parameters if service is a library. Libraries should have plain ''version'' value and with ''age'' field, it will be used in [http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html#Libtool-versioning libtool] like style e.g. in [[#Autotools|autotools]] based projects.
+
=== Interfaces ===
  
Section contains:
+
The ''implement'', ''associate'' and ''requires'' (optionally) options contain [[Platform_Team/Sweets/Glossary#Short_form_for_sweet_interfaces|short interfaces]]. These values have two meanings:
  
* ''age'' libtool like age of version
+
* 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.
  
=== [Buildtime] section ===
+
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.
  
File ''service.info'' could have optional ''[Buildtime]'' section which describes additional parameters that should be taken into account during other service(which uses this one) building i.e. it is an equivalent for *-dev(el) packages in GNU/Linux distributions.
+
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.
  
Section contains:
+
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.
  
* ''requires'', additional dependencies that will be required during building other service which depends on this one
+
See OBS [https://packages.sugarlabs.org/project/list_public projects] for all existed sweets.
  
* ''exec'', command how to make buildtime bundle for ''dist'' command<br>Shell command, executed from service root directory. If this command starts to get complicated, you should move it to a script and just set this attribute to the command to run the script.<br>By default ''0sugar dist'' uses the same bundle as for runtime feed
+
=== Dependencies ===
  
* ''generate-documentation'', if set, documentation project will be created on [http://api.sugarlabs.org/services/], for now only ''epydoc'' value is supported
+
Dependencies might be used in the ''requires'' and ''suggests'' options in recipes files to declare that the current sweet depends on another sweet/s.
  
=== [Build] section ===
+
The format of a dependency string is:
  
If service contains binary implementations, this section should present to describe building process.
+
<interface> [(=|>=|<) <version>]
  
Section contains:
+
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.
  
* ''requires'', what services should be installed before building this one from sources
+
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.
requires = <service-name> [<not-before-version>[-<before-version>]] [; ...]
 
  
* ''exec'', command how to build binaries<br>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.<br>'''NOTE''': This command will be executed not only in service developer environment but also on user side if proper binary wasn't found, so do not use here any development related commands like ''autogen.sh''<br>For example, followed command builds regular autotools based project
+
=== Stability status ===
exec = "$SRCDIR"/configure --prefix="$DISTDIR" && make install
 
  
=== Support several ABIs of service dependencies ===
+
Sweets should have stability status:
  
File ''service.info'' could contain other sections for various binary implementations. These sections are intended to describe particular dependencies environment and should contain only:
+
* ''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'',
  
* ''requires'' that overwrite ''Service'''s section ''requires''
+
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.
  
For example if service developer is going to add binary implementations for f9/f11, and the same service dependency in these distributions has different ABIs, activity developer has to build two additional binaries, for f9 and f11. In that case developer creates two sections ''F9'' and ''F11'', put exact dependency versions(to separate particular section from others) and invoke ''0sugar dist_bin <section-name>'' in proper f9/f11 environment.
+
=== Glob patterns ===
  
== 0sugar tool ==
+
The ''include'' and ''exclude'' options contain file patterns. A pattern could be of two types:
  
To start developing services, install [http://0install.net/injector.html injector] tool, and ''0sugar'' - main tool to maintain services infrastructure.
+
* 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
  
0alias 0sugar http://download.sugarlabs.org/services/0sugar/runtime.xml
+
Only these pattern symbols are allowed:
  
While working, ''0sugar'' creates ''dist/'' directory in project's root and uses it as a rsynced copy of service's directory on the server. So, you need ssh access to sunjammer server, create ticket for ''shell.sugarlabs.org'' category on http://bugs.sugarlabs.org/.
+
* ''*'' matches everything, except directory separator
 +
* ''?'' matches any single character, except directory separator
 +
* ''**'' matches everything, including directory separator
  
''0sugar'' commands are:
+
=== Examples ===
  
* ''init'', create service/ directory and default service.info file
+
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.
* ''clone'', rsync entirely dist/ from the server
 
* ''dist'', create source or any arch tarball/implementation in ''dist/'' directory and tweak ''dist/feed.xml'' correspondingly<br>If there is second option-less argument, it will be treated as a path of tarball to release(e.g. you can create such tarball by ''make distcheck'' command for autotools based projects), otherwise ''0sugar'' will tar all project files(and try to avoid temporary files as much as possible)<br>''dist'' will create
 
** any arch archive, if ''build-command'' field was omitted in ''service.info''
 
** source archive, if ''service.info'' has ''build-command'' field
 
* ''dist_bin'', create binary tarball/implementation for current arch in ''dist/'' directory and tweak ''dist/feed.xml'' correspondingly<br>if second argument was passed, it will be treated as a name of ''service.info'' section with additional ''requires'' fields
 
* ''push'', rsync dist/ to the server
 
* ''lint'', check feed file on the server<br>will run [http://0install.net/feedlint.html FeedLint] application for http://download.sugarlabs.org/services/ feed
 
  
Feed files in ''dist/'' directory could be changed manually but keep in mind that ''dist*'' commands will rewrite entries for current service version.
+
'''Python activity'''
  
== Development workflows ==
+
Python-based activity with standard Sugar Platform dependencies.
  
How to build services.
+
[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
  
=== Any arch services ===
+
'''Python library'''
  
Work flow for services that don't require compilation stage thus could be just packaged and used as is on server side:
+
A python-based library that could be used as is, or as an activity dependency.
  
* create local initial service.info by invoking ''0sugar init'', tweak newly created ''service/service.info'' file
+
[Library]
* increase/change version field in ''service.info'' file
+
implement = libjournal
* ''0sugar dist'' to change local feed in ''dist/'' and place there tarball
+
name      = libjournal
* ''0sugar push stable'' to rsync changed files from ''dist/'' to the server<br>see [[#Release workflows]] for other release scenarios
+
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
  
=== Binary services ===
+
'''C-based library'''
  
Work flow for services that require compilation stage:
+
[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
  
* create local initial service.info by invoking ''0sugar init'', tweak newly created ''service/service.info'' file
+
== Releasing ==
* provide relevant value for ''build-command'' field in ''service.info'' file
 
* if you want to support binaries for different dependencies environments, add additional sections to ''service.info'' file with ''requires'' fields that describe dependencies versions of particular environment
 
* increase/change version field in ''service.info'' file
 
* ''0sugar dist'' to add sources tarball to ''dist/'' and change local feed correspondingly
 
* on every platform, you are trying to support binaries for, run ''0sugar dist_bin'' to build, and add to local field, binaries for this particular platform
 
* if you added additional sections to ''service.info'', run ''0sugar dist_bin <section-name>'' in every environment, ''services.info'' has additional sections for
 
* ''0sugar push stable'' to rsync changed files from ''dist/'' to the server<br>see [[#Release workflows]] for other release scenarios
 
  
== Versioning scheme ==
+
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.
  
There could be two different versioning scheme for services.
+
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).
  
=== Upstream versions ===
+
To initiate releasing, enter from the sweet sources directory:
  
If service is just a wrapper around existed project with its own versioning scheme then there is even no need in any mentioning of versions in service.info file. Particular version will be chosen on every ''0sugar dist*'' command invoking or will be fetched from native packaging systems(if service doesn't provide binaries and [[Documentation Team/Services/Native packages usage|only]] contains information about already well packaged in various GNU/Linux distributions).
+
sweets commit
  
=== Native versions ===
+
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.
  
The rest of services will use scheme:
+
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.
  
<version>-<revision>
+
== Development with Sweets ==
  
* <version> is a ''version'' field from service.info file which is a plain number
+
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:
* <revision> is an auto incremented number which is beeing changed by ''0sugar push'' command (like Subversion revision)
 
  
Commands ''dist'' and ''dist_bin'' rewrite releases with the same ''version'' versions and don't remove other releases.
+
* 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.
  
[[#Library_section|Libraries]] have also ''age'' parameter which is [http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html#Libtool-versioning libtool] like age version part. ''age'' won't be exposed in version string but will be present in feed files and 0sugar will check it while deciding what dependency version should be chosen.
+
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}}.
  
== Stability status ==
+
=== Sugar sweets ===
  
One of core differences from 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 stability [http://0install.net/interface-spec.html#id4091477 statuses]:
+
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.
  
* ''stable'', final stable release
+
Checkout sources from:
* ''testing'', let interested in testing people, try last changes that are not yet stable
 
* ''developer'', just 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 upgrade to new bugfix version
 
* ''insecure'', extreme version of ''buggy''
 
  
''0sugar push'' w/o arguments will push local changes as is. If you want to push with particular stability status, use ''0sugar push <status>''.
+
* 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
  
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 [[#Bugfix_releases|bugfix releases]] workflow.
+
and see its {{Code|sweets.recipe}} files.
  
== Release workflows ==
+
== Developing activities ==
  
Useful scenarios for service release process.
+
How Sweets might be useful while developing activities.
  
=== Having only stable releases ===
+
=== Manage sources ===
  
All releases of your services will have ''stable'' stability status.
+
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:
  
* when your code is ready to release
+
* 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);
* ''0sugar dist''/''0sugar dist_bin'' to make local releases
+
* 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;
* ''0sugar push stable'' to rsync local releases to the server
+
* The {{Code|sweets}} command already contains development related functionality; it is useful to keep all development related functions in one utility.
* if it was wrong time to release and you want to re-release it, repeat previous steps to rewrite wrong release
 
  
=== Bugfix releases ===
+
Sweets support the following {{Code|setup.py}}'s commands:
  
Services assume simple versioning scheme, if you found bugs in stable version:
+
* {{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.
  
* either ''0sugar push stable'' release once more(users will not mess this new copy of release with previous ones)
+
And doesn't support the following:
* or ''0sugar push stable'' release with incremented ''version'' field
 
* if bugs are critical, mark previous release as ''buggy'' or ''insecure'' to force users 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]}
+
* {{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;
 +
* {{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;
 +
* {{Code|install}} - function installs the activity to the root system.  Sweets avoid, by design, any global changes during its regular behaviour.
  
=== Development 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.:
  
If you want to test your new version among interested people:
+
sweets build [PATH]
  
* do all steps that are mentioned in previous workflows
+
=== Launch activity ===
* but use either ''testing'' or ''developer'' status for ''push'' command
 
* users who interested in testing(enabled testing mode) will get your new development version
 
* you don't have to change ''compatibility-version'' and ''version'' all time for micro releases, ''0sugar'' will implicitly change revision of new pushes and user's saccharin will download last changes
 
  
== Development tools support ==
+
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).
  
Useful addons to popular development tools. These are optional features that simplify service development process.
+
== Good practices ==
  
=== Autotools ===
+
=== Devel packages ===
  
Add [http://git.sugarlabs.org/projects/toolkit/repos/mainline/blobs/master/m4/service.m4 service.m4] macros file to your project. It provides:
+
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.
  
* ''SERVICE_INIT'' macro to initialize services support, use it after other (AC|AM)_INIT macros like in [http://git.sugarlabs.org/projects/toolkit/repos/mainline/blobs/master/configure.ac]<br>It takes optional string to define prefix value for ''DIST_'' variables,  in most cases it should be just ''sugar''<br>Macro exports follows variables:
+
Keep all build-time files in the sweet with runtime files.
** ''SERVICE_NAME'', name of service in service.info file
 
** ''SERVICE_VERSION'', version of service in service.info file
 
** ''SERVICE_REVISION'', revision number from dist/revision file
 
** ''DIST_NAME'', combines prefix macro argument with ''SERVICE_NAME'' to use it as a distribution name(see example below)
 
** ''DIST_VERSION'', combines ''SERVICE_VERSION'' and ''SERVICE_REVISION'' to use it as a distribution version(see example below)
 
** ''SERVICE_SUMMARY'', summary from service.info file
 
** macro also changes ''PACKAGE'' and ''VERSION'' variables with values from proper ''DIST_'', so it rewrites ''AC_INIT'' arguments(you have to use fake values for ''AC_INIT'' macro)
 
** if ''[Library]'' section exists in service.info file, macro will
 
*** check if ''SERVICE_VERSION'' is a plain number
 
*** export ''SERVICE_AGE'', age from ''[Library]'' section
 
*** export ''SERVICE_LIBRARY_VERSION'' which is libtool's -version-info parameter
 
*** if ''service.pc.in'' presents in root directory, rename it to ''DIST_NAME''.pc.in
 
  
* ''SERVICE_ECHO'' convenient macro to print various variables
+
=== Transparent behaviour ===
  
These macros could be used like in [http://git.sugarlabs.org/projects/toolkit/repos/mainline/trees/master Toolkit] serivce.
+
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.
  
== Tips ==
+
== Feedback ==
  
* Via ''binding'''s variables, service's root directory will be accessible for service users, so for python services(for example), better to use subdirectory for service's import modules like [http://git.sugarlabs.org/projects/toolkit/repos/mainline/trees/master Toolkit] does - there is ''toolkit'' subdirectory in Toolkit's root.
+
{{:Platform_Team/Sweets/Feedback}}
 
 
* Be careful with machine architecture, especially in making binaries in VMs e.g. XO-1 arch is i586 but built in XO VM, binaries could have i686 thus won't start(0install won't let) on XO-1. Use --arch 0sugar's argument to set targeted architecture explicitly.
 
 
 
== Documentation ==
 
 
 
* [http://0install.net/injector-packagers.html Packaging guide] for 0install packages
 
* [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 01: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).