Using the craftctl tool

The craftctl tool is bundled with snapcraft to help get and set metadata, and to run default actions, from scripts that override a build step.

It is only available when building snaps with a core22 base snap or higher.

From within an override script, craftctl can do the following:

Running the default action

When overriding a step, the default logic for that step will not be executed. Instead, the script you specify using override-* will run. In this script, the default logic for that step can be run with the craftctl default command.

For example, if you want to modify a file after pulling and before building, you can override the pull step, run the step using craftctl default, and change the sources.

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.in.in

Setting metadata

Metadata, such as the version or title of a snap, can be dynamically set within an override-* script using the craftctl set <key>=<value> command.

Replace <key> with the name of the value you want to change and <value> with what you want to change it to.

The following keys are supported:

  • version
  • grade

For example, if you want to set the version of a snap based on the git tags for a project, override the pull step with a script that first runs craftctl default before executing the craftctl set version assignment with the git command to retrieve the version information:

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 details on how a snap build can incorporate external metadata, see Using external metadata.

Caution:

Use adopt-info

To incorporate retrieved metadata correctly, ensure that adopt-info points to the part that runs craftctl set. Without this, snap metadata will not be updated.

Getting metadata

Current metadata values can be retrieved with craftctl get <key>. Replace <key> with the name of the value to retrieve. This command supports the same keys as Setting metadata.

For example, to append the git commit hash to snap version, override stage, run the default action, use craftctl get version to get the current version, and modify it:

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

Only version and grade should be available to be set with craftctl, these map the previously existing snapcraftctl set-version and snapcraftctl set-grade commands and are listed in the core22 migration howto.

From reading the code, more seem to be supported:

Although I might be misreading this completely.

These are fields that can be assigned using appstream metadata. Variables that can be assigned using craftctl set are defined by the application using craft-parts, because variables can be application-specific (for example “grade” makes sense in Snapcraft, but not in Charmcraft). Snapcraft defines the variables here:

Ok, thanks for the explanation! I fixed the doc.

1 Like

@galgalesh Thank you so much for your work on this. I’ll make sure it’s added to the navigation.

3 Likes

I might mention that since a popular use for “craftctl” is to set a Git-based version string, you can now do that with just “version:git”. I’m betting that covers the majority of uses for craftctl.

Thanks for the hint, but I think it’s still the case that version: git is somewhat deprecated, although it’s still working for me and is a convenient feature.

Ah, I thought it was the other way around, that “version: git” was the newer way. Noted, and will make changes to SC101 course to reflect this.

2 Likes

If you have one part that "craftctl set"s the version, and another part that gets that version, should you ensure that those parts are ordered properly with “after:”?

Indeed, otherwise you might get the wrong version, depending on how the build lifecycle is executed.

1 Like

I thought as much; that tidbit should be added to this page for completeness.