Producing skeleton files

Generally speaking anybody can write skeleton files, but like with packages themselves the best people to do it are the developers of the library themselves. Only they know the full versioning history of their product. Even if they don't want to write it themselves, it's a good idea to check with them that you did it correctly once completed.

The first thing is to allocate the software a root name, if they don't already have one. It is of vital important that once you've done this, you send a mail to the developers list or maintainers explaining what you've done. This way, if two or more people independently try to write skeletons or packages, there is a central meeting point where duplication of effort can be avoided. It's vital that the same piece of software does not have two root names.

Next, add a [Meta] section like the following and adapt as needed:

                
[Meta]
RootName: @foobar.org/foo
DisplayName: The foobar widget is a world changing program!
ShortName: foobar
Skeleton-Author: Firstname Lastname <a@b.c>
Skeleton-Version: 1

[Notes]
We'll fill this in shortly

[Test]
Code goes here.

The metadata should be self explanatory. Like specfiles, they can be translated. There is one optional section we haven't put into the skeleton here, that's the [Retrieval] section. We can leave this for now. If it's missing, autopackage writes one for you which just calls into the retrieve API.

The [Test] section is the most important. It's expected to set the INTERFACE_VERSIONS variable to a whitespace separated list identifying which interfaces the systems implementation of the foobar widget supports. There is no need to enumerate all of them, if your tests return "2.4 1.2" as the value of INTERFACE_VERSIONS this will be expanded out to "2.4 2.3 2.2 2.1 2.0 1.2 1.1 1.0" by autopackage for you, because of the IV rules.

Writing the tests is the bulk of the work in writing a skeleton. Autopackage provides several APIs you can use to help automate this task, but there is no obligation to use them. You are free to use any techniques you wish to examine the system. One restriction is you can't assume you have root, as autopackages can be installed without superuser priviledges.

The most common case will involve checking for an ELF shared library. To help with this, we provide the testForLib() function. Using this is straightforward, as it can produce output suitable for inclusion in INTERFACE_VERSIONS directly. In the most basic form this call returns 0 if the given library soname is found on the system, and 1 if not. This involves checking the linker cache and LD_LIBRARY_PATH. The -i switch to this function will cause it to produce a list of interface versions, so:

INTERFACE_VERSIONS=$( testForLib -i libfoo.so )

... will in most cases do the right thing. There is a large collection of example skeletons shipped as part of the developer tools, so you can see the test sections there for more complex examples.

The INTERFACE_VERSIONS variable can be stacked, eg:

                
INTERFACE_VERSIONS=$( testForLib -i libfoo.so )
vers=$( testForLib -i libfoo2.so )
for v in $vers; do
    INTERFACE_VERSIONS="$INTERFACE_VERSIONS 2.`getMinor $v`"
done

The mapping between system state and interface versions is arbitrary and up to you. If the project follows best practice and has software versions equal to interface versions, a good history of stability etc then it'll be quite straightforward to do this mapping - if it's more convoluted it won't be. You have freedom to do it however you like.

One thing to be aware of is that you cannot change the mapping after the fact. This would not be backwards compatible.