diff --git a/.idea/dictionaries/develar.xml b/.idea/dictionaries/develar.xml index 260eccb6b93..00398e7e6c5 100644 --- a/.idea/dictionaries/develar.xml +++ b/.idea/dictionaries/develar.xml @@ -307,6 +307,7 @@ rollouts rpmbuild rtfs + sbin scripthost semver setfinderinfo diff --git a/packages/electron-builder-lib/src/options/SnapOptions.ts b/packages/electron-builder-lib/src/options/SnapOptions.ts index 586f0bf5f2a..41c7637aa38 100644 --- a/packages/electron-builder-lib/src/options/SnapOptions.ts +++ b/packages/electron-builder-lib/src/options/SnapOptions.ts @@ -54,8 +54,21 @@ export interface SnapOptions extends CommonLinuxOptions, TargetSpecificOptions { * Defaults to `["desktop", "desktop-legacy", "home", "x11", "unity7", "browser-support", "network", "gsettings", "pulseaudio", "opengl"]`. * * If list contains `default`, it will be replaced to default list, so, `["default", "foo"]` can be used to add custom plug `foo` in addition to defaults. + * + * Additional attributes can be specified using object instead of just name of plug: + * ``` + *[ + * { + * "browser-sandbox": { + * "interface": "browser-support", + * "allow-sandbox": true + * }, + * }, + * "another-simple-plug-name" + *] + * ``` */ - readonly plugs?: Array | null + readonly plugs?: Array | object | null /** * Specifies any [parts](https://snapcraft.io/docs/reference/parts) that should be built before this part. diff --git a/packages/electron-builder-lib/src/targets/snap.ts b/packages/electron-builder-lib/src/targets/snap.ts index f73e6408c2b..82b00cd16f2 100644 --- a/packages/electron-builder-lib/src/targets/snap.ts +++ b/packages/electron-builder-lib/src/targets/snap.ts @@ -50,6 +50,10 @@ export default class SnapTarget extends Target { const appInfo = this.packager.appInfo const options = this.options const linuxArchName = toAppImageOrSnapArch(arch) + + const plugs: { [key: string]: object | null } | null = normalizePlugConfiguration(options.plugs == null ? null : asArray(options.plugs)) + const plugNames = this.replaceDefault(plugs == null ? null : Object.getOwnPropertyNames(plugs), defaultPlugs) + const snap: any = { name: snapName, version: appInfo.version, @@ -74,7 +78,7 @@ export default class SnapTarget extends Target { ].join(":"), ...options.environment, }, - plugs: this.replaceDefault(options.plugs, defaultPlugs), + plugs: plugNames, } }, parts: { @@ -87,6 +91,20 @@ export default class SnapTarget extends Target { }, } + if (plugs != null) { + for (const plugName of plugNames) { + const plugOptions = plugs[plugName] + if (plugOptions == null) { + continue + } + + if (snap.plugs == null) { + snap.plugs = {} + } + snap.plugs[plugName] = plugOptions + } + } + if (options.assumes != null) { snap.assumes = asArray(options.assumes) } @@ -234,4 +252,21 @@ export default class SnapTarget extends Target { stdio: ["ignore", "inherit", "inherit"], }) } +} + +function normalizePlugConfiguration(raw: Array | null) { + const result: any = {} + if (raw == null) { + return result + } + + for (const item of raw) { + if (typeof item === "string") { + result[item] = null + } + else { + Object.assign(result, item) + } + } + return result } \ No newline at end of file diff --git a/test/out/linux/__snapshots__/snapTest.js.snap b/test/out/linux/__snapshots__/snapTest.js.snap index 01daf7d3816..15ab06f7b69 100644 --- a/test/out/linux/__snapshots__/snapTest.js.snap +++ b/test/out/linux/__snapshots__/snapTest.js.snap @@ -274,6 +274,122 @@ Object { } `; +exports[`plugs option 1`] = ` +Object { + "apps": Object { + "testapp": Object { + "adapter": "none", + "command": "bin/desktop-launch $SNAP/testapp", + "environment": Object { + "LD_LIBRARY_PATH": "$SNAP_LIBRARY_PATH:$SNAP/usr/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu/pulseaudio:$SNAP/usr/lib/x86_64-linux-gnu/mesa-egl:$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", + "TMPDIR": "$XDG_RUNTIME_DIR", + }, + "plugs": Array [ + "browser-sandbox", + "another-simple-plug-name", + ], + }, + }, + "confinement": "strict", + "description": "Test Application (test quite “ #378)", + "grade": "stable", + "icon": "snap/gui/icon.png", + "name": "testapp", + "parts": Object { + "app": Object { + "after": Array [ + "desktop-gtk2", + ], + "plugin": "dump", + "stage-packages": Array [ + "libasound2", + "libgconf2-4", + "libnotify4", + "libnspr4", + "libnss3", + "libpcre3", + "libpulse0", + "libxss1", + "libxtst6", + ], + }, + }, + "plugs": Object { + "browser-sandbox": Object { + "allow-sandbox": true, + "interface": "browser-support", + }, + }, + "summary": "Test App ßW", + "version": "1.1.0", +} +`; + +exports[`plugs option 2`] = ` +Object { + "linux": Array [], +} +`; + +exports[`plugs option 3`] = ` +Object { + "apps": Object { + "testapp": Object { + "adapter": "none", + "command": "bin/desktop-launch $SNAP/testapp", + "environment": Object { + "LD_LIBRARY_PATH": "$SNAP_LIBRARY_PATH:$SNAP/usr/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu/pulseaudio:$SNAP/usr/lib/x86_64-linux-gnu/mesa-egl:$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", + "TMPDIR": "$XDG_RUNTIME_DIR", + }, + "plugs": Array [ + "browser-sandbox", + "another-simple-plug-name", + ], + }, + }, + "confinement": "strict", + "description": "Test Application (test quite “ #378)", + "grade": "stable", + "icon": "snap/gui/icon.png", + "name": "testapp", + "parts": Object { + "app": Object { + "after": Array [ + "desktop-gtk2", + ], + "plugin": "dump", + "stage-packages": Array [ + "libasound2", + "libgconf2-4", + "libnotify4", + "libnspr4", + "libnss3", + "libpcre3", + "libpulse0", + "libxss1", + "libxtst6", + ], + }, + }, + "plugs": Object { + "browser-sandbox": Object { + "allow-sandbox": true, + "interface": "browser-support", + }, + }, + "summary": "Test App ßW", + "version": "1.1.0", +} +`; + +exports[`plugs option 4`] = ` +Object { + "linux": Array [], +} +`; + exports[`snap 1`] = ` Object { "linux": Array [ diff --git a/test/src/linux/snapTest.ts b/test/src/linux/snapTest.ts index dabf564000c..19e2dbf6435 100644 --- a/test/src/linux/snapTest.ts +++ b/test/src/linux/snapTest.ts @@ -59,6 +59,43 @@ test.ifAll.ifDevOrLinuxCi("default stagePackages", async () => { } }) +test.ifAll.ifDevOrLinuxCi("plugs option", async () => { + for (const p of [ + [ + { + "browser-sandbox": { + interface: "browser-support", + "allow-sandbox": true + }, + }, + "another-simple-plug-name", + ], + { + "browser-sandbox": { + interface: "browser-support", + "allow-sandbox": true + }, + "another-simple-plug-name": null, + }, + ]) { + await assertPack("test-app-one", { + targets: Platform.LINUX.createTarget("snap"), + config: { + snap: { + plugs: p, + // otherwise "parts" will be removed + useTemplateApp: false, + } + }, + effectiveOptionComputed: async ({snap}) => { + delete snap.parts.app.source + expect(snap).toMatchSnapshot() + return true + }, + }) + } +}) + test.ifAll.ifDevOrLinuxCi("custom env", app({ targets: Platform.LINUX.createTarget("snap"), config: {