I suggest covering the appstream ID details in a separate topic as it’s a red-herring here. The language for extracting details out of external files should support any kind of data that snapcraft supports, and the appstream ID will be just one of those details among many others. It will be handled correctly no matter what we end up with as the right thing for that one case.
So, focusing on the data extraction, I think we need to split the logic in two different actions: one of them defines what information is available in a given part, and another one defines what content to adopt. Otherwise, how would we tell which of the N parts a snap makes use of defines the actual content that represents the exposed functionality of the snap?
Defining what a part has to offer takes place inside the part definition itself, perhaps via a new parse-info field. The info term is somewhat general, but we’re already using it on the snap info side which exposes some of those details, and given that we’re qualifying it with the parse prefix it sounds reasonable.
It would look similar to:
parts:
part-one:
source: .
plugin: python
parse-info:
- setup.py
- data/appstream.xml
Instead of asking the user to define whether these paths are inside the build directory or the installation one, we can just look up in both. First the installed one, as that may have been processed and thus should have precedence, and then the build location. If both are missing, we error out clearly complaining about the inconsistency. Otherwise, the path and content are then introspected to find out which info parsing plugin to use, and the parsing then takes place extracting all known details out of the file.
Information defined inside files presented above in the list take precedence over files defined below, so in the example above if both setup.py
and appstream.xml
define a summary, the one from setup.py
is recorded for this part.
For the snap to actually use that data, though, the top-level adopt-info field must point to the specific part name containing the data. This way there’s no risk for bogus data to be injected into a snap because one of its parts suddenly makes information available, nor any ambiguities if multiple parts define their own information sources.
adopt-info: part-one
With that, all information parsed out of the given part is imported into the snap definition as long as it hasn’t been defined explicitly locally. In other words, any details defined locally in snapcraft.yaml take precedence over anything parsed out of the defined part. This allows importing external details while still overriding and polishing specific fields as required.
How does that sound?