Customize lifecycle steps and project variables

Snapcraft ships with craftctl, a utility for executing steps in parts. When defining a part, you can use it to customise the part’s files and build environment before and after a step.

Declare an override key

You can customise the lifecycle steps for any part in your snap. Overriding the step is achieved through the part override-* keys, which execute a scriptlet at that step. The scriptlet is executed with /bin/bash.

If an override key is declared at all, it entirely replaces the step’s normal behavior. Instead, whatever code in the key, even no code, is executed.

In the general case, you can override any step with this structure:

parts:
  <part-name>:
    override-<step>: |
      # Scriptlet code

Replace <step> with the name of a step in the lifecycle.

Override a step

Craftctl comes in most handy when when you need to tweak files or settings before or after executing a step.

To specify where the regular step behavior occurs inside the scriptlet, call it with the special craftctl default command. Using that command as an anchor point, alter the build files or environment with other commands before or after it.

Don’t forget to execute the step

If you don’t call craftctl default inside a scriptlet, the step is skipped, and the part doesn’t finish building.

Let’s say you want to modify a file copied from a part’s source. You would add an override for the pull step with the override-pull key, run the default step with craftctl, then change the copied source file.

The following example does just that. The icon path inside the part’s desktop file in the is tweaked after downloading it, but before Snapcraft builds it.

parts:
  gnome-text-editor:
    source: https://gitlab.gnome.org/GNOME/gnome-text-editor
    override-pull: |
      craftctl default
      sed -i.bak -e 's|Icon=@app_id@$|Icon=snap.gnome-text-editor.icon|g' data/org.gnome.TextEditor.desktop

Override project variables

With craftctl, you can dynamically set project variables specific to Snapcraft – distinct from environment variables – within an override scriptlet. Set values with:

craftctl set <key>=<value>

You can also retrieve the current value of a project key, with:

craftctl get <key>

The version and grade keys are supported.

To incorporate retrieved package information correctly, point adopt-info to the part that runs craftctl set. Without such a connection, the snap fails to build. You can find more guidance on sourcing information in External package information.

Example solutions

For example, if you want to set the version key of a snap to the latest Git tag in a part’s source, declare this override:

Project file
adopt-info: gnome-text-editor
parts:
  gnome-text-editor:
    source: https://gitlab.gnome.org/GNOME/gnome-text-editor
    override-pull: |
      craftctl default
      craftctl set version=$(git describe --tags --abbrev=10)

For another example, let’s say a snap has a manually-set version number in the project file. To append the latest Git commit hash to the version, declare this override:

Project file
version: "1.0"
adopt-info: gnome-text-editor
parts:
  gnome-text-editor:
    override-stage: |
      craftctl default
      craftctl set version="$(craftctl get version)-$(git rev-parse --short HEAD)"