@driftengine/package 3.62.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +20 -0
- package/README.md +58 -1
- package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
- package/dist/bootstrap.js +7 -1
- package/dist/build.js +23 -10
- package/dist/cli.js +50 -7
- package/dist/flags.js +16 -0
- package/dist/main/ipc.js +5 -19
- package/dist/main/storeFile.d.ts +30 -0
- package/dist/main/storeFile.js +104 -0
- package/dist/main/window.js +6 -3
- package/dist/manifest.d.ts +8 -1
- package/dist/manifest.js +8 -0
- package/dist/native.d.ts +67 -0
- package/dist/native.js +212 -0
- package/dist/nativeBundle.d.ts +53 -0
- package/dist/nativeBundle.js +177 -0
- package/dist/nativeCopy.d.ts +39 -0
- package/dist/nativeCopy.js +110 -0
- package/dist/nativeLicenses.d.ts +42 -0
- package/dist/nativeLicenses.js +131 -0
- package/dist/signing.js +2 -2
- package/dist/toolchain.js +3 -0
- package/package.json +12 -2
- package/src/bootstrap.ts +11 -1
- package/src/build.ts +25 -13
- package/src/cli.ts +54 -7
- package/src/flags.ts +18 -0
- package/src/main/ipc.ts +6 -17
- package/src/main/storeFile.ts +113 -0
- package/src/main/window.ts +6 -3
- package/src/manifest.ts +19 -1
- package/src/native.ts +263 -0
- package/src/nativeBundle.ts +215 -0
- package/src/nativeCopy.ts +133 -0
- package/src/nativeLicenses.ts +163 -0
- package/src/signing.ts +2 -2
- package/src/toolchain.ts +3 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The native artifact's `licenses/`: Node's licence, and each package's licence files, with an
|
|
3
|
+
* index saying what every part is under.
|
|
4
|
+
*
|
|
5
|
+
* **Because a bundle drops them.** The desktop target ships Electron, whose own licence files come
|
|
6
|
+
* with it, and a game's web build that its own bundler made. The native target bundles every
|
|
7
|
+
* package the game and the host import into one file, and most of them are MIT or BSD, whose one
|
|
8
|
+
* condition is that the notice goes with the copy — so this build is the one that has to carry it.
|
|
9
|
+
*
|
|
10
|
+
* **Node's licence is the binary's own**, and covers what Node carries inside it: V8, OpenSSL, ICU
|
|
11
|
+
* and the rest. It is read from beside the binary where the release archive puts it, or from `n`'s
|
|
12
|
+
* cache, and otherwise fetched at the exact release that is being shipped. A file there that does
|
|
13
|
+
* not open as Node's does is passed over, because `LICENSE` one directory above `/usr/local/bin` can
|
|
14
|
+
* be anybody's.
|
|
15
|
+
*
|
|
16
|
+
* **The LGPL 3.0 comes with the GPL 3.0**, because it is written as permissions on top of it and
|
|
17
|
+
* asks for both texts; the library's own package carries only the first. And **a copyleft package is
|
|
18
|
+
* named** (`copyleftOf`) so that the build can refuse to bundle one: a dual licence counts as
|
|
19
|
+
* permissive when either half is.
|
|
20
|
+
*
|
|
21
|
+
* What it gives up: a package whose licence is only a word in its manifest has no text to copy, and
|
|
22
|
+
* the index says so for each one rather than inventing one.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
26
|
+
import { copyFile, mkdir, writeFile } from 'node:fs/promises';
|
|
27
|
+
import { dirname, join } from 'node:path';
|
|
28
|
+
|
|
29
|
+
/** What a package's licence files are called, and its notice, which Apache-2.0 asks to go too. */
|
|
30
|
+
const LICENCE_FILE = /^(licen[cs]e|copying|notice)([.-].*)?$/i;
|
|
31
|
+
const NODE_OPENS = 'Node.js is licensed';
|
|
32
|
+
/** The licences whose terms reach the file a library is bundled into, by their SPDX names. */
|
|
33
|
+
const COPYLEFT = /\b(?:AGPL|LGPL|GPL|MPL|EPL|EUPL|CDDL|OSL)-/i;
|
|
34
|
+
const LGPL3 = /\bLGPL-3\.0/i;
|
|
35
|
+
|
|
36
|
+
function manifestOf(dir: string): { name: string; version?: string; license?: unknown } {
|
|
37
|
+
return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {
|
|
38
|
+
name: string;
|
|
39
|
+
version?: string;
|
|
40
|
+
license?: unknown;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Whether `license`, an SPDX expression, holds a work to a copyleft licence: every alternative of
|
|
46
|
+
* an `OR` is copyleft, since otherwise a permissive one can be chosen.
|
|
47
|
+
*/
|
|
48
|
+
function copyleft(license: string): boolean {
|
|
49
|
+
return license
|
|
50
|
+
.replace(/[()]/g, '')
|
|
51
|
+
.split(/\s+OR\s+/i)
|
|
52
|
+
.every((alternative) => COPYLEFT.test(alternative));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Each of `packageDirs` under a copyleft licence, as `name (licence)`. The native build refuses to
|
|
57
|
+
* bundle one: the LGPL lets a work of any licence use its library so long as a person can put a
|
|
58
|
+
* modified copy in its place, which one file with the game in it does not allow, and the others
|
|
59
|
+
* reach further.
|
|
60
|
+
*/
|
|
61
|
+
export function copyleftOf(packageDirs: Iterable<string>): string[] {
|
|
62
|
+
const found: string[] = [];
|
|
63
|
+
for (const dir of packageDirs) {
|
|
64
|
+
const { name, license } = manifestOf(dir);
|
|
65
|
+
if (typeof license === 'string' && copyleft(license)) found.push(`${name} (${license})`);
|
|
66
|
+
}
|
|
67
|
+
return found;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type FetchText = (url: string) => Promise<string>;
|
|
71
|
+
|
|
72
|
+
/** Node's licence for the binary at `execPath`, which is `version`, or a refusal naming both. */
|
|
73
|
+
export async function nodeLicense(
|
|
74
|
+
execPath: string,
|
|
75
|
+
version: string,
|
|
76
|
+
fetchText: FetchText,
|
|
77
|
+
): Promise<string> {
|
|
78
|
+
const prefix = dirname(dirname(execPath));
|
|
79
|
+
for (const candidate of [
|
|
80
|
+
join(prefix, 'LICENSE'),
|
|
81
|
+
join(prefix, 'n', 'versions', 'node', version.replace(/^v/, ''), 'LICENSE'),
|
|
82
|
+
]) {
|
|
83
|
+
if (!existsSync(candidate)) continue;
|
|
84
|
+
const text = readFileSync(candidate, 'utf8');
|
|
85
|
+
if (text.startsWith(NODE_OPENS)) return text;
|
|
86
|
+
}
|
|
87
|
+
const url = `https://raw.githubusercontent.com/nodejs/node/${version}/LICENSE`;
|
|
88
|
+
let text: string;
|
|
89
|
+
try {
|
|
90
|
+
text = await fetchText(url);
|
|
91
|
+
} catch (cause) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`the native artifact ships Node ${version} and must carry Node's licence, and there is no ` +
|
|
94
|
+
`copy beside ${execPath} and none could be fetched from ${url}: ${String(cause)}`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
if (!text.startsWith(NODE_OPENS)) {
|
|
98
|
+
throw new Error(`${url} answered a text that is not Node's licence; nothing was written`);
|
|
99
|
+
}
|
|
100
|
+
return text;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The licences directory for `packageDirs` and Node, written into `into`. `gpl` is the GPL's text,
|
|
105
|
+
* which goes beside any part under the LGPL 3.0: that licence is written as permissions on top of
|
|
106
|
+
* the GPL, and its section 4 asks for both texts to accompany a work that uses the library.
|
|
107
|
+
*/
|
|
108
|
+
export async function writeLicenses(
|
|
109
|
+
packageDirs: Iterable<string>,
|
|
110
|
+
node: { readonly version: string; readonly text: string },
|
|
111
|
+
into: string,
|
|
112
|
+
gpl: string | null,
|
|
113
|
+
): Promise<void> {
|
|
114
|
+
const packages = [...packageDirs].map((dir) => ({ dir, manifest: manifestOf(dir) }));
|
|
115
|
+
packages.sort((a, b) => (a.manifest.name < b.manifest.name ? -1 : 1));
|
|
116
|
+
const lesser = packages.find(
|
|
117
|
+
({ manifest }) => typeof manifest.license === 'string' && LGPL3.test(manifest.license),
|
|
118
|
+
);
|
|
119
|
+
if (lesser !== undefined && gpl === null) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`${lesser.manifest.name} is ${String(lesser.manifest.license)}, which asks for the GPL's text ` +
|
|
122
|
+
'to go with it, and none was given to write beside it',
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
await mkdir(join(into, 'node'), { recursive: true });
|
|
127
|
+
await writeFile(join(into, 'node', 'LICENSE'), node.text);
|
|
128
|
+
const lines = [`node ${node.version} — node/LICENSE`];
|
|
129
|
+
|
|
130
|
+
for (const { dir, manifest } of packages) {
|
|
131
|
+
const folder = manifest.name.replace('/', '+');
|
|
132
|
+
const named = typeof manifest.license === 'string' ? manifest.license : 'no licence';
|
|
133
|
+
const files = readdirSync(dir, { withFileTypes: true })
|
|
134
|
+
.filter((entry) => entry.isFile() && LICENCE_FILE.test(entry.name))
|
|
135
|
+
.map((entry) => entry.name)
|
|
136
|
+
.sort();
|
|
137
|
+
const heading = `${manifest.name} ${manifest.version ?? ''} (${named})`;
|
|
138
|
+
if (files.length === 0) {
|
|
139
|
+
lines.push(`${heading} — the package carries no licence file; its manifest names ${named}`);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
await mkdir(join(into, folder), { recursive: true });
|
|
143
|
+
for (const file of files) await copyFile(join(dir, file), join(into, folder, file));
|
|
144
|
+
lines.push(`${heading} — ${files.map((file) => `${folder}/${file}`).join(', ')}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (lesser !== undefined && gpl !== null) {
|
|
148
|
+
await writeFile(join(into, 'GPL-3.0.txt'), gpl);
|
|
149
|
+
lines.push(
|
|
150
|
+
'GPL-3.0 — GPL-3.0.txt, which the LGPL-3.0 above is written against and asks to accompany it',
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
await writeFile(
|
|
155
|
+
join(into, 'INDEX.txt'),
|
|
156
|
+
[
|
|
157
|
+
'Everything this application ships, and the licence each part is under.',
|
|
158
|
+
'',
|
|
159
|
+
...lines,
|
|
160
|
+
'',
|
|
161
|
+
].join('\n'),
|
|
162
|
+
);
|
|
163
|
+
}
|
package/src/signing.ts
CHANGED
|
@@ -63,14 +63,14 @@ export function planSigning(
|
|
|
63
63
|
env: Readonly<Record<string, string | undefined>>,
|
|
64
64
|
platform: BuildHost,
|
|
65
65
|
): SigningPlan {
|
|
66
|
-
if (target === 'linux-x64') {
|
|
66
|
+
if (target === 'linux-x64' || target === 'native-linux-x64') {
|
|
67
67
|
return {
|
|
68
68
|
...HOST_SIGNED,
|
|
69
69
|
mode: 'none',
|
|
70
70
|
notarise: false,
|
|
71
71
|
/* No signature is expected of a Linux artifact by anything that runs one. An AppImage can
|
|
72
72
|
carry a detached GPG signature and nothing checks it by default, so producing one would be
|
|
73
|
-
ceremony rather than protection. */
|
|
73
|
+
ceremony rather than protection. The native host's archive is the same case. */
|
|
74
74
|
reason: 'Linux artifacts are not signed; nothing on the platform checks one',
|
|
75
75
|
};
|
|
76
76
|
}
|
package/src/toolchain.ts
CHANGED
|
@@ -188,6 +188,9 @@ export function requirementsFor(target: Target): readonly string[] {
|
|
|
188
188
|
/* XcodeGen is downloadable; Xcode is not, and pretending otherwise would be the lie this
|
|
189
189
|
file exists to avoid — it is a sign-in and an App Store download, and only on a Mac. */
|
|
190
190
|
return ['macOS', 'Xcode with the iOS SDK', PINS.xcodegen.label];
|
|
191
|
+
case 'native-linux-x64':
|
|
192
|
+
/* Nothing of the machine: it ships the Node that runs the build. The host is the game's. */
|
|
193
|
+
return ["@driftengine/native-host at the packager's version, installed in the game"];
|
|
191
194
|
default:
|
|
192
195
|
return [
|
|
193
196
|
'the Electron runtime for this platform',
|