Skip to content

Commit

Permalink
Merge tag 'v6.0.1' into runelite
Browse files Browse the repository at this point in the history
jdk requires 10.12
this means we can use ULFO everywhere, which requires 10.11 (UDBZ was 10.4)
however APFS requires 10.13, so use HFS+ instead
  • Loading branch information
Adam- committed Nov 3, 2023
2 parents fffb129 + 198716c commit 5809af2
Show file tree
Hide file tree
Showing 30 changed files with 447 additions and 130 deletions.
4 changes: 0 additions & 4 deletions .github/funding.yml

This file was deleted.

22 changes: 22 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI
on:
- push
- pull_request
jobs:
test:
name: Node.js ${{ matrix.node-version }}
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
node-version:
- 18
- 16
- 14
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
6 changes: 0 additions & 6 deletions .travis.yml

This file was deleted.

33 changes: 33 additions & 0 deletions base.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
data 'TMPL' (128, "LPic") {
$"1344 6566 6175 6C74 204C 616E 6775 6167" /* .Default Languag */
$"6520 4944 4457 5244 0543 6F75 6E74 4F43" /* e IDDWRD.CountOC */
$"4E54 042A 2A2A 2A4C 5354 430B 7379 7320" /* NT.****LSTC.sys */
$"6C61 6E67 2049 4444 5752 441E 6C6F 6361" /* lang IDDWRD.loca */
$"6C20 7265 7320 4944 2028 6F66 6673 6574" /* l res ID (offset */
$"2066 726F 6D20 3530 3030 4457 5244 1032" /* from 5000DWRD.2 */
$"2D62 7974 6520 6C61 6E67 7561 6765 3F44" /* -byte language?D */
$"5752 4404 2A2A 2A2A 4C53 5445" /* WRD.****LSTE */
};

data 'LPic' (5000) {
$"0000 0001 0000 0000 0000"
};

data 'STR#' (5000, "English") {
$"0006 0745 6E67 6C69 7368 0541 6772 6565" /* ...English.Agree */
$"0844 6973 6167 7265 6505 5072 696E 7407" /* .Disagree.Print. */
$"5361 7665 2E2E 2E7B 4966 2079 6F75 2061" /* Save...{If you a */
$"6772 6565 2077 6974 6820 7468 6520 7465" /* gree with the te */
$"726D 7320 6F66 2074 6869 7320 6C69 6365" /* rms of this lice */
$"6E73 652C 2070 7265 7373 2022 4167 7265" /* nse, press "Agre */
$"6522 2074 6F20 696E 7374 616C 6C20 7468" /* e" to install th */
$"6520 736F 6674 7761 7265 2E20 2049 6620" /* e software. If */
$"796F 7520 646F 206E 6F74 2061 6772 6565" /* you do not agree */
$"2C20 7072 6573 7320 2244 6973 6167 7265" /* , press "Disagre */
$"6522 2E" /* e". */
};

data 'styl' (5000, "English") {
$"0001 0000 0000 000E 0011 0015 0000 000C"
$"0000 0000 0000"
};
150 changes: 99 additions & 51 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#!/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 composeIcon = require('./compose-icon');
import process from 'node:process';
import path from 'node:path';
import fs from 'node:fs';
import {fileURLToPath} from 'node:url';
import meow from 'meow';
import appdmg from 'appdmg';
import plist from 'plist';
import Ora from 'ora';
import {execa} from 'execa';
import addLicenseAgreementIfNeeded from './sla.js';
import composeIcon from './compose-icon.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

if (process.platform !== 'darwin') {
console.error('macOS only');
Expand All @@ -19,42 +23,44 @@ const cli = meow(`
$ create-dmg <app> [destination]
Options
--overwrite Overwrite existing DMG with the same name
--identity=<value> Manually set code signing identity (automatic by default)
--format Set DMG format (default ULFO)
--overwrite Overwrite existing DMG with the same name
--identity=<value> Manually set code signing identity (automatic by default)
--dmg-title=<value> Manually set DMG title (must be <=27 characters) [default: App name]
Examples
$ create-dmg 'Lungo.app'
$ create-dmg 'Lungo.app' Build/Releases
`, {
importMeta: import.meta,
flags: {
overwrite: {
type: 'boolean'
type: 'boolean',
},
identity: {
type: 'string'
type: 'string',
},
format: {
dmgTitle: {
type: 'string',
default: 'ULFO'
}
}
},
},
});

let [appPath, destPath] = cli.input;
let [appPath, destinationPath] = cli.input;

if (!appPath) {
console.error('Specify an app');
process.exit(1);
}

if (!destPath) {
destPath = process.cwd();
if (!destinationPath) {
destinationPath = process.cwd();
}

const infoPlistPath = path.join(appPath, 'Contents/Info.plist');

let infoPlist;
try {
infoPlist = fs.readFileSync(path.join(appPath, 'Contents/Info.plist'), 'utf8');
infoPlist = fs.readFileSync(infoPlistPath, 'utf8');
} catch (error) {
if (error.code === 'ENOENT') {
console.error(`Could not find \`${path.relative(process.cwd(), appPath)}\``);
Expand All @@ -64,57 +70,84 @@ try {
throw error;
}

const appInfo = plist.parse(infoPlist);
const appName = appInfo.CFBundleDisplayName || appInfo.CFBundleName;
const appIconName = appInfo.CFBundleIconFile.replace(/\.icns/, '');
const dmgPath = path.join(destPath, `${appName} ${appInfo.CFBundleShortVersionString}.dmg`);

const ora = new Ora('Creating DMG');
ora.start();

async function init() {
let appInfo;
try {
appInfo = plist.parse(infoPlist);
} catch {
const {stdout} = await execa('/usr/bin/plutil', ['-convert', 'xml1', '-o', '-', infoPlistPath]);
appInfo = plist.parse(stdout);
}

const appName = appInfo.CFBundleDisplayName || appInfo.CFBundleName;
if (!appName) {
throw new Error('The app must have `CFBundleDisplayName` or `CFBundleName` defined in its `Info.plist`.');
}

const dmgTitle = cli.flags.dmgTitle || appName;
const dmgFilename = `${appName} ${appInfo.CFBundleShortVersionString}.dmg`;
const dmgPath = path.join(destinationPath, dmgFilename);

if (dmgTitle.length > 27) {
ora.fail('The disk image title cannot exceed 27 characters. This is a limitation in a dependency: https://github.com/LinusU/node-alias/issues/7');
process.exit(1);
}

if (cli.flags.overwrite) {
try {
fs.unlinkSync(dmgPath);
} catch (_) {}
} catch {}
}

ora.text = 'Creating icon';
const composedIconPath = await composeIcon(path.join(appPath, 'Contents/Resources', `${appIconName}.icns`));
const hasAppIcon = appInfo.CFBundleIconFile;
let composedIconPath;
if (hasAppIcon) {
ora.text = 'Creating icon';
const appIconName = appInfo.CFBundleIconFile.replace(/\.icns/, '');
composedIconPath = await composeIcon(path.join(appPath, 'Contents/Resources', `${appIconName}.icns`));
}

// Xcode 14+ only supports building apps for macOS 10.13+
const dmgFormat = 'ULFO'; // ULFO requires macOS 10.11+
const dmgFilesystem = 'HFS+';

const ee = appdmg({
target: dmgPath,
basepath: process.cwd(),
specification: {
title: appName,
title: dmgTitle,
icon: composedIconPath,
//
// 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: cli.flags.format,
format: dmgFormat,
filesystem: dmgFilesystem,
window: {
size: {
width: 660,
height: 400
}
height: 400,
},
},
contents: [
{
x: 180,
y: 170,
type: 'file',
path: appPath
path: appPath,
},
{
x: 480,
y: 170,
type: 'link',
path: '/Applications'
}
]
}
path: '/Applications',
},
],
},
});

ee.on('progress', info => {
Expand All @@ -125,29 +158,42 @@ async function init() {

ee.on('finish', async () => {
try {
ora.text = 'Replacing DMG icon';
// `seticon`` is a native tool to change files icons (Source: https://github.com/sveinbjornt/osxiconutils)
await execa(path.join(__dirname, 'seticon'), [composedIconPath, dmgPath]);
ora.text = 'Adding Software License Agreement if needed';
await addLicenseAgreementIfNeeded(dmgPath, dmgFormat);

if (hasAppIcon) {
ora.text = 'Replacing DMG icon';
// `seticon`` is a native tool to change files icons (Source: https://github.com/sveinbjornt/osxiconutils)
await execa(path.join(__dirname, 'seticon'), [composedIconPath, dmgPath]);
}

ora.text = 'Code signing DMG';
let identity;
const {stdout} = await execa('security', ['find-identity', '-v', '-p', 'codesigning']);
const {stdout} = await execa('/usr/bin/security', ['find-identity', '-v', '-p', 'codesigning']);
if (cli.flags.identity && stdout.includes(`"${cli.flags.identity}"`)) {
identity = cli.flags.identity;
} else if (!cli.flags.identity && stdout.includes('Developer ID Application:')) {
identity = 'Developer ID Application';
} else if (!cli.flags.identity && stdout.includes('Mac Developer:')) {
identity = 'Mac Developer';
} else if (!cli.flags.identity && stdout.includes('Apple Development:')) {
identity = 'Apple Development';
}

if (!identity) {
const error = new Error();
const error = new Error(); // eslint-disable-line unicorn/error-message
error.stderr = 'No suitable code signing identity found';
throw error;
}

await execa('codesign', ['--sign', identity, dmgPath]);
const {stderr} = await execa('codesign', [dmgPath, '--display', '--verbose=2']);
try {
await execa('/usr/bin/codesign', ['--sign', identity, dmgPath]);
} catch (error) {
ora.fail(`Code signing failed. The DMG is fine, just not code signed.\n${error.stderr?.trim() ?? error}`);
process.exit(2);
}

const {stderr} = await execa('/usr/bin/codesign', [dmgPath, '--display', '--verbose=2']);

const match = /^Authority=(.*)$/m.exec(stderr);
if (!match) {
Expand All @@ -156,9 +202,9 @@ async function init() {
}

ora.info(`Code signing identity: ${match[1]}`).start();
ora.succeed('DMG created');
ora.succeed(`Created “${dmgFilename}”`);
} catch (error) {
ora.fail(`Code signing failed. The DMG is fine, just not code signed.\n${error.stderr.trim()}`);
ora.fail(`${error.stderr?.trim() ?? error}`);
process.exit(2);
}
});
Expand All @@ -169,7 +215,9 @@ async function init() {
});
}

init().catch(error => {
ora.fail(error);
try {
await init();
} catch (error) {
ora.fail((error && error.stack) || error);
process.exit(1);
});
}
Loading

0 comments on commit 5809af2

Please sign in to comment.