123 lines
2.6 KiB
JavaScript
Executable File
123 lines
2.6 KiB
JavaScript
Executable File
#!/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');
|
|
|
|
if (process.platform !== 'darwin') {
|
|
console.error('macOS only');
|
|
process.exit(1);
|
|
}
|
|
|
|
const cli = meow(`
|
|
Usage
|
|
$ create-dmg <app> [destination]
|
|
|
|
Examples
|
|
$ create-dmg 'Lungo.app'
|
|
$ create-dmg 'Lungo.app' Build/Releases
|
|
`);
|
|
|
|
let [appPath, destPath] = cli.input;
|
|
|
|
if (!appPath) {
|
|
console.error('Specify an app');
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!destPath) {
|
|
destPath = process.cwd();
|
|
}
|
|
|
|
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 = path.join(destPath, `${appName.replace(/ /g, '-')}-${appInfo.CFBundleShortVersionString}.dmg`);
|
|
|
|
const ora = new Ora('Creating DMG');
|
|
ora.start();
|
|
|
|
const ee = appdmg({
|
|
target: dmgPath,
|
|
basepath: __dirname,
|
|
specification: {
|
|
title: appName,
|
|
// Disabled because of #16
|
|
// 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', async () => {
|
|
ora.text = 'Code signing DMG';
|
|
|
|
try {
|
|
await execa('codesign', ['--sign', 'Developer ID Application', dmgPath]);
|
|
const {stderr} = await execa('codesign', [dmgPath, '--display', '--verbose=2']);
|
|
|
|
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', error => {
|
|
ora.fail(error);
|
|
process.exit(1);
|
|
});
|