Eggs in GroupServer

GroupServer is made up of many components, which are know as eggs. This guide is to help those that create components for GroupServer create eggs.

Step 1: Name the Egg

Unlike Zope 2 Products, the name of the egg is a pain to change. A lot depends on the name, and you cannot start anything without creating a name.

  • Names are in lower case.
  • The different parts of the name are separated by ".".
  • The name of an egg that is part of the GroupServer core starts with "gs".
  • The name of an egg that is an extension written for a client will start with the name of the client.
  • The name of the component comes next.

A typical example of an egg-name is gs.image, which is the component responsible for scaling and displaying images. It is possible to break up a egg into multiple parts, but this is rare. However, the gs.skin component is an example of this. In gs.skin each site gets its own egg, such as gs.skin.groupserver.

Step 2: Create the directories

The specific type of egg that we are creating is called a “develop egg”. They live in the src directory of your GroupServer installation. The directory structure for the egg is egg.name/egg/name:

  • For gs.image the dictories are gs.image/gs/image
  • For gs.skin.groupserver the dictories are gs.skin.groupserver/gs/skin/groupserver

The quickest and easiest way to create the directories is to use the -p flag to mkdir:

$ mkdir -p egg.name/egg/name

There is also a docs directory in the egg:

$ mkdir -p egg.name/docs

Step 3: Cut 'n' Paste Software Engineering

An egg always contains the following components. Download them to the new egg.

setup.py
The instructions to setuptools on how to build the egg.
setup.cfg
System-dependent instructions on how to set up the component.
README.txt
A short introduction to the component.
docs/HISTORY.txt
The major version changes betwen releases of the component.
.hgignore
The file that tells Mercurial to stop trying to version-control pyc and ~ files.

Step 4: Write the Readme

The README.txt is a description of the egg, and is written using ReStructuredText wiki markup. I like writing the README early, as it helps me think about the egg.

Step 5: Configure the Egg

Most of the configuration for the egg is in setup.py. Some of the options you will need to change, some you will not.

version
The version of the egg. It is a string, so it can contain things like 1.3b12 or 2.0rc4. The version will be modified for each new release of the egg, and it will make up of the egg-name when egg is built. For some reason we declare the version as a variable; I do not question such things as it does not seem to hurt anything.
name
The name of the egg has already been decided, so write the full name in here as a string.
description
A one line description of the component. This is equivalent to the title attribute of Zope 3 schema attributes. The long_description is automatically set to the contents of the README.txt and HISTORY.txt files in our standard setup.py.
classifiers
A list of strings, where the strings are from the list of classifiers on PyPI. These classifiers are used by PyPI to organise packages. While GroupServer is not on PyPI, we hope to get it there. Do not bother too much with the classifiers for client-specific components.
keywords
A string of space-seperated kewords that describe the component.
author and author_email
Your name and email address, if you are the main person responsible for the component.
url
For a GroupServer component this should be set to http://groupserver.org/, otherwise it is the URL of the client's site.
licence
For client-specific code this should be set to other, otherwise set it to GNU GPL.
namespace_packages
The list of packages that appear as a name only and make up the name of the egg. The only namespace package listed is normally gs in a GroupServer package ― but sometimes there are others, such as gs.skin, are listed.
install_requres
A list of components that this egg relies on. All eggs rely on setuptools, but they may also rely on some other eggs.

Step 6: Initialise the Namespace Packages

Namespace packages a packages that exist in name only. A little bit of voodoo is required to create a namespace package. The first part is to list the namespace package in setup.py. The second part is to write this __init__.py to every directory of the egg that is part of a namespace package. So for gs.image it will be written to the gs.image/gs directory. For gs.skin.groupserver it will be written to gs.skin.groupserver/gs and gs.skin.groupserver/gs/skin directories.

Step 7: Code!

Your code actually sits at the bottom of the folder hierarachy that makes up the egg-name. For gs.image the code sits in gs.image/gs/image; for gs.skin.groupserver the code sits in gs.skin.groupserver/gs/skin/groupserver. Everything in the code folder looks like a Zope 2 product.

  • There could be more folders underneath this folder, such as browser, test, or sql. These folders can contain a hierarachy of folders.
  • The folder needs to contain an __init__.py, so Python recognises the folder as a module. However, the file can be empty: $ touch __init__.py
  • The configure.zcml for the code sits in this folder.
  • Python files are normally stored in this folder.

Step 8: Builout

Buildout now needs to be told of your develop-egg. At the top of your GroupServer install there should be a file buildout.cfg, and your develop-egg is mentioned in it three times.

  1. In the develop part of the buildout section add the relative path to the egg: src/egg.name. This tells buildout that there is a develop-egg there, which it should use rather than a normal egg.
  2. Add the egg name to the eggs part of the instance section. This tells Zope that the egg exists.
  3. Add the egg name to the zcml part of the instance section. This tells Zope to read in the confgure.zcml in the egg when the instance is started.

Now buildout has to be run. At the top of your GroupServer install run the following.

$ bin/buildout -vN

You should see your egg mentioned in the output of buildout.