breaking change. allow building apps for other platforms

This commit is contained in:
Max Ogden 2015-05-10 13:57:42 -07:00
parent f9fdb45d09
commit 260a16509b
8 changed files with 108 additions and 67 deletions

10
cli.js
View File

@ -1,6 +1,8 @@
#!/usr/bin/env node
var fs = require('fs')
var args = require('minimist')(process.argv.slice(2), {boolean: ['prune', 'asar']})
var packager = require('./')
var usage = fs.readFileSync(__dirname + '/usage.txt').toString()
args.dir = args._[0]
args.name = args._[1]
@ -14,14 +16,14 @@ if (protocolSchemes && protocolNames && protocolNames.length === protocolSchemes
})
}
if (!args.dir || !args.name) {
console.error('Usage: electron-packager <sourcedir> <Appname>')
if (!args.dir || !args.name || !args.platform || !args.arch || !args.version) {
console.error(usage)
process.exit(1)
}
console.log('args', args)
packager(args, function done (err, appPath) {
if (err) {
console.error(err.stack)
console.error(err, err.stack)
process.exit(1)
}

View File

@ -1,31 +1,48 @@
var os = require('os')
var path = require('path')
var os = require('os')
var download = require('electron-download')
var extract = require('extract-zip')
var mkdirp = require('mkdirp')
var rimraf = require('rimraf')
var mac = require('./mac.js')
var linux = require('./linux.js')
var win32 = require('./win32.js')
module.exports = function packager (opts, cb) {
var electronPath
var platform
var packager
var platform = opts.platform
var arch = opts.arch
var version = opts.version
try {
electronPath = require.resolve('electron-prebuilt')
electronPath = path.join(electronPath, '..')
} catch (e) {
try {
electronPath = require.resolve(path.join(process.execPath, '../../lib/node_modules/electron-prebuilt'))
electronPath = path.join(electronPath, '..')
} catch (e) {
cb(new Error('Cannot find electron-prebuilt from here, please install it from npm'))
}
}
if (!platform || !arch || !version) cb(new Error('Must specify platform, arch and version'))
var electronPkg = require(path.join(electronPath, 'package.json'))
console.error('Using electron-prebuilt version', electronPkg.version, 'from', electronPath)
switch (os.platform()) {
case 'darwin': platform = require('./mac'); break
case 'linux': platform = require('./linux'); break
case 'win32': platform = require('./windows'); break
switch (platform) {
case 'darwin': packager = mac; break
case 'linux': packager = linux; break
case 'win32': packager = win32; break
default: cb(new Error('Unsupported platform'))
}
platform.createApp(opts, cb, electronPath)
download({
platform: platform,
arch: arch,
version: version
}, function (err, zipPath) {
if (err) return cb(err)
console.error('Packaging app for platform', platform + ' ' + arch, 'using electron v' + version)
// extract zip into tmp so that packager can use it as a template
var tmpDir = path.join(os.tmpdir(), 'electron-packager-' + platform + '-template')
rimraf(tmpDir, function (err) {
if (err) {} // ignore err
mkdirp(tmpDir, function (err) {
if (err) return cb(err)
extract(zipPath, {dir: tmpDir}, function (err) {
if (err) return cb(err)
packager.createApp(opts, tmpDir, cb)
})
})
})
})
}

View File

@ -7,9 +7,8 @@ var rimraf = require('rimraf')
var asar = require('asar')
module.exports = {
createApp: function createApp (opts, cb, electronPath) {
var templateApp = path.join(electronPath, 'dist')
var finalDir = opts.out || path.join(process.cwd(), 'dist')
createApp: function createApp (opts, templateApp, cb) {
var finalDir = opts.out || path.join(process.cwd(), opts.name + '-linux')
var userAppDir = path.join(finalDir, 'resources', 'default_app')
var originalBinary = path.join(finalDir, 'electron')
var finalBinary = path.join(finalDir, opts.name)
@ -48,7 +47,7 @@ module.exports = {
if (opts.asar) {
asarApp(cb)
} else {
cb()
cb(null, finalBinary)
}
})
}
@ -78,7 +77,10 @@ module.exports = {
var dest = path.join(finalDir, 'resources', 'app.asar')
asar.createPackage(src, dest, function (err) {
if (err) return cb(err)
rimraf(src, cb)
rimraf(src, function (err) {
if (err) return cb(err)
cb(null, dest)
})
})
}

4
mac.js
View File

@ -10,8 +10,8 @@ var ncp = require('ncp').ncp
var asar = require('asar')
module.exports = {
createApp: function createApp (opts, cb, electronPath) {
var electronApp = path.join(electronPath, 'dist', 'Electron.app')
createApp: function createApp (opts, electronPath, cb) {
var electronApp = path.join(electronPath, 'Electron.app')
var tmpDir = path.join(os.tmpdir(), 'electron-packager-mac')
var newApp = path.join(tmpDir, opts.name + '.app')

View File

@ -1,7 +1,7 @@
{
"name": "electron-packager",
"version": "3.4.0",
"description": "package and distribute your electron app in OS executables (.app, .exe, etc) via JS or CLI",
"description": "package your electron app in OS executables (.app, .exe, etc) via JS or CLI",
"main": "index.js",
"bin": {
"electron-packager": "cli.js"
@ -18,6 +18,8 @@
"homepage": "https://github.com/maxogden/electron-packager",
"dependencies": {
"asar": "^0.6.1",
"electron-download": "^1.0.0",
"extract-zip": "^1.0.3",
"minimist": "^1.1.1",
"mkdirp": "^0.5.0",
"mv": "^2.0.3",

View File

@ -1,6 +1,6 @@
# electron-packager
Build a distributable app from an electron app source code directory. **Currently only Mac OS and Linux are implemented** but you can send PRs to implement windows :)
Package your electron app in OS executables (.app, .exe, etc) via JS or CLI. Supports building Windows, Linux or Mac executables.
*formerly known as atom-shell-packager*
@ -8,8 +8,6 @@ Build a distributable app from an electron app source code directory. **Currentl
[![Build Status](https://travis-ci.org/maxogden/electron-packager.svg?branch=master)](https://travis-ci.org/maxogden/electron-packager)
For an example project using this, check out [Monu](https://github.com/maxogden/monu)
### installation
```
@ -18,35 +16,38 @@ npm i electron-packager --save-dev
# for use from cli
npm i electron-packager -g
# you also need electron installed
npm i electron-prebuilt
```
### usage
```
$ electron-packager my-app-source-dir AppName
Usage: electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> --version=<version>
Required options
platform linux, win32, darwin
arch ia32, x64
version see https://github.com/atom/electron/releases
Example electron-packager ./ FooBar --platform=darwin --arch=x64 --version=0.25.1
Optional options
out the dir to put the app into at the end. defaults to current working dir
icon the icon file to use as the icon for the app
app-bundle-id bundle identifier to use in the app plist
app-version version to set for the app
helper-bundle-id bundle identifier to use in the app helper plist
ignore do not copy files into App whose filenames regex .match this string
prune runs `npm prune --production` on the app
asar packages the source code within your app into an archive
```
This will:
- Find the closest local version of `electron` installed (using `require.resolve`)
- Use that version of electron to create a Mac app in `cwd` called `AppName.app`
- Find or download the correct release of Electron
- Use that version of electron to create a app in `cwd` named using `appname` for the platform you specified
You should be able to double-click `AppName.app` to launch the app. If not, check your settings and try again.
You should be able to launch the app on the platform you built for. If not, check your settings and try again.
**Be careful** not to include node_modules you don't want into your final app. For example, do not include the `node_modules/electron-packager` folder or `node_modules/electron-prebuilt`. You can use `--ignore=node_modules/electron-prebuilt` to ignore of these
### options
these are optional CLI options you can pass in
- `out` (default current working dir) - the dir to put the app into at the end
- `icon` - the icon file to use as the icon for the app
- `app-bundle-id` - bundle identifier to use in the app plist
- `app-version` - version to set for the app
- `helper-bundle-id` - bundle identifier to use in the app helper plist
- `ignore` (default none) - do not copy files into App whose filenames regex .match this string
- `prune` - runs `npm prune --production` on the app
- `asar` - packages the source code within your app into an archive

20
usage.txt Normal file
View File

@ -0,0 +1,20 @@
Usage: electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> --version=<version>
Required options
platform linux, win32, darwin
arch ia32, x64
version see https://github.com/atom/electron/releases
Example electron-packager ./ FooBar --platform=darwin --arch=x64 --version=0.25.1
Optional options
out the dir to put the app into at the end. defaults to current working dir
icon the icon file to use as the icon for the app
app-bundle-id bundle identifier to use in the app plist
app-version version to set for the app
helper-bundle-id bundle identifier to use in the app helper plist
ignore do not copy files into App whose filenames regex .match this string
prune runs `npm prune --production` on the app
asar packages the source code within your app into an archive

View File

@ -10,18 +10,16 @@ var mv = require('mv')
var rcedit = require('rcedit')
module.exports = {
createApp: function createApp (opts, cb, electronPath) {
var electronApp = path.join(electronPath, 'dist')
createApp: function createApp (opts, electronApp, cb) {
var tmpDir = path.join(os.tmpdir(), 'electron-packager-windows')
var newApp = path.join(tmpDir, opts.name + '.app')
console.log('newApp', newApp)
var newApp = path.join(tmpDir, opts.name + '-win32')
// reset build folders + copy template app
rimraf(tmpDir, function rmrfd () {
// ignore errors
mkdirp(newApp, function mkdirpd () {
// ignore errors
// copy .app folder and use as template (this is exactly what Atom editor does)
// copy app folder and use as template (this is exactly what Atom editor does)
ncp(electronApp, newApp, function copied (err) {
if (err) return cb(err)
// rename electron.exe
@ -82,8 +80,7 @@ function buildWinApp (opts, cb, newApp) {
function moveApp () {
// finally, move app into cwd
var finalPath = path.join(opts.out || process.cwd(), opts.name + '.app')
console.log('finalPath', finalPath)
var finalPath = path.join(opts.out || process.cwd(), opts.name + '-win32')
copy(newApp, finalPath, function moved (err) {
if (err) return cb(err)
if (opts.asar) {
@ -98,13 +95,13 @@ function buildWinApp (opts, cb, newApp) {
}
function updateIcon () {
var finalPath = path.join(opts.out || process.cwd(), opts.name + '.app')
var finalPath = path.join(opts.out || process.cwd(), opts.name + '-win32')
if (!opts.icon) {
return cb(null, finalPath)
}
var exePath = path.join(opts.out || process.cwd(), opts.name + '.app', opts.name + '.exe')
var exePath = path.join(opts.out || process.cwd(), opts.name + '-win32', opts.name + '.exe')
rcedit(exePath, {icon: opts.icon}, function (err) {
cb(err, finalPath)
@ -113,7 +110,7 @@ function buildWinApp (opts, cb, newApp) {
}
function asarApp (cb) {
var finalPath = path.join(opts.out || process.cwd(), opts.name + '.app', 'resources')
var finalPath = path.join(opts.out || process.cwd(), opts.name + '-win32', 'resources')
var src = path.join(finalPath, 'app')
var dest = path.join(finalPath, 'app.asar')
asar.createPackage(src, dest, function (err) {