-
Notifications
You must be signed in to change notification settings - Fork 15
/
build.js
130 lines (119 loc) · 3 KB
/
build.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* eslint-disable no-console */
/**
* Build script for compiling the app UI. This must be run before packaging the app for
* for distribution. By default, this script will compile the app and start it.
*
* Options:
* --no-browser: Do not open a browser when running.
* --watch: Rebuild and restart app when source files change.
* --build-only: Do not run the app after building.
*/
import { watch } from 'chokidar';
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
function includeIf(predicate, elem) {
if (typeof predicate === 'function') {
return predicate() ? [elem] : [];
}
return predicate ? [elem] : [];
}
function asyncTimeout(millis) {
return new Promise((resolve) => {
setTimeout(() => resolve(), millis);
});
}
function debounce(func, millis, initial = false) {
let count = 0;
const loop = async (...args) => {
if (!count && initial) {
func(...args);
}
count++;
const id = count;
await asyncTimeout(millis);
if (id === count) {
count = 0;
if (id > 1 || !initial) {
func(...args);
}
}
};
return loop;
}
async function execPrint(command) {
try {
const { stdout, stderr } = await execAsync(command);
if (stdout) {
console.log(stdout);
}
if (stderr) {
console.error(stderr);
}
} catch (error) {
console.error(error);
throw error;
}
}
async function compile({ targetPath, noBrowser, buildOnly, watch }) {
try {
console.log('Compiling TS...');
await execPrint('npx tsc');
console.log('Compiling SCSS...');
await execPrint('npx sass mangareader/src/styles.scss mangareader/build/styles.css');
if (!buildOnly) {
console.log('Starting app...');
const pyArgs = [
...includeIf(targetPath, `"${targetPath}"`),
...includeIf(noBrowser, '--no-browser'),
];
await execPrint(`python reader.py ${pyArgs.join(' ')}`);
}
console.log('Compile successful.');
} catch (error) {
console.error('Compile failed.');
if (!watch) {
process.exit(1);
}
}
}
function processArgs() {
const [, , ...args] = process.argv;
const targetPath = args.find((arg) => !arg.startsWith('-'));
const isNoBrowser = args.includes('--no-browser');
const isWatch = args.includes('--watch');
const isBuildOnly = args.includes('--build-only');
return {
targetPath,
noBrowser: isNoBrowser,
watch: isWatch,
buildOnly: isBuildOnly,
};
}
function startWatch(args) {
const debouncedCompile = debounce(compile, 500);
const watcher = watch(
[
'mangareader/**/*.py',
'mangareader/**/*.ts',
'mangareader/**/*.scss',
'mangareader/**/*.html',
'reader.py',
],
{
persistent: true,
},
);
watcher.on('change', async (path) => {
console.log('File changed:', path);
await debouncedCompile(args);
});
}
function main() {
const args = processArgs();
if (args.watch) {
startWatch(args);
}
compile(args);
}
main();