Snapcraft filesets


#1

A fileset is used within snapcraft.yaml to represent a group of files, or a single file, when creating a snap.

They’re useful when moving files into the stage and prime areas of the build process (see Snapcraft lifecycle for more details) as they can be referenced individually, rather than always having to construct a list of filenames.

A fileset is implemented as a YAML map between the fileset name (the key) and a list of corresponding filenames for each fileset. This list can be built from any of the following:

  • individual files, eg. [ bin/dnsmasq ]
  • subdirectory paths, eg. [ etc ]
  • wildcard globs, eg. [ usr/* ]
  • globstar globs, eg. [ lib/**/*.so* ]

The * (asterisk) wildcard glob returns all the files in that path. Conversely, adding an initial - (dash) will exclude the files in that path. For example, you could add usr/local/* then remove usr/local/man/* with the following:

filesets:
   allbutman: [ usr/local/*, -usr/local/man/* ]

Filenames are relative to the part install directory, eg. parts/<part-name>/install.

If you have used the organize keyword to rename files from your snapcraft.yaml part, your fileset will be built from filenames after they’re renamed.

Conflicting rules

Snapcraft does not attempt to aggregate conflicting rules from different filesets. For example, the following will stage usr/share/alsa despite its specific exclusion under exclude-alsa-files:

filesets:
  exclude-alsa-files:
  - -usr/share/alsa/*
  include-usr-files:
  - usr/*
stage:
- $exclude-alsa-files
- $include-usr-files

The solution is to state any necessary inclusions and exclusions within the same fileset, as shown in the following example:

filesets:
  include-usr-files:
  - usr/*
  - -usr/share/alsa/*
stage:
- $include-usr-files

Relevant Snapcraft source code

Search filesets in snapcraft/init.py at master · snapcore/snapcraft


The docs roadmap
Snapcraft.yaml reference
Snap documentation
#2

Note that Snapcraft doesn’t aggregate conflicting rules from different filesets, for example, the following recipe will still stage usr/share/alsa:

    filesets:
      exclude-alsa-files:
      - -usr/share/alsa/*
      include-usr-files:
      - usr/*
    stage:
    - $exclude-alsa-files
    - $include-usr-files

while this one works:

    filesets:
      include-usr-files:
      - usr/*
      - -usr/share/alsa/*
    stage:
    - $include-usr-files

#3

Thanks for mentioning this - it’s an important point which I’ve added to the main doc.