AKKU

NAME
SYNOPSIS
DESCRIPTION
PUBLISHING PACKAGES
BUGS
EXAMPLES
Updating the local package index
Quick start in a new project
Install dependencies step-by-step
ENVIRONMENT
FILES
AUTHOR
HISTORY
COPYRIGHT
SEE ALSO

NAME

akku - R6RS/R7RS Scheme language package manager

SYNOPSIS

akku [--debug] [--trace] {init directory | list | show pkg | install pkg[@version-range]... | update | add [--dev] pkg[@version-range] | lock | install | remove pkg... | uninstall pkg... | version | scan [directory] | publish [--version=version] [--tag=tag] | graph [directory] | dependency-scan --implementation=impl filename... | license-scan --implementation=impl filename... | archive-scan directory... | compat-scan filename...}

DESCRIPTION

Akku.scm is a project-based language package manager for R6RS and R7RS Scheme. It is mainly meant for programmers who develop portable programs or libraries in Scheme, but could potentially work for end-users of those programs. It also has a translator from R7RS, which allows most R7RS code to run on R6RS implementations.

Being project-based means that dependencies are local to each project you manage with Akku. Each project specifies its dependencies through a manifest and a lockfile. When working on a project, you run akku install and then .akku/env to start a new shell with that project’s environment variables set. This ensures that the code you load into your program is that of your direct or indirect dependencies, instead of something that just happened to exist somewhere in your load path.

A project’s direct dependencies are listed in the manifest. By running a dependency solver, specific versions of those dependencies are locked. The lockfile contains locations, cryptographic checksums and other information needed for Akku to install selected versions of all dependencies. This means that everyone using the same lockfile will get exactly the same dependencies installed as you.

This manpage mostly describes the command line interface, where these commands are available:
init
directory

Initialize a new project with a simple template that demonstrates a program, a library and a test. This is not necessary to start using Akku in an existing project. In that case you simply go to the root directory of the project and start running akku.

list

List the local package index. For each package in the index it shows the name (used in command line arguments), the version and a short synopsis. When used in the project directory it will read the manifest and the lockfile and use that information to highlight versions that match the dependencies.

show pkg

Display details about a package in the local package index. The first few sections are for your information only. Any dependencies are listed together with a simplified version range in braces. The source code section shows all information that will be used to download the package when it is installed.

install pkg[@version-range]...

Running install with a list of packages will add them to the package manifest, lock dependencies and install everything in the lockfile.

install

Run this command to rebuild .akku/lib. Also run this command after adding new libraries to your project since they need to be symlinked into .akku/lib.

This command follows the instructions in the lockfile to download and install the listed dependencies. A file scanner looks at each file in the downloaded projects and figures out what type of source it is and where it goes in the file system.

update

Updates the local package index. Use this to get access to the latest list of packages. It does not change your project in any way, apart from letting the lock command choose newer versions that were not previously available.

The index files are signed with GnuPG signatures that are verified before they are used. The SHA-2 implementation is a little slow, so this takes a few seconds.

add [--dev] pkg[@version-range]

Adds a package to the manifest using a version range that allows forwards-compatible upgrades. Optionally the range can be specified manually using the pkg@version-range syntax, e.g. semver@ˆ1.0.0. It’s also possible to edit the manifest by hand, but formatting will not be preserved by these commands.

The range notation is provided by the semver package.

The --dev option adds the package as a development dependency. Development dependencies are ignored when the package is used as a dependency by a third package (they are only needed when doing development on the current package).

lock

Locks dependencies. Runs a dependency solver over the manifest and the local package index and generates the lockfile. The lockfile contains the location of each transitive dependency together with a cryptographic identity.

It is wise to commit both the manifest and the lockfile in your source code repository. Neither are used by your reverse dependencies after a package has been published, but both are useful for yourself and other people.

remove pkg...

Updates the package manifest to remove dependencies, doing the opposite of add.

uninstall pkg...

Does three things: removes dependencies from the manifest, locks dependencies and runs install to remove the files that are no longer needed.

version

Print the Akku.scm version number to standard output.

scan [directory]

Scans a directory recursively and analyses all files. The result of the analysis is printed as a series of YAML documents (syntax might be a bit off: send bug reports). Useful for figuring out what type of code Akku thinks the repository contains.

publish [--version=version] [--tag=tag]

Guides you through publishing your package. It generates a package index snippet and asks if you want to submit it. If you answer yes then it fires up gpg to sign the displayed snippet, which is then submitted to the archive server.

The version to publish is taken from the manifest but can be overridden by using the --version=version option. By default it looks for a tag named vversion. It is possible to override the tag using the --tag=tag option if the repository does not use the v1.2.3 tagging scheme. If it does not find a tag then the published revision will match the current HEAD.

It is always the lock section of the printed index snippet that controls which revision is used for the published version. It is also the currently checked out manifest that will be used to populate the metadata of the index snippet; not the manifest that happens to be checked in under the revision.

There is no strong requirement to commit the manifest before publishing. This means that you can also publish other people’s repositories, even if you do not have commit rights.

See section PUBLISHING PACKAGES below for a checklist of things to go through before publishing.

This command requires gpg, a gpg key and curl.

graph [directory]

Runs the repository analyser and prints a digraph of library dependencies. It’s kind of a proof of concept at this point. Example usage: akku graph | dot -Tx11.

dependency-scan --implementation=impl filename...

Traces the dependencies of a set of program source files. At least one implementation should be specified. They are named by the short names used in sls filenames, e.g. ikarus.

license-scan --implementation=impl filename...

Does the same dependency scanning as dependency-scan, but then searches through all files it finds to look for license notices and similar legal text. This command is useful as a first step in gathering notices when distributing a compiled Scheme program.

Some words are worth repeating here: this program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

archive-scan directory...

Scans the given directories for *.akku files and gathers them into a single index file. This is used at repository servers as part of maintaining the archive.

compat-scan filename...

Scans the given files for Scheme implementation compatibility. The files should be programs or libraries. All their imports are recursively checked for compatibility and missing libraries are printed.

PUBLISHING PACKAGES

You can make R6RS packages available to other users through the central Akku.scm registry with the publish command described above. If your package is written in R7RS then please publish to Snow instead so that your package will also be available in other R7RS package managers. Here is a checklist of items to consider before publishing:

1.

Check that your manifest is up to date and contains at least the right package name, version, synopsis, at least one author and a license identifier.

2.

Version numbers must follow the SemVer specification. If you are packaging software that does not follow the SemVer rules then adjust the version numbers so that they follow the rules (they don’t need to match the original software exactly).

3.

Please pay some attention to the license field to make sure that it is accurate. Use the identifiers from the SPDX project, making sure to use an open source license.

4.

Prepare and publish your GnuPG key if you do not yet have one. If you’re not too particular on the details of this and just want a key that works then you can run gpg ---gen and answer the prompts. Afterwards you need to publish your key to the public key servers using the command gpg --keyserver pgp.mit.edu --send-keys keyID, using the key ID associated with your new key.

5.

Currently all projects need to be in a publicly available git repository, but this will change later. The release should preferably be tagged using their SemVer version numbers: version 1.0.0 gets tagged with v1.0.0. You can use git tag -s v1.0.0 to make a signed tag (and don’t forget to use git push --tags).

All packages in the index are signed with GnuPG signatures. This provides important benefits: third parties can verify the package index and the archive software can verify that a newly uploaded version came from same author as previously uploaded versions. The email on your GnuPG key is used to contact you if there are any questions.

Packages are manually reviewed before they are accepted into the package index. Ask in #akku on Libera.Chat if there are problems.

Publishing is meant to be easy and hassle-free after some initial setup, so please report any usability problems with the publish command.

BUGS

Implementation-specific language constructs such as modules and lexical syntax are handled rather poorly.

The conversion of R7RS code is not complete. It does not add quotes to vectors, which are self-quoting in R7RS but not in R6RS. If the R7RS code uses shared data at the lexical level then the written R6RS library will also use that and may end up not being loadable by a conformant R6RS implementation. The R7RS support needs the akku-r7rs package to be installed.

The lock command (and any command that uses it behind the scenes) does not preserve the versions of previously locked packages. This is planned to be fixed.

The Cygwin and MSYS2 ports do not support colons in filenames. This has the unfortunate consequence that Chez Scheme and SRFI 97-compliant SRFI distributions do not work on these platforms. Symlinks are also not supported.

Whereas GNU Guile 3.0 has the --r6rs command line argument, GNU Guile 2.2 does not provide a direct way to enable full R6RS support. It should be started with the flags -x .guile.sls -x .sls on the command line. Alternatively you can add these lines to your ˜/.guile:

(set! %load-extensions (append '(".guile.sls" ".sls")
%load-extensions))
(read-enable 'r6rs-hex-escapes)
(read-enable 'hungry-eol-escapes)

Please report bugs to GitLab issues or by email.

EXAMPLES

Updating the local package index

Right after installation and before doing anything else, it’s a good idea to update the local package index:

$ akku update

Quick start in a new project

A quick way to get a new project up and running is the init command:

$ akku init my-project
$ cd my-project
$ akku install
$ .akku/env

Use akku list to find some package you want to use, or browse the package list on the Akku website. When you want to install a package, e.g. json-tools, run akku install json-tools. This adds it to the package manifest, locks all dependencies to specific versions and rewrites .akku/ to the locked versions.

Install dependencies step-by-step

Dependencies can be installed step-by-step in order to follow the process:

$ akku add chez-srfi # writes Akku.manifest
$ akku lock # writes Akku.lock
$ akku install # updates .akku/

ENVIRONMENT

AKKU_LOG_LEVEL

log level: trace, debug, info, warning, error, critical

AKKU_ENV

informative variable; not used (set by .akku/env)

AKKU_R6RS

R6RS Scheme library path, for system libraries

AKKU_R7RS

R7RS Scheme library path, for system libraries

AKKU_PROJECTS

extra project directories to install into .akku/

AKKU_SETTINGS

comma-separated list of settings (see below)

XDG_CACHE_HOME

cache directory home (default: ˜/.cache)

XDG_DATA_HOME

data directory home (default: ˜/.local/share/)

HOME

user’s home directory

The AKKU_SETTINGS variable can contain these settings:

no-network

do not use the network (and fail if it would be needed)

no-dependencies

do not use any projects from the lockfile

copy-current-project copy (do not symlink) the current project

FILES

PREFIX/share/akku/bootstrap.db

the package index from the distribution

PREFIX/share/akku/keys.d

trusted keys for package indices

˜/.local/share/akku/keys.d/

extra trusted keys

˜/.local/share/akku/index.db

the latest package index

˜/.cache/akku

cached downloads

Akku.manifest

the package manifest

Akku.lock

instructions for installing dependencies

.akkuignore

files to ignore (no wildcards)

.akku/bin/

programs from packages; activate script

.akku/lib/

installed libraries from packages

.akku/ffi/

compiled libraries for use with an FFI

.akku/list

a list of files and whence they came

.akku/notices/

license notices from installed packages

.akku/src/

downloaded source code

AUTHOR

Written by G. Weinholt.

Thanks to everyone who has contributed to Scheme over the years.

HISTORY

The dependency solver comes from Andreas Rottmann’s dorodango, an earlier R6RS package manager, and he ported it from the solver in aptitude(8).

COPYRIGHT

Copyright © 2023 G. Weinholt. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

SEE ALSO

The project website: https://akkuscm.org/
The project wiki: https://gitlab.com/akkuscm/akku/wikis/home