multi-downloader-nx/tsc.ts
2024-04-11 13:17:29 -07:00

164 lines
No EOL
4.2 KiB
TypeScript

import { ChildProcess, exec } from 'child_process';
import fs from 'fs-extra';
import path from 'path';
import { removeSync, copyFileSync } from 'fs-extra';
const argv = process.argv.slice(2);
let buildIgnore: string[] = [];
const isTest = argv.length > 0 && argv[0] === 'test';
const isGUI = !(argv.length > 1 && argv[1] === 'false');
if (!isTest)
buildIgnore = [
'*/\\.env',
'./config/setup.json'
];
if (!isGUI)
buildIgnore = buildIgnore.concat([
'./gui*',
'./build*',
'gui.ts'
]);
const ignore = [
...buildIgnore,
'*/\\.git*',
'./lib*',
'*/@types*',
'./out*',
'./bin/mkvtoolnix*',
'./config/token.yml$',
'./config/updates.json$',
'./config/*_token.yml$',
'./config/*_sess.yml$',
'./config/*_profile.yml$',
'*/\\.eslint*',
'*/*\\.tsx?$',
'./fonts*',
'./gui/react*',
'./dev.js$',
'*/node_modules/*',
'./widevine/*',
'./videos/*',
'./logs/*',
].map(a => a.replace(/\*/g, '[^]*').replace(/\.\//g, escapeRegExp(__dirname) + '/').replace(/\//g, path.sep === '\\' ? '\\\\' : '/')).map(a => new RegExp(a, 'i'));
export { ignore };
(async () => {
const waitForProcess = async (proc: ChildProcess) => {
return new Promise((resolve, reject) => {
proc.stdout?.on('data', console.log);
proc.stderr?.on('data', console.error);
proc.on('close', resolve);
proc.on('error', reject);
});
};
process.stdout.write('Removing lib dir... ');
removeSync('lib');
process.stdout.write('✓\nRunning tsc... ');
const tsc = exec('npx tsc');
await waitForProcess(tsc);
if (!isGUI) {
fs.emptyDirSync(path.join('lib', 'gui'));
fs.rmdirSync(path.join('lib', 'gui'));
}
if (!isTest && isGUI) {
process.stdout.write('✓\nBuilding react... ');
const installReactDependencies = exec('pnpm install', {
cwd: path.join(__dirname, 'gui', 'react'),
});
await waitForProcess(installReactDependencies);
const react = exec('pnpm run build', {
cwd: path.join(__dirname, 'gui', 'react'),
env: {
...process.env,
CI: 'false'
}
});
await waitForProcess(react);
}
process.stdout.write('✓\nCopying files... ');
if (!isTest && isGUI) {
copyDir(path.join(__dirname, 'gui', 'react', 'build'), path.join(__dirname, 'lib', 'gui', 'server', 'build'));
}
const files = readDir(__dirname);
files.forEach(item => {
const itemPath = path.join(__dirname, 'lib', item.path.replace(__dirname, ''));
if (item.stats.isDirectory()) {
if (!fs.existsSync(itemPath))
fs.mkdirSync(itemPath);
} else {
copyFileSync(item.path, itemPath);
}
});
process.stdout.write('✓\nInstalling dependencies... ');
if (!isTest) {
const dependencies = exec(`pnpm install ${isGUI ? '' : '-P'}`, {
cwd: path.join(__dirname, 'lib')
});
await waitForProcess(dependencies);
}
process.stdout.write('✓\n');
})();
function readDir (dir: string): {
path: string,
stats: fs.Stats
}[] {
const items: {
path: string,
stats: fs.Stats
}[] = [];
const content = fs.readdirSync(dir);
itemLoop: for (const item of content) {
const itemPath = path.join(dir, item);
for (const ignoreItem of ignore) {
if (ignoreItem.test(itemPath))
continue itemLoop;
}
const stats = fs.statSync(itemPath);
items.push({
path: itemPath,
stats
});
if (stats.isDirectory()) {
items.push(...readDir(itemPath));
}
}
return items;
}
async function copyDir(src: string, dest: string) {
await fs.promises.mkdir(dest, { recursive: true });
const entries = await fs.promises.readdir(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
entry.isDirectory() ?
await copyDir(srcPath, destPath) :
await fs.promises.copyFile(srcPath, destPath);
}
}
function escapeRegExp(string: string): string {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}