Scripting and setting metadata in snapcraft

Sometimes, sometimes, declarative is not enough, one needs to get out of convened norms and do ones own thing.


To solve that we previously introduced these three primitives: prepare, build and install. They lived around the build step of a plugin’s lifecycle where prepare would run before the build logic of a plugin, build would replace this logic and install would run after the build logic of a plugin.

Many problems were solved with this, but it is not clear from the get go what and when things will happen.

With scripting in mind, we additionally introduced the concept version-script which would run at the end of the prime step where the script would be required to echo the string of what the version would be set to. Again, useful, but not clear. Added to that, we introduced a magic stanza in version which when set to git would do some automatic magical version tricks with git’s annotated tags.


Taking a step back, this is what we should have done and may make its way bit by bit.


Of the current steps a part can have today:

  • pull
  • build
  • stage
  • prime

Of which pull and build are implemented by the plugin, we will be introducing a backwards compatible change and adding a new step a plugin can implement, so that the lifecycle steps for are part become:

  • pull
  • build
  • install
  • stage
  • prime


Instead of having random keyword names for which you have to know live around the build step we will make it so that you can:

  • pre-pull
  • pull, replacing the logic of the plugin’s pull
  • post-pull
  • pre-build
  • build, replacing the logic of the plugin’s build
  • post-build
  • pre-install
  • install, replacing the logic of the plugin’s install
  • post-install
  • pre-stage
  • stage, (TBD replacing the core logic of how files are migrated to stage)
  • post-stage
  • pre-prime
  • prime, (TBD replacing the core logic of how files are migrated to prime)
  • post-prime

Setting metadata

Instead of have a version-script and a grade-script you will be able to call:

  • set-version <version-string>
  • set-grade <stable|devel>

From any of the scripting entry points defined before.

Metadata plugins

Some projects are already well defined and to have to yet again define things in snapcraft.yaml is a cumbersome and error prone process, to address that we will introduce a new plugin concept orthogonal to the building plugins that would allow you to consume this metadata and set things like the summary, description, license, …

To illustrate better, metadata plugins would be named something like this:

  • appstream
  • python
  • maven

Which will have a sole purpose would be to consume metadata and pass it on to snapcraft. There will be a more design oriented post for this specific one so people can get into the nuts of it, but didn’t want to leave it out from the big picture of this whole change.


This came up in another thread, but if you’re updating the way scriptlets are handled by snapcraft, I think it would be worth running them with the -e shell flag.

With the current system, I can create a scriptlet like this:

install: |
    false   # or some other command that will fail
    true    # or some other command that will succeed

And the scriptlet will run successfully. I can make this fail by adding set -e to the top of my scriptlet, but for people who are used to working with Makefiles (or similar cases like debian/rules files, or RPM spec files), this behaviour is surprising. I’d much prefer a scriptlet like this to fail by default and require me to explicitly ignore return values if I don’t care about a particular failure.

Maybe the behaviour of the existing scriptlet extension points needs to remain the same for compatibility, but I think it would be worth changing the behaviour for all the new ones.


This should be the case for prepare, build and install today, the fact that the implementation does not follow this should just be a bug.


Fair enough. I’ve filed a bug report here:

what a perfict solution …