forked from sindresorhus/create-dmg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.js
executable file
·115 lines (99 loc) · 2.45 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env node
'use strict';
const path = require('path');
const fs = require('fs');
const meow = require('meow');
const appdmg = require('appdmg');
const plist = require('plist');
const Ora = require('ora');
const execa = require('execa');
const cli = meow(`
Usage
$ create-dmg <app>
Example
$ create-dmg 'Lungo.app'
`);
if (process.platform !== 'darwin') {
console.error('macOS only');
process.exit(1);
}
if (cli.input.length === 0) {
console.error('Specify an app');
process.exit(1);
}
const appPath = path.resolve(cli.input[0]);
let infoPlist;
try {
infoPlist = fs.readFileSync(path.join(appPath, 'Contents/Info.plist'), 'utf8');
} catch (err) {
if (err.code === 'ENOENT') {
console.error(`Could not find "${path.relative(process.cwd(), appPath)}"`);
process.exit(1);
}
throw err;
}
const appInfo = plist.parse(infoPlist);
const appName = appInfo.CFBundleName;
const appIconName = appInfo.CFBundleIconFile.replace(/\.icns/, '');
const dmgPath = `${appName.replace(/ /g, '-')}-${appInfo.CFBundleShortVersionString}.dmg`;
const ora = new Ora('Creating DMG');
ora.start();
const ee = appdmg({
target: dmgPath,
basepath: __dirname,
specification: {
title: appName,
icon: path.join(appPath, 'Contents/Resources', `${appIconName}.icns`),
// Use transparent background and `background-color` option when this is fixed:
// https://github.com/LinusU/node-appdmg/issues/135
background: path.join(__dirname, 'assets/dmg-background.png'),
'icon-size': 160,
format: 'ULFO',
window: {
size: {
width: 660,
height: 400
}
},
contents: [
{
x: 180,
y: 170,
type: 'file',
path: appPath
},
{
x: 480,
y: 170,
type: 'link',
path: '/Applications'
}
]
}
});
ee.on('progress', info => {
if (info.type === 'step-begin') {
ora.text = info.title;
}
});
ee.on('finish', () => {
ora.text = 'Code signing DMG';
execa('codesign', ['--sign', 'Developer ID Application', dmgPath]).then(() => {
return execa.stderr('codesign', [dmgPath, '--display', '--verbose=2']);
}).then(stderr => {
const match = /^Authority=(.*)$/m.exec(stderr);
if (!match) {
ora.fail('Not code signed');
process.exit(1);
}
ora.info(`Code signing identity: ${match[1]}`).start();
ora.succeed('DMG created');
}).catch(err => {
ora.fail(`Code signing failed. The DMG is fine, just not code signed.\n${err.stderr.trim()}`);
process.exit(1);
});
});
ee.on('error', err => {
ora.fail(err);
process.exit(1);
});