Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimal Electron dependencies #99

Merged
merged 4 commits into from
Dec 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@

## Requirements

This tool requires Node 6 or greater and `rpmbuild` to build the `.rpm` package. On Fedora you can do something like this:
This tool requires Node 6 or greater and `rpmbuild` to build the `.rpm` package.

**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).

On Fedora you can do something like this:

```
$ sudo dnf install rpm-build
```

While on Ubuntu you'll need to do this instead:
While on Debian/Ubuntu you'll need to do this instead:

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

## Installation

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

#### options.requires
Type: `Array[String]`
Default: `["lsb", "libXScrnSaver"]`
Default: The minimum list of packages needed for Electron to run

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).
malept marked this conversation as resolved.
Show resolved Hide resolved

All user requirements will be appended to the default array of requirements, and any duplicates will be removed.

#### options.homepage
Type: `String`
Default: `package.homepage || package.author.url`
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"dependencies": {
"debug": "^3.1.0",
"electron-installer-common": "^0.2.0",
"electron-installer-common": "^0.4.0",
"fs-extra": "^5.0.0",
"lodash": "^4.17.4",
"nodeify": "^1.0.1",
Expand All @@ -53,6 +53,7 @@
"eslint-plugin-standard": "^3.0.1",
"mocha": "^5.0.4",
"mz": "^2.7.0",
"promise-retry": "^1.1.1"
"promise-retry": "^1.1.1",
"sinon": "^7.2.2"
}
}
75 changes: 75 additions & 0 deletions src/dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict'

const dependencies = require('electron-installer-common/src/dependencies')
malept marked this conversation as resolved.
Show resolved Hide resolved
const spawn = require('./spawn')

const dependencyMap = {
gconf: 'GConf2',
glib2: 'glib2',
gtk2: 'gtk2',
gtk3: 'gtk3',
gvfs: 'gvfs-client',
kdeCliTools: 'kde-cli-tools',
kdeRuntime: 'kde-runtime',
notify: 'libnotify',
nss: 'nss',
trashCli: 'trash-cli',
uuid: 'libuuid',
xdgUtils: 'xdg-utils',
xss: 'libXScrnSaver',
xtst: 'libXtst'
}

/**
* Retrieves the RPM version number and determines whether it has support for boolean
* dependencies (>= 4.13.0).
*/
function rpmSupportsBooleanDependencies (logger) {
return spawn('rpmbuild', ['--version'], logger)
.then(output => rpmVersionSupportsBooleanDependencies(output.trim().split(' ')[2]))
}

/**
* Determine whether the RPM version string has support for boolean dependencies (>= 4.13.0).
*
* RPM does not follow semantic versioning, so `semver` cannot be used.
*/
function rpmVersionSupportsBooleanDependencies (rpmVersionString) {
const rpmVersion = rpmVersionString.split('.').slice(0, 3).map(n => parseInt(n))
return rpmVersion >= [4, 13, 0]
}

/**
* Transforms the list of trash requires into an RPM boolean dependency list.
*/
function trashRequiresAsBoolean (electronVersion, dependencyMap) {
const trashDepends = dependencies.getTrashDepends(electronVersion, dependencyMap)
if (trashDepends.length === 1) {
return [trashDepends[0]]
} else {
return [`(${trashDepends.join(' or ')})`]
}
}

module.exports = {
dependencyMap,
/**
* The dependencies for Electron itself, given an Electron version.
*/
forElectron: function dependenciesForElectron (electronVersion, logger) {
const requires = dependencies.getDepends(electronVersion, dependencyMap)
return module.exports.rpmSupportsBooleanDependencies(logger)
.then(supportsBooleanDependencies => {
if (supportsBooleanDependencies) {
const trashRequires = trashRequiresAsBoolean(electronVersion, dependencyMap)
return { requires: requires.concat(trashRequires) }
} else {
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.")
return { requires }
}
})
},
rpmSupportsBooleanDependencies,
rpmVersionSupportsBooleanDependencies,
trashRequiresAsBoolean
}
20 changes: 10 additions & 10 deletions src/installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ const dependencies = require('electron-installer-common/src/dependencies')
const fs = require('fs-extra')
const nodeify = require('nodeify')
const path = require('path')
const readElectronVersion = require('electron-installer-common/src/readelectronversion')
malept marked this conversation as resolved.
Show resolved Hide resolved
const wrap = require('word-wrap')

const redhatDependencies = require('./dependencies')
const spawn = require('./spawn')
const util = require('./util')

Expand All @@ -23,26 +25,24 @@ const defaultRename = function (dest, src) {
* read from `package.json`, and some are hardcoded.
*/
const getDefaults = function (data) {
return common.readMeta(data)
.then(pkg => {
pkg = pkg || {}
return readElectronVersion(data.src)
.then(electronVersion => Promise.all([common.readMeta(data), redhatDependencies.forElectron(electronVersion, data.logger)]))
.then(([pkg, requires]) => {
if (!pkg) {
pkg = {}
}

return Object.assign(common.getDefaultsFromPackageJSON(pkg), {
version: pkg.version || '0.0.0',
license: pkg.license,
requires: [
'lsb',
'libXScrnSaver'
],
compressionLevel: 2,
execArguments: [],
icon: path.resolve(__dirname, '../resources/icon.png'),

pre: undefined,
post: undefined,
preun: undefined,
postun: undefined
})
}, requires)
})
}

Expand Down Expand Up @@ -93,7 +93,7 @@ function getOptions (data, defaults) {
*
* See: https://fedoraproject.org/wiki/How_to_create_an_RPM_package
*/
const createSpec = function (options, dir) {
function createSpec (options, dir) {
const specSrc = path.resolve(__dirname, '../resources/spec.ejs')
const specDest = path.join(dir, 'SPECS', options.name + '.spec')
options.logger(`Creating spec file at ${specDest}`)
Expand Down
57 changes: 57 additions & 0 deletions test/dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const dependencies = require('../src/dependencies')
const { expect } = require('chai')
const sinon = require('sinon')

describe('dependencies', () => {
describe('forElectron', () => {
beforeEach(() => {
sinon.spy(console, 'warn')
})

afterEach(() => {
sinon.restore()
})

it('uses an RPM that does not support boolean dependencies', () => {
sinon.stub(dependencies, 'rpmSupportsBooleanDependencies').resolves(false)
return dependencies.forElectron('v1.0.0')
.then(result => {
expect(console.warn.calledWithMatch(/^You are using RPM < 4.13/)).to.equal(true)
})
})

it('uses an RPM that supports boolean dependencies', () => {
sinon.stub(dependencies, 'rpmSupportsBooleanDependencies').resolves(true)
return dependencies.forElectron('v1.0.0')
.then(result => {
expect(console.warn.calledWithMatch(/^You are using RPM < 4.13/)).to.equal(false)
})
})
})

describe('rpmVersionSupportsBooleanDependencies', () => {
it('works with release candidates', () => {
expect(dependencies.rpmVersionSupportsBooleanDependencies('4.13.0-rc1')).to.equal(true)
})

it('works with git snapshots', () => {
expect(dependencies.rpmVersionSupportsBooleanDependencies('4.11.90-git12844')).to.equal(false)
})

it('works with 4 part versions (1.2.3.4)', () => {
expect(dependencies.rpmVersionSupportsBooleanDependencies('4.1.12.2')).to.equal(false)
})
})

describe('trashRequiresAsBoolean', () => {
it('does not use parentheses for one item', () => {
const trashDeps = dependencies.trashRequiresAsBoolean('1.0.0', dependencies.dependencyMap)[0]
expect(trashDeps[0]).to.not.match(/^\(/)
})

it('ORs more than one item', () => {
const trashDeps = dependencies.trashRequiresAsBoolean('1.5.0', dependencies.dependencyMap)[0]
expect(trashDeps).to.match(/^\(.* or .*\)$/)
})
})
})
2 changes: 1 addition & 1 deletion test/fixtures/app-without-asar/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.29.2
v1.8.5