6. Developer's Guide
This a guide for developers working on the Zeek Package Manager itself.
6.1. Versioning/Releases
After making a commit to the master branch, you can use the update-changes script in the zeek-aux repository to automatically adapt version numbers and regenerate the zkg man page. Make sure to install the documentation dependencies before using it.
Releases are hosted at PyPi. To build and upload a release:
Finalize the git repo tag and version with
update-changes -R <version>if not done already.Upload the distribution (you will need the credentials for the 'zeek' account on PyPi):
$ make upload
6.2. Documentation
Documentation is written in reStructuredText (reST), which Sphinx uses to generate HTML documentation and a man page.
6.2.1. Dependencies
To build documentation locally, find the requirements in
requirements.txt:
# NOTE: Dependencies should go into `pyproject.toml`. We keep this file to e.g., support RTD. # Requirements for general zkg usage GitPython>=3.1.43 semantic_version>=2.10.0 # Technically not a zkg dependency, but typically expected by users to be present. btest>=1.1 # Requirements for development (e.g. building docs) Sphinx>=7.2.6 sphinx_rtd_theme>=2.0.0
They can be installed like:
pip3 install -r requirements.txt
6.2.2. Local Build/Preview
Use the Makefile targets make html and make man to build the
HTML and man page, respectively, or make doc to build them both. To view
the generated HTML output, open doc/_build/index.html. The generated
man page is located in doc/man/zkg.1.
If you have also installed sphinx-autobuild (e.g. via
pip3), there's a Makefile target, make livehtml, you can
use to help preview documentation changes as you edit the reST files.
6.2.3. Remote Hosting
The GitHub repository has a webhook configured to automatically rebuild the HTML documentation hosted at Read the Docs whenever a commit is pushed.
6.2.4. Style Conventions
The following style conventions are (generally) used.
Documentation Subject |
reST Markup |
Preview |
|---|---|---|
File Path |
|
|
File Path w/ Substitution |
|
|
OS-Level Commands |
|
cmd |
Program Names |
|
prog |
Environment Variables |
|
|
Literal Text (e.g. code) |
|
|
Substituted Literal Text |
|
|
Variable/Type Name |
|
x |
INI File Option |
|
name |
Python API docstrings roughly follow the Google Style Docstrings format.
6.3. Internals
6.3.1. zkg's view of a package
zkg maintains copies of a Zeek package in up to four places:
A long-lived clone of the package's git repo in
$STATEDIR/clones/package/<name>. This clone (not its installed version, see below) iszkg's "authoritative" view of a package.A conceptually short-lived clone in
$STATEDIR/scratch/<name>, for retrieving information about a package ("short-lived", because access to those copies is momentary -- not becausezkgnecessarily cleans up after those copies).A "stage". A stage is any place in which
zkgactually installs a package for running in Zeek. This can be the local Zeek installation, or locally below$STATEDIR/testingwhen testing a package. So "staging" here does not mean "not yet live"; rather the opposite: it's closer to "any place where the package may actually run". A stage allows customization of many of the directories involved (for internal cloning, installing Zeek scripts and plugins, binary files, etc). Installation into a stage is also wherezkgadds its management ofpackages.zeek, in the stage's scripts directory.In
$STATEDIR/testing/<name>/clones/<names>, for testing a given package along with any dependencies it might have.
zkg captures state about installed packages in $STATEDIR/manifest.json.
This does not capture all knowable information about packages, though.
More on this next.
6.3.2. Directory usage
zkg populates its internal state directory (dubbed $STATEDIR below) with
several subdirectories.
6.3.2.1. $STATEDIR/clones
This directory keeps git clones of installed packages
($STATEDIR/clones/package/<name>), packages sources
($STATEDIR/clones/source/<name>), and package template repositories
($STATEDIR/clones/template/<name>).
zkg clones the relevant repositories as needed. It can dynamically re-create
some of these directories as needed, but interfering in that space is not
recommended. For example, if you remove a clone of an installed package, the
installation itself will remain live (via the staging mechanism), but zkg
will no longer be able to refer to all information about the installed package
(because anything not explicitly captured about the package in
$STATEDIR/manifest.json is now gone).
Removal of a package (zkg remove) removes its clone in $STATEDIR/clones.
6.3.2.2. $STATEDIR/scratch
When retrieving information on a package that isn't yet installed, or where
zkg doesn't want to touch the installed code, $STATEDIR/scratch/<name>
is a clone of the package's git repo at a version (often a git tag) of
interest. This clone is shallow for any versions that aren't raw SHA-1
hashes. The information parsed includes the zkg.meta as well as git
branch/tag/commit info.
During package installation, zkg places backups of user-tweakable files into
$STATEDIR/scratch/tmpcfg. zkg restores these after package installation
to preserve the user's edits. During package source aggregation, zkg places
temporary versions of aggregate.meta directly into $STATEDIR/scratch.
Creation or unbundling of a package happens via $STATEDIR/scratch/bundle, to
compose or retrieve information about the bundle. The directory is deleted and
re-created at the beginning of those operations:
During bundling,
zkgcopies installed package repos from$STATEDIR/clones/<name>into$STATEDIR/scratch/bundle/<name>, and creates fresh git clones in thebundledirectory for any packages not currently installed. It creates a.tar.gzof the whole directory, initially in the bundle directory, and moves it to where the user specified.During unbundling,
zkgreads the bundle manifest as well as the git repos of the contained packages, and moves the package repos from the scratch space into$STATEDIR/clones/package/<name>.
When installing a package's script_dir or plugin_dir into a staging area
and the source file is a tarfile, zkg temporarily extracts the tarball into
$STATEDIR/scratch/untar/.
There's little or no cleanup of files in the scratch space after the operations
creating them complete. zkg only deletes, then (re-)creates, the directories
involved upon next use.
When zkg isn't in the middle of executing any commands, you can always
delete the scratch space without negatively affecting zkg.
6.3.2.3. $STATEDIR/testing
When testing a package (during installation, or when explicitly running zkg
test), zkg creates a staging area $STATEDIR/testing/<name> for the
package under test, clones the package and its dependencies into
$STATEDIR/testing/<name>/clones/, installs them from there into
$STATEDIR/testing/<name>, and then runs the package's test_command from
its clone ($STATEDIR/testing/<name>/clones/<name>), with an environment set
such that it finds the installation in the local stage. The stdout and stderr of
those testing runs is preserved into zkg.test_command.stdout and
zkg.test_command.stderr in that directory.
As in STATEDIR/scratch, there's no cleanup, and you can delete the testing
space as needed after a test run is complete.