Skip to content

Commit 80b40f2

Browse files
authored
Merge pull request #99 from electron-userland/common-dependencies
Add minimal Electron dependencies
2 parents e5eff39 + 34bfdad commit 80b40f2

File tree

6 files changed

+155
-17
lines changed

6 files changed

+155
-17
lines changed

README.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@
77

88
## Requirements
99

10-
This tool requires Node 6 or greater and `rpmbuild` to build the `.rpm` package. On Fedora you can do something like this:
10+
This tool requires Node 6 or greater and `rpmbuild` to build the `.rpm` package.
11+
12+
**Note**: If your application uses the [Electron API's `shell.moveItemToTrash` method](https://electronjs.org/docs/api/shell#shellmoveitemtotrashfullpath), RPM 4.13.0 or greater is required, due to the [boolean dependency feature](http://rpm.org/user_doc/boolean_dependencies.html).
13+
14+
On Fedora you can do something like this:
1115

1216
```
1317
$ sudo dnf install rpm-build
1418
```
1519

16-
While on Ubuntu you'll need to do this instead:
20+
While on Debian/Ubuntu you'll need to do this instead:
1721

1822
```
1923
$ sudo apt-get install rpm
2024
```
21-
In order to use [boolean dependencies](http://rpm.org/user_doc/boolean_dependencies.html),`rpm >= 4.13` is required.
2225

2326
## Installation
2427

@@ -272,10 +275,12 @@ Machine architecture the package is targeted to, used to set the `--target` opti
272275

273276
#### options.requires
274277
Type: `Array[String]`
275-
Default: `["lsb", "libXScrnSaver"]`
278+
Default: The minimum list of packages needed for Electron to run
276279

277280
Packages that are required when the program starts, used in the [`Requires` field of the `spec` file](https://fedoraproject.org/wiki/How_to_create_an_RPM_package#Creating_a_SPEC_file).
278281

282+
All user requirements will be appended to the default array of requirements, and any duplicates will be removed.
283+
279284
#### options.homepage
280285
Type: `String`
281286
Default: `package.homepage || package.author.url`

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
},
3535
"dependencies": {
3636
"debug": "^3.1.0",
37-
"electron-installer-common": "^0.2.0",
37+
"electron-installer-common": "^0.4.0",
3838
"fs-extra": "^5.0.0",
3939
"lodash": "^4.17.4",
4040
"nodeify": "^1.0.1",
@@ -53,6 +53,7 @@
5353
"eslint-plugin-standard": "^3.0.1",
5454
"mocha": "^5.0.4",
5555
"mz": "^2.7.0",
56-
"promise-retry": "^1.1.1"
56+
"promise-retry": "^1.1.1",
57+
"sinon": "^7.2.2"
5758
}
5859
}

src/dependencies.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'use strict'
2+
3+
const dependencies = require('electron-installer-common/src/dependencies')
4+
const spawn = require('./spawn')
5+
6+
const dependencyMap = {
7+
gconf: 'GConf2',
8+
glib2: 'glib2',
9+
gtk2: 'gtk2',
10+
gtk3: 'gtk3',
11+
gvfs: 'gvfs-client',
12+
kdeCliTools: 'kde-cli-tools',
13+
kdeRuntime: 'kde-runtime',
14+
notify: 'libnotify',
15+
nss: 'nss',
16+
trashCli: 'trash-cli',
17+
uuid: 'libuuid',
18+
xdgUtils: 'xdg-utils',
19+
xss: 'libXScrnSaver',
20+
xtst: 'libXtst'
21+
}
22+
23+
/**
24+
* Retrieves the RPM version number and determines whether it has support for boolean
25+
* dependencies (>= 4.13.0).
26+
*/
27+
function rpmSupportsBooleanDependencies (logger) {
28+
return spawn('rpmbuild', ['--version'], logger)
29+
.then(output => rpmVersionSupportsBooleanDependencies(output.trim().split(' ')[2]))
30+
}
31+
32+
/**
33+
* Determine whether the RPM version string has support for boolean dependencies (>= 4.13.0).
34+
*
35+
* RPM does not follow semantic versioning, so `semver` cannot be used.
36+
*/
37+
function rpmVersionSupportsBooleanDependencies (rpmVersionString) {
38+
const rpmVersion = rpmVersionString.split('.').slice(0, 3).map(n => parseInt(n))
39+
return rpmVersion >= [4, 13, 0]
40+
}
41+
42+
/**
43+
* Transforms the list of trash requires into an RPM boolean dependency list.
44+
*/
45+
function trashRequiresAsBoolean (electronVersion, dependencyMap) {
46+
const trashDepends = dependencies.getTrashDepends(electronVersion, dependencyMap)
47+
if (trashDepends.length === 1) {
48+
return [trashDepends[0]]
49+
} else {
50+
return [`(${trashDepends.join(' or ')})`]
51+
}
52+
}
53+
54+
module.exports = {
55+
dependencyMap,
56+
/**
57+
* The dependencies for Electron itself, given an Electron version.
58+
*/
59+
forElectron: function dependenciesForElectron (electronVersion, logger) {
60+
const requires = dependencies.getDepends(electronVersion, dependencyMap)
61+
return module.exports.rpmSupportsBooleanDependencies(logger)
62+
.then(supportsBooleanDependencies => {
63+
if (supportsBooleanDependencies) {
64+
const trashRequires = trashRequiresAsBoolean(electronVersion, dependencyMap)
65+
return { requires: requires.concat(trashRequires) }
66+
} else {
67+
console.warn("You are using RPM < 4.13, which does not support boolean dependencies. This is required to express the dependencies needed for the 'shell.moveItemToTrash' API.\nIf you do not use this API, you can safely ignore this warning.\nIf you do use this API, please upgrade to RPM 4.13 or above to have the trash dependencies added to your RPM's requires section.")
68+
return { requires }
69+
}
70+
})
71+
},
72+
rpmSupportsBooleanDependencies,
73+
rpmVersionSupportsBooleanDependencies,
74+
trashRequiresAsBoolean
75+
}

src/installer.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ const dependencies = require('electron-installer-common/src/dependencies')
77
const fs = require('fs-extra')
88
const nodeify = require('nodeify')
99
const path = require('path')
10+
const readElectronVersion = require('electron-installer-common/src/readelectronversion')
1011
const wrap = require('word-wrap')
1112

13+
const redhatDependencies = require('./dependencies')
1214
const spawn = require('./spawn')
1315
const util = require('./util')
1416

@@ -23,26 +25,24 @@ const defaultRename = function (dest, src) {
2325
* read from `package.json`, and some are hardcoded.
2426
*/
2527
const getDefaults = function (data) {
26-
return common.readMeta(data)
27-
.then(pkg => {
28-
pkg = pkg || {}
28+
return readElectronVersion(data.src)
29+
.then(electronVersion => Promise.all([common.readMeta(data), redhatDependencies.forElectron(electronVersion, data.logger)]))
30+
.then(([pkg, requires]) => {
31+
if (!pkg) {
32+
pkg = {}
33+
}
2934

3035
return Object.assign(common.getDefaultsFromPackageJSON(pkg), {
3136
version: pkg.version || '0.0.0',
3237
license: pkg.license,
33-
requires: [
34-
'lsb',
35-
'libXScrnSaver'
36-
],
3738
compressionLevel: 2,
38-
execArguments: [],
3939
icon: path.resolve(__dirname, '../resources/icon.png'),
4040

4141
pre: undefined,
4242
post: undefined,
4343
preun: undefined,
4444
postun: undefined
45-
})
45+
}, requires)
4646
})
4747
}
4848

@@ -93,7 +93,7 @@ function getOptions (data, defaults) {
9393
*
9494
* See: https://fedoraproject.org/wiki/How_to_create_an_RPM_package
9595
*/
96-
const createSpec = function (options, dir) {
96+
function createSpec (options, dir) {
9797
const specSrc = path.resolve(__dirname, '../resources/spec.ejs')
9898
const specDest = path.join(dir, 'SPECS', options.name + '.spec')
9999
options.logger(`Creating spec file at ${specDest}`)

test/dependencies.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const dependencies = require('../src/dependencies')
2+
const { expect } = require('chai')
3+
const sinon = require('sinon')
4+
5+
describe('dependencies', () => {
6+
describe('forElectron', () => {
7+
beforeEach(() => {
8+
sinon.spy(console, 'warn')
9+
})
10+
11+
afterEach(() => {
12+
sinon.restore()
13+
})
14+
15+
it('uses an RPM that does not support boolean dependencies', () => {
16+
sinon.stub(dependencies, 'rpmSupportsBooleanDependencies').resolves(false)
17+
return dependencies.forElectron('v1.0.0')
18+
.then(result => {
19+
expect(console.warn.calledWithMatch(/^You are using RPM < 4.13/)).to.equal(true)
20+
})
21+
})
22+
23+
it('uses an RPM that supports boolean dependencies', () => {
24+
sinon.stub(dependencies, 'rpmSupportsBooleanDependencies').resolves(true)
25+
return dependencies.forElectron('v1.0.0')
26+
.then(result => {
27+
expect(console.warn.calledWithMatch(/^You are using RPM < 4.13/)).to.equal(false)
28+
})
29+
})
30+
})
31+
32+
describe('rpmVersionSupportsBooleanDependencies', () => {
33+
it('works with release candidates', () => {
34+
expect(dependencies.rpmVersionSupportsBooleanDependencies('4.13.0-rc1')).to.equal(true)
35+
})
36+
37+
it('works with git snapshots', () => {
38+
expect(dependencies.rpmVersionSupportsBooleanDependencies('4.11.90-git12844')).to.equal(false)
39+
})
40+
41+
it('works with 4 part versions (1.2.3.4)', () => {
42+
expect(dependencies.rpmVersionSupportsBooleanDependencies('4.1.12.2')).to.equal(false)
43+
})
44+
})
45+
46+
describe('trashRequiresAsBoolean', () => {
47+
it('does not use parentheses for one item', () => {
48+
const trashDeps = dependencies.trashRequiresAsBoolean('1.0.0', dependencies.dependencyMap)[0]
49+
expect(trashDeps[0]).to.not.match(/^\(/)
50+
})
51+
52+
it('ORs more than one item', () => {
53+
const trashDeps = dependencies.trashRequiresAsBoolean('1.5.0', dependencies.dependencyMap)[0]
54+
expect(trashDeps).to.match(/^\(.* or .*\)$/)
55+
})
56+
})
57+
})
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.29.2
1+
v1.8.5

0 commit comments

Comments
 (0)