Skip to content

Commit

Permalink
feat(snap): ability to specify slot properties (#5313)
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy committed Nov 28, 2020
1 parent 552f1a4 commit 1235c4e
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 23 deletions.
27 changes: 25 additions & 2 deletions packages/app-builder-lib/scheme.json
Expand Up @@ -4341,6 +4341,19 @@
],
"type": "object"
},
"SlotDescriptor": {
"additionalProperties": {
"anyOf": [
{
"typeof": "function"
},
{
"type": "null"
}
]
},
"type": "object"
},
"SnapOptions": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -4607,17 +4620,27 @@
},
"slots": {
"anyOf": [
{
"$ref": "#/definitions/PlugDescriptor"
},
{
"items": {
"type": "string"
"anyOf": [
{
"$ref": "#/definitions/SlotDescriptor"
},
{
"type": "string"
}
]
},
"type": "array"
},
{
"type": "null"
}
],
"description": "The list of [slots](https://snapcraft.io/docs/reference/interfaces)."
"description": "The list of [slots](https://snapcraft.io/docs/reference/interfaces).\n\nAdditional attributes can be specified using object instead of just name of slot:\n```\n[\n {\n \"mpris\": {\n \"name\": \"chromium\"\n },\n }\n]\n\nIn case you want your application to be a compliant MPris player, you will need to definie\nThe mpris slot with \"chromium\" name.\nThis electron has it [hardcoded](https://source.chromium.org/chromium/chromium/src/+/master:components/system_media_controls/linux/system_media_controls_linux.cc;l=51;bpv=0;bpt=1),\nand we need to pass this name so snap [will allow it](https://forum.snapcraft.io/t/unable-to-use-mpris-interface/15360/7) in strict confinement."
},
"stagePackages": {
"anyOf": [
Expand Down
22 changes: 21 additions & 1 deletion packages/app-builder-lib/src/options/SnapOptions.ts
Expand Up @@ -71,8 +71,24 @@ export interface SnapOptions extends CommonLinuxOptions, TargetSpecificOptions {

/**
* The list of [slots](https://snapcraft.io/docs/reference/interfaces).
*
* Additional attributes can be specified using object instead of just name of slot:
* ```
*[
* {
* "mpris": {
* "name": "chromium"
* },
* }
*]
*
* In case you want your application to be a compliant MPris player, you will need to definie
* The mpris slot with "chromium" name.
* This electron has it [hardcoded](https://source.chromium.org/chromium/chromium/src/+/master:components/system_media_controls/linux/system_media_controls_linux.cc;l=51;bpv=0;bpt=1),
* and we need to pass this name so snap [will allow it](https://forum.snapcraft.io/t/unable-to-use-mpris-interface/15360/7) in strict confinement.
*
*/
readonly slots?: Array<string> | null
readonly slots?: Array<string | SlotDescriptor> | PlugDescriptor | null

/**
* Specifies any [parts](https://snapcraft.io/docs/reference/parts) that should be built before this part.
Expand Down Expand Up @@ -108,4 +124,8 @@ export interface SnapOptions extends CommonLinuxOptions, TargetSpecificOptions {

export interface PlugDescriptor {
[key: string]: {[key: string]: any} | null
}

export interface SlotDescriptor {
[key: string]: {[key: string]: any} | null
}
21 changes: 17 additions & 4 deletions packages/app-builder-lib/src/targets/snap.ts
Expand Up @@ -47,6 +47,9 @@ export default class SnapTarget extends Target {
const plugs = normalizePlugConfiguration(this.options.plugs)

const plugNames = this.replaceDefault(plugs == null ? null : Object.getOwnPropertyNames(plugs), defaultPlugs)

const slots = normalizePlugConfiguration(this.options.slots)

const buildPackages = asArray(options.buildPackages)
const defaultStagePackages = getDefaultStagePackages()
const stagePackages = this.replaceDefault(options.stagePackages, defaultStagePackages)
Expand All @@ -62,10 +65,6 @@ export default class SnapTarget extends Target {
adapter: "none",
}

if (options.slots != null) {
appDescriptor.slots = options.slots
}

const snap: any = safeLoad(await readFile(path.join(getTemplatePath("snap"), "snapcraft.yaml"), "utf-8"))
if (this.isUseTemplateApp) {
delete appDescriptor.adapter
Expand All @@ -82,6 +81,20 @@ export default class SnapTarget extends Target {
if (options.layout != null) {
snap.layout = options.layout
}
if (slots != null) {
appDescriptor.slots = Object.getOwnPropertyNames(slots)
for (const slotName of appDescriptor.slots) {
const slotOptions = slots[slotName]
if (slotOptions == null) {
continue
}
if (!snap.slots) {
snap.slots = {}
}
snap.slots[slotName] = slotOptions
}
}

deepAssign(snap, {
name: snapName,
version: appInfo.version,
Expand Down
79 changes: 79 additions & 0 deletions test/snapshots/linux/snapTest.js.snap
Expand Up @@ -1637,6 +1637,85 @@ Object {
}
`;

exports[`slots option 3`] = `
Object {
"apps": Object {
"sep": Object {
"command": "command.sh",
"environment": Object {
"DISABLE_WAYLAND": "1",
"LD_LIBRARY_PATH": "$SNAP_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu",
"PATH": "$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH",
"SNAP_DESKTOP_RUNTIME": "$SNAP/gnome-platform",
"TMPDIR": "$XDG_RUNTIME_DIR",
},
"plugs": Array [
"desktop",
"desktop-legacy",
"home",
"x11",
"wayland",
"unity7",
"browser-support",
"network",
"gsettings",
"audio-playback",
"pulseaudio",
"opengl",
],
"slots": Array [
"mpris",
"another-simple-slot-name",
],
},
},
"architectures": Array [
"amd64",
],
"base": "core18",
"confinement": "strict",
"description": "Test Application (test quite “ #378)",
"grade": "stable",
"name": "sep",
"plugs": Object {
"gnome-3-28-1804": Object {
"default-provider": "gnome-3-28-1804",
"interface": "content",
"target": "$SNAP/gnome-platform",
},
"gtk-3-themes": Object {
"default-provider": "gtk-common-themes",
"interface": "content",
"target": "$SNAP/data-dir/themes",
},
"icon-themes": Object {
"default-provider": "gtk-common-themes",
"interface": "content",
"target": "$SNAP/data-dir/icons",
},
"sound-themes": Object {
"default-provider": "gtk-common-themes",
"interface": "content",
"target": "$SNAP/data-dir/sounds",
},
},
"slots": Object {
"mpris": Object {
"interface": "mpris",
"name": "chromium",
},
},
"summary": "Sep",
"version": "1.1.0",
}
`;

exports[`slots option 4`] = `
Object {
"linux": Array [],
}
`;

exports[`snap 1`] = `
Object {
"linux": Array [
Expand Down
47 changes: 31 additions & 16 deletions test/src/linux/snapTest.ts
Expand Up @@ -132,22 +132,37 @@ test.ifDevOrLinuxCi("plugs option", async () => {
}
})

test.ifDevOrLinuxCi("slots option", app({
targets: Platform.LINUX.createTarget("snap"),
config: {
extraMetadata: {
name: "sep",
},
productName: "Sep",
snap: {
slots: [ "foo", "bar" ],
}
},
effectiveOptionComputed: async ({snap}) => {
expect(snap).toMatchSnapshot()
return true
},
}))
test.ifDevOrLinuxCi("slots option", async () => {
for (const slots of [
[ "foo", "bar" ],
[
{
"mpris": {
interface: "mpris",
"name": "chromium"
},
},
"another-simple-slot-name",
]
]) {
await assertPack("test-app-one", {
targets: Platform.LINUX.createTarget("snap"),
config: {
extraMetadata: {
name: "sep",
},
productName: "Sep",
snap: {
slots
}
},
effectiveOptionComputed: async ({snap, args}) => {
expect(snap).toMatchSnapshot()
return true
},
})
}
})

test.ifDevOrLinuxCi("custom env", app({
targets: Platform.LINUX.createTarget("snap"),
Expand Down

0 comments on commit 1235c4e

Please sign in to comment.