PMSes are most commonly found in free and open source UNIX-like operating systems, such as the various GNU/Linux distributions and free BSDs. There are also a few for Mac OS X, but very few, if any, can be found for Windows.
I will not be going too far into the details of package management in this article, because that is not its point. This article is about a package manager that I am developing. Code name (and possibly normal name in the future):
For more information on PMSes, please visit Wikipedia.
I am developing a package management systems inspired by the Slackware and MacPorts package management systems. It will be able to install two types of packages: Source and Binary packages (as with the RPM Package Manager). Source packages will function similarly to MacPorts Portfiles and RPM Specfiles. They will contain instructions on fetching, verifying, extracting, installing, and then later uninstalling software.
Source Package Format #1Each package will get its own directory. In this directory, there will be a series of files:
static.yml: This file will contain static (non-scripted) information about the package, such as metadata (title, description, etc.) and dependencies.
features.lst: (Produced by Candy, deleted if
--dont-save-featuresis specified.) See below: Compile-Time Features.
fetch.sh: This file is a Bourne Shell script that will download and verify (via WHIRLPOOL, SHA512, and RMD160 checksums) the source code. This script should not re-download archives unless the checksums do not match. If the downloaded archive still does not match, then it should exit with code
build.sh: This file will compile and install the files. It will compile the files to install to locations that are specified by Candy's configuration file, but will actually install the files into a temporary directory via a
make install DESTROOT=/tmp/blah).
preinstall.sh: (Optional) this file will be executed before files are installed into the root directory.
postinstall.sh: (Optional) this file will be executed after files are installed into the root directory.
predeinstall.sh: (Optional) this file will be executed before files are uninstalled.
postdeinstall.sh: (Optional) this file will be executed after files are uninstalled.
patches/*.patch: (Optional) patch files to be applied to the source archive post-extraction.
source/: Unextracted sources. This will be produced by
fetch.sh. This directory will be deletable with the
source-archive.*: May be an archive or a directory checked out with a version control system. If it was a VCS checkout,
source/will be a symbolic link, and the directory should have the
.vcsextension. This will be produced by
build.shwill be called. However, there are two things that may happen after
build.shexecutes, depending on the command specified to Candy. The two commands are:
install: This command will run
preinstall.sh, move the files into the root directory, and then run
postdeinstall.shfiles will be saved for whenever the program gets deinstalled.
build-binary: This command will create an archive from the temporary files which will also include the pre- and post-scripts. This package is faster to install, does not require any development utilities in most cases, but is not configurable and less portable.
Source Package Format #2Another format that will be supported is an archive that contains the files
postdeinstall.sh(all files but
features.lst). Along with these files will be the downloaded source files. This is more similar to RPM, while the previous format is more similar to MacPorts.
Binary Package FormatYet another format that will be supported is an archive that contains the files
postdeinstall.sh(all files but
build.sh). It will also contain the built program binaries (produced by
build.sh) which will be extracted into the root directory.
Compile-Time FeaturesLike MacPorts and Portage, Candy will support Compile-Time Features (in Portage talk, USE flags). They can be enabled with
-fand disabled with
-F, and all features are enabled by default.
static.ymlwill contain summaries/descriptions of these features, and information about which features are enabled/disabled will be saved in
features.lst. The various scripts will use
features.lst, a list of enabled features separated by newlines, to determine which features to include.
Initially, I was planning to have
static.ymltruncated in Binary Package Format, but I decided that it was useful for users to have information about which features were enabled/disabled by the binary package author.
DialogsPackages will be passed the variable
$DIALOG, which will evaluate to a program compatible with
dialogwhich will vary between the original program or a graphical replica.
Amendment 1: File Selection and Multi-Package OutputThis is an amendment to the previous section. It was added after the original article was written but before the article was published. I found that it would cause inconsistencies in the article to edit this in, so I decided to add it in this section. Further amendments will be posted in separate posts and linked to from here.
In the original design specified in this document, all of the files installed into a temporary directory are installed or archived in Source Package Format #2 or Binary Package Format. This amendment changes this:
static.ymlwill contain globs (a.k.a. wildcards) specifying which files in the temporary directory are to be installed or archived (where
/**/*would specify all files recursively). All files are excluded by default, since certain files such as the GNU Info
dirfile should be excluded.
Furthermore, the globs may be specified to specific Binary Packages, meaning that although both Source Packages will see them all as one tree, multiple Binary Packages may be generated. By standard, architecture-specific files, non-architecture-specific files, documentation, and development files (headers and static libraries) will be in separate packages. All of them will share the same package root name, but have the following mechanism for distinguishing them (by standard):
packagerootname: Architecture-specific files.
packagerootname-share: Non-architecture-specific files (will be stored in just
packagerootnameif there are no architecture-specific files.
packagerootname-doc: Documentation files (man pages will be stored in
packagerootnameif there are no non-architecture-specific files).
packagerootname-devel: Development header files.
packagerootname-static: Static object files (if it is a library, that is).