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

Drop packageManager support & refactor pruning to be part of the copy filter #819

Merged
merged 1 commit into from
Mar 31, 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
11 changes: 11 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@

[Unreleased]: https://github.com/electron-userland/electron-packager/compare/v11.2.0...master

### Changed

* `prune` exclusively utilizes the `galactus` module for pruning devDependencies, instead of
depending on package managers
* `electron-packager` is no longer ignored by default
* A warning is emitted when an Electron module is a production dependency

### Removed

* `packageManager` option

## [11.2.0] - 2018-03-24

[11.2.0]: https://github.com/electron-userland/electron-packager/compare/v11.1.0...v11.2.0
Expand Down
6 changes: 6 additions & 0 deletions common.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ module.exports = {
generateFinalBasename: generateFinalBasename,
generateFinalPath: generateFinalPath,
sanitizeAppName: sanitizeAppName,
/**
* Convert slashes to UNIX-format separators.
*/
normalizePath: function normalizePath (pathToNormalize) {
return pathToNormalize.replace(/\\/g, '/')
},

info: info,
warning: warning
Expand Down
17 changes: 1 addition & 16 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,21 +313,6 @@ The base directory where the finished package(s) are created.

Whether to replace an already existing output directory for a given platform (`true`) or skip recreating it (`false`).

##### `packageManager`

*String* or *Boolean* (default: `npm`)

The package manager used to [prune](#prune) `devDependencies` modules from the outputted Electron
app. Supported package managers:

* [`npm`](https://npmjs.com/)
* [`cnpm`](https://github.com/cnpm/cnpm) (Does not currently work with Windows, see
[GitHub issue](https://github.com/electron-userland/electron-packager/issues/515#issuecomment-297604044))
* [`yarn`](https://yarnpkg.com/)

If set to `false` we will use a custom [pruning module](https://www.npmjs.com/package/pruner) to walk your dependency
tree and prune your dependencies for you.

##### `platform`

*String* (default: the arch of the host computer running Node)
Expand All @@ -345,7 +330,7 @@ is not restricted to the official set if [`download.mirror`](#download) is set.

*Boolean* (default: `true`)

Runs the [package manager](#packagemanager) command to remove all of the packages specified in the
Walks the `node_modules` dependency tree to remove all of the packages specified in the
`devDependencies` section of `package.json` from the outputted Electron app.

##### `quiet`
Expand Down
19 changes: 11 additions & 8 deletions ignore.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
const common = require('./common')
const debug = require('debug')('electron-packager')
const path = require('path')
const prune = require('./prune')
const targets = require('./targets')

const DEFAULT_IGNORES = [
'/node_modules/electron($|/)',
'/node_modules/electron-prebuilt(-compile)?($|/)',
'/node_modules/electron-packager($|/)',
'/\\.git($|/)',
'/node_modules/\\.bin($|/)',
'\\.o(bj)?$'
Expand All @@ -30,8 +28,8 @@ function generateIgnores (opts) {
}

function generateOutIgnores (opts) {
let normalizedOut = opts.out ? path.resolve(opts.out) : null
let outIgnores = []
const normalizedOut = opts.out ? path.resolve(opts.out) : null
const outIgnores = []
if (normalizedOut === null || normalizedOut === process.cwd()) {
for (const platform of Object.keys(targets.officialPlatformArchCombos)) {
for (const arch of targets.officialPlatformArchCombos[platform]) {
Expand Down Expand Up @@ -66,7 +64,8 @@ function userIgnoreFilter (opts) {
}
}

let outIgnores = generateOutIgnores(opts)
const outIgnores = generateOutIgnores(opts)
const pruner = opts.prune ? new prune.Pruner(opts.dir) : null

return function filter (file) {
if (outIgnores.indexOf(file) !== -1) {
Expand All @@ -76,8 +75,12 @@ function userIgnoreFilter (opts) {
let name = file.split(path.resolve(opts.dir))[1]

if (path.sep === '\\') {
// convert slashes so unix-format ignores work
name = name.replace(/\\/g, '/')
name = common.normalizePath(name)
}

if (pruner && name.startsWith('/node_modules/')) {
return prune.isModule(file)
.then(isModule => isModule ? pruner.pruneModule(name) : ignoreFunc(name))
}

return ignoreFunc(name)
Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@
"electron-osx-sign": "^0.4.1",
"extract-zip": "^1.0.3",
"fs-extra": "^5.0.0",
"galactus": "^0.2.0",
"get-package-info": "^1.0.0",
"mz": "^2.6.0",
"nodeify": "^1.0.1",
"parse-author": "^2.0.0",
"pify": "^3.0.0",
"plist": "^2.0.0",
"pruner": "^0.0.7",
"rcedit": "^1.0.0",
"resolve": "^1.1.6",
"sanitize-filename": "^1.6.0",
Expand All @@ -40,18 +39,18 @@
"ava": "^0.25.0",
"buffer-equal": "^1.0.0",
"codecov": "^3.0.0",
"eslint": "^4.1.0",
"eslint": "^4.18.0",
"eslint-config-standard": "^11.0.0",
"eslint-plugin-ava": "^4.3.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-node": "^6.0.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.0",
"mz": "^2.6.0",
"nyc": "^11.0.0",
"pkg-up": "^2.0.0",
"sinon": "^4.1.3",
"tempy": "^0.2.1",
"which": "^1.2.14"
"tempy": "^0.2.1"
},
"engines": {
"node": ">= 4.0"
Expand Down
31 changes: 17 additions & 14 deletions platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ const fs = require('fs-extra')
const path = require('path')
const pify = require('pify')

const common = require('./common')
const hooks = require('./hooks')
const ignore = require('./ignore')
const pruneModules = require('./prune').pruneModules

const common = require('./common')

class App {
constructor (opts, templatePath) {
this.opts = opts
this.templatePath = templatePath

if (this.opts.prune === undefined) {
this.opts.prune = true
}
}

/**
Expand Down Expand Up @@ -94,7 +96,6 @@ class App {
}).then(() => fs.remove(path.join(this.originalResourcesDir, 'default_app.asar')))
// Prune and asar are performed before platform-specific logic, primarily so that
// this.originalResourcesAppDir is predictable (e.g. before .app is renamed for mac)
.then(() => this.prune())
.then(() => this.asarApp())
}

Expand All @@ -107,7 +108,18 @@ class App {
this.opts.electronVersion,
this.opts.platform,
this.opts.arch
]))
])).then(() => {
if (this.opts.prune) {
return hooks.promisifyHooks(this.opts.afterPrune, [
this.originalResourcesAppDir,
this.opts.electronVersion,
this.opts.platform,
this.opts.arch
])
} else {
return true
}
})
}

/**
Expand All @@ -130,15 +142,6 @@ class App {
.catch(/* istanbul ignore next */ () => null)
}

prune () {
if (this.opts.prune || this.opts.prune === undefined) {
return pruneModules(this.opts, this.originalResourcesAppDir)
.then(() => hooks.promisifyHooks(this.opts.afterPrune, [this.originalResourcesAppDir, this.opts.electronVersion, this.opts.platform, this.opts.arch]))
}

return Promise.resolve()
}

asarApp () {
const asarOptions = common.createAsarOpts(this.opts)
if (!asarOptions) {
Expand Down
86 changes: 55 additions & 31 deletions prune.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,69 @@
'use strict'

const child = require('mz/child_process')
const debug = require('debug')('electron-packager')
const Walker = require('pruner').Walker

const knownPackageManagers = ['npm', 'cnpm', 'yarn']

function pruneCommand (packageManager) {
switch (packageManager) {
case 'npm':
case 'cnpm':
return `${packageManager} prune --production`
case 'yarn':
return `${packageManager} install --production --no-bin-links --no-lockfile`
const common = require('./common')
const galactus = require('galactus')
const fs = require('fs-extra')
const path = require('path')

const ELECTRON_MODULES = [
'electron',
'electron-prebuilt',
'electron-prebuilt-compile'
]

class Pruner {
constructor (dir) {
this.baseDir = common.normalizePath(dir)
this.galactus = new galactus.DestroyerOfModules({
rootDirectory: dir,
shouldKeepModuleTest: (module, isDevDep) => this.shouldKeepModule(module, isDevDep)
})
this.walkedTree = false
}
}

function pruneModules (opts, appPath) {
if (opts.packageManager === false) {
const walker = new Walker(appPath)
return walker.prune()
} else {
const packageManager = opts.packageManager || 'npm'
setModuleMap (moduleMap) {
this.moduleMap = new Map()
// destructured assignments are in Node 6
for (const modulePair of moduleMap) {
const modulePath = modulePair[0]
const module = modulePair[1]
this.moduleMap.set(`/${common.normalizePath(modulePath)}`, module)
}
this.walkedTree = true
}

/* istanbul ignore if */
if (packageManager === 'cnpm' && process.platform === 'win32') {
return Promise.reject(new Error('cnpm support does not currently work with Windows, see: https://github.com/electron-userland/electron-packager/issues/515#issuecomment-297604044'))
pruneModule (name) {
if (this.walkedTree) {
return this.isProductionModule(name)
} else {
return this.galactus.collectKeptModules({ relativePaths: true })
.then(moduleMap => this.setModuleMap(moduleMap))
.then(() => this.isProductionModule(name))
}
}

const command = pruneCommand(packageManager)
shouldKeepModule (module, isDevDep) {
if (isDevDep || module.depType === galactus.DepType.ROOT) {
return false
}

if (command) {
debug(`Pruning modules via: ${command}`)
return child.exec(command, { cwd: appPath })
} else {
return Promise.reject(new Error(`Unknown package manager "${packageManager}". Known package managers: ${knownPackageManagers.join(', ')}`))
// Node 6 has Array.prototype.includes
if (ELECTRON_MODULES.indexOf(module.name) !== -1) {
common.warning(`Found '${module.name}' but not as a devDependency, pruning anyway`)
return false
}

return true
}

isProductionModule (name) {
return !!this.moduleMap.get(name)
}
}

module.exports = {
pruneCommand: pruneCommand,
pruneModules: pruneModules
isModule: function isModule (pathToCheck) {
return fs.pathExists(path.join(pathToCheck, 'package.json'))
},
Pruner: Pruner
}
1 change: 1 addition & 0 deletions test/_setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function npmInstallForFixtures () {
const fixtures = [
'basic',
'basic-renamed-to-electron',
'electron-in-dependencies',
'infer-missing-version-only',
'el-0374'
]
Expand Down
8 changes: 1 addition & 7 deletions test/ci/before_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ case "$TRAVIS_OS_NAME" in
# Not using Trusty containers because it can't install wine1.6(-i386),
# see: https://github.com/travis-ci/travis-ci/issues/6460
sudo rm /etc/apt/sources.list.d/google-chrome.list
sudo apt-key adv --fetch-keys http://dl.yarnpkg.com/debian/pubkey.gpg
echo "deb http://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y wine1.6 yarn
sudo apt-get install -y wine1.6
;;
"osx")
# Create CA
Expand All @@ -31,9 +29,5 @@ case "$TRAVIS_OS_NAME" in
npm install [email protected]
# Setup ~/.wine by running a command
./node_modules/.bin/wine hostname
# Install yarn
npm install -g yarn
;;
esac

npm install -g cnpm
1 change: 1 addition & 0 deletions test/fixtures/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "4.99.101",
"productName": "MainJS",
"dependencies": {
"@types/node": "^8.0.0",
"run-series": "^1.1.1"
},
"//": "ncp used to test https://github.com/electron-userland/electron-packager/pull/186",
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/electron-in-dependencies/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!DOCTYPE html>
<html>
<body>Hello, world!</body>
</html>
1 change: 1 addition & 0 deletions test/fixtures/electron-in-dependencies/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'use strict'
8 changes: 8 additions & 0 deletions test/fixtures/electron-in-dependencies/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"main": "main.js",
"productName": "MainJS",
"description": "Removing electron from dependencies",
"dependencies": {
"electron": "1.3.1"
}
}
Loading