Merge pull request #7 from sethlu/electron-osx-flat

Flattening signed application package
This commit is contained in:
Zhuo Lu 2016-02-15 17:42:30 +08:00
Родитель 5b4b197f03 e0c30079ed
Коммит a01b00bb22
6 изменённых файлов: 250 добавлений и 32 удалений

160
README.md
Просмотреть файл

@ -18,7 +18,9 @@ npm install electron-osx-sign -g
## Usage
### From the Command Line
### electron-osx-sign
#### From the Command Line
```sh
electron-osx-sign <app> [additional-binaries...] [--options...]
@ -32,11 +34,11 @@ electron-osx-sign path/to/my.app
For details on the optional flags, run `electron-osx-sign --help` or see [electron-osx-sign-usage.txt](https://github.com/sethlu/electron-sign/blob/master/bin/electron-osx-sign-usage.txt).
### From the API
#### From the API
```javascript
var sign = require('electron-osx-sign')
sign(opts[, function done (err) {}])
sign(opts[, function callback (err) {}])
```
Example:
@ -45,7 +47,7 @@ Example:
var sign = require('electron-osx-sign')
sign({
app: 'path/to/my.app'
}, function done (err) {
}, function callback (err) {
if (err) {
// Handle the error
return;
@ -54,15 +56,16 @@ sign({
})
```
#### sign(opts, callback)
##### sign(opts, callback)
##### opts
###### opts
**Required**
`app` - *String*
Path to the application package.
Needs file extension `.app`.
**Optional**
@ -131,7 +134,86 @@ Default to auto detect from presence of `Squirrel.framework` within the applicat
Verbose flag, to display every action through `console.log()`.
Allowed values: `true`, `false`.
##### callback
###### callback
`err` - *Error*
### electron-osx-flat
#### From the Command Line
```sh
electron-osx-flat <app> [--options...]
```
Example:
```sh
electron-osx-flat path/to/my.app
```
For details on the optional flags, run `electron-osx-flat --help` or see [electron-osx-flat-usage.txt](https://github.com/sethlu/electron-sign/blob/master/bin/electron-osx-flat-usage.txt).
#### From the API
```javascript
var flat = require('electron-osx-sign').flat
flat(opts[, function done (err) {}])
```
Example:
```javascript
var flat = require('electron-osx-sign').flat
flat({
app: 'path/to/my.app'
}, function done (err) {
if (err) {
// Handle the error
return;
}
// Regular callback
})
```
##### flat(opts, callback)
###### opts
**Required**
`app` - *String*
Path to the application package.
Needs file extension `.app`.
**Optional**
`identity` - *String*
Name of certificate to use when flattening.
Default to retrieve from `login.keychain`.
`install` - *String*
Path to install for the bundle.
Default to `/Applications`.
`platform` - *String*
Build platform of Electron. Allowed values: `darwin`, `mas`.
Default to auto detect from application.
`pkg` - *String*
Path to the output flattened package.
Needs file extension `.app`.
`verbose` - *String*
Verbose flag, to display every action.
###### callback
`err` - *Error*
@ -183,41 +265,57 @@ TAP version 13
# setup
# defaults-test:v0.24.0-darwin-x64
ok 1 app signed
ok 2 app flattened
# defaults-test:v0.25.0-darwin-x64
ok 2 app signed
# defaults-test:v0.26.0-darwin-x64
ok 3 app signed
# defaults-test:v0.27.0-darwin-x64
ok 4 app signed
# defaults-test:v0.28.0-darwin-x64
ok 4 app flattened
# defaults-test:v0.26.0-darwin-x64
ok 5 app signed
# defaults-test:v0.29.0-darwin-x64
ok 6 app signed
# defaults-test:v0.30.0-darwin-x64
ok 6 app flattened
# defaults-test:v0.27.0-darwin-x64
ok 7 app signed
# defaults-test:v0.31.0-darwin-x64
ok 8 app signed
# defaults-test:v0.32.0-darwin-x64
ok 8 app flattened
# defaults-test:v0.28.0-darwin-x64
ok 9 app signed
# defaults-test:v0.33.0-darwin-x64
ok 10 app signed
# defaults-test:v0.34.0-darwin-x64
ok 10 app flattened
# defaults-test:v0.29.0-darwin-x64
ok 11 app signed
# defaults-test:v0.34.0-mas-x64
ok 12 app signed
# defaults-test:v0.35.0-darwin-x64
ok 12 app flattened
# defaults-test:v0.30.0-darwin-x64
ok 13 app signed
# defaults-test:v0.35.0-mas-x64
ok 14 app signed
# defaults-test:v0.36.0-darwin-x64
ok 14 app flattened
# defaults-test:v0.31.0-darwin-x64
ok 15 app signed
ok 16 app flattened
# defaults-test:v0.32.0-darwin-x64
ok 17 app signed
ok 18 app flattened
# defaults-test:v0.33.0-darwin-x64
ok 19 app signed
ok 20 app flattened
# defaults-test:v0.34.0-darwin-x64
ok 21 app signed
ok 22 app flattened
# defaults-test:v0.34.0-mas-x64
ok 23 app signed
ok 24 app flattened
# defaults-test:v0.35.0-darwin-x64
ok 25 app signed
ok 26 app flattened
# defaults-test:v0.35.0-mas-x64
ok 27 app signed
ok 28 app flattened
# defaults-test:v0.36.0-darwin-x64
ok 29 app signed
ok 30 app flattened
# defaults-test:v0.36.0-mas-x64
ok 16 app signed
ok 31 app signed
ok 32 app flattened
# teardown
1..16
# tests 16
# pass 16
1..32
# tests 32
# pass 32
# ok
```

Просмотреть файл

@ -0,0 +1,10 @@
Usage: electron-osx-flat <app> [--options...]
Optional options
identity Name of certificate to use when flattening. Default to retrieve from `login.keychain`.
install Path to install for the bundle. Default `/Applications`.
platform Build platform of Electron. Allowed values: darwin, mas. Default to auto detect from application package.
pkg Path to the output package.
verbose Verbose flag, to display every action.

23
bin/electron-osx-flat.js Executable file
Просмотреть файл

@ -0,0 +1,23 @@
#!/usr/bin/env node
var fs = require('fs')
var args = require('minimist')(process.argv.slice(2), {boolean: ['help', 'verbose']})
var usage = fs.readFileSync(__dirname + '/electron-osx-flat-usage.txt').toString()
var flat = require('../').flat
args.app = args._.shift()
if (!args.app || args.help) {
console.log(usage)
process.exit(0)
}
flat(args, function done (err) {
if (err) {
console.error('Flat failed.')
if (err.message) console.error(err.message)
else console.error(err, err.stack)
process.exit(1)
}
console.log('Application flattened:', args.pkg)
process.exit(0)
})

Просмотреть файл

@ -33,6 +33,29 @@ function findIdentity (opts, identity, cb) {
})
}
function flatApplication (opts, callback) {
var operations = []
// Call productbuild
operations.push(function (cb) {
child.exec([
'productbuild',
'--component', '"' + opts.app.replace(/"/g, '\\"') + '"', '"' + opts.install.replace(/"/g, '\\"') + '"',
'--sign', '"' + opts.identity + '"',
'"' + opts.pkg.replace(/"/g, '\\"') + '"'
].join(' '), function (err, stdout, stderr) {
if (err) return cb(err)
cb()
})
if (opts.verbose) console.log('Flattening with productbuild...')
})
series(operations, function (err) {
if (err) return callback(err)
callback()
})
}
function generateAppBasename (opts) {
return path.basename(opts.app, '.app')
}
@ -293,3 +316,61 @@ module.exports = function sign (opts, cb) {
return signApplication(opts, cb)
})
}
module.exports.flat = function flat (opts, cb) {
// Default callback function if none provided
if (!cb) {
cb = function (err) {
if (err) {
if (opts.verbose) {
console.error('Flat failed.')
if (err.message) console.error(err.message)
else console.error(err, err.stack)
}
return
}
if (opts.verbose) console.log('Application flattened:', opts.pkg)
}
}
if (!opts.app) return cb(new Error('Path to aplication must be specified.'))
if (path.extname(opts.app) !== '.app') return cb(new Error('Extension of application must be `.app`.'))
if (!fs.existsSync(opts.app)) return cb(new Error('Application not found.'))
// Match platform if none is provided
if (!opts.pkg) {
if (opts.verbose) console.warn('No `--pkg` passed in arguments, will fallback to default, inferred from the given application.')
opts.pkg = path.join(path.dirname(opts.app), path.basename(opts.app, '.app') + '.pkg')
} else if (path.extname(opts.pkg) !== '.pkg') return cb(new Error('Extension of output package must be `.pkg`.'))
if (!opts.install) {
if (opts.verbose) console.warn('No `--install` passed in arguments, will fallback to default `/Applications`.')
opts.install = '/Applications'
}
series([
function (cb) {
// Checking identity with series for async execution of child process
if (!opts.identity) {
if (opts.verbose) console.warn('No `--identity` passed in arguments, matching identities...')
if (!opts.platform) {
if (opts.verbose) console.warn('No `--platform` passed in arguments, cheking Electron platform...')
detectElectronPlatform(opts)
} else if (opts.platform !== 'mas' && opts.platform !== 'darwin') {
return cb(new Error('Only platform `darwin` and `mas` are supported.'))
}
if (opts.platform === 'mas') {
findIdentity(opts, '3rd Party Mac Developer Installer', cb)
} else if (opts.platform === 'darwin') {
findIdentity(opts, 'Developer ID Installer', cb)
}
} else cb()
}
], function (err) {
if (err) return cb(err)
if (opts.verbose) {
console.log('Flattening application...')
console.log('> application ', opts.app)
console.log('> package-output ', opts.pkg)
console.log('> install-path ', opts.install)
console.log('> identity ', opts.identity)
}
return flatApplication(opts, cb)
})
}

Просмотреть файл

@ -4,6 +4,7 @@
"description": "Code-signing for Electron-packed OS X apps.",
"main": "index.js",
"bin": {
"electron-osx-flat": "bin/electron-osx-flat.js",
"electron-osx-sign": "bin/electron-osx-sign.js"
},
"repository": {
@ -31,6 +32,7 @@
"compare-version": "^0.1.2"
},
"scripts": {
"pretest": "rimraf test/work",
"test": "standard && tape test"
},
"standard": {

Просмотреть файл

@ -1,4 +1,5 @@
var sign = require('..')
var flat = require('..').flat
var waterfall = require('run-waterfall')
@ -16,9 +17,12 @@ function createDefaultsTest (release) {
waterfall([
function (cb) {
sign(opts, cb)
sign(Object.create(opts), cb)
}, function (cb) {
t.pass('app signed')
flat(Object.create(opts), cb)
}, function (cb) {
t.pass('app flattened')
cb()
}
], function (err) {