You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.4 KiB

const sleep = x => new Promise(res => setTimeout(() => res(), x * 1000))
;(async () => {
const { spawn } = require('node:child_process')
const ora = (await import('ora')).default
class Builder {
constructor() {
this.spinner = ora('Starting build').start()
this.contextMaxLines = 3
this.contextLines = Array(this.contextMaxLines).fill('')
this.allLines = []
this.steps = []
this.renderLines()
}
pushLine(line) {
if ( this.contextLines.length >= this.contextMaxLines ) this.contextLines = this.contextLines.slice(1)
this.contextLines.push(String(line).trimEnd())
this.allLines.push(String(line).trimEnd())
this.renderLines()
}
renderLines() {
this.spinner.suffixText = `\n--\n${this.contextLines.join('\n')}\n--`
}
addStep(name, callback) {
this.steps.push({ name, callback })
}
async build() {
for ( let i = 0; i < this.steps.length; i += 1 ) {
const step = this.steps[i]
this.spinner.text = `(${i+1}/${this.steps.length}) ${step.name}`
await step.callback(this)
}
this.spinner.suffixText = ''
this.spinner.succeed('Built successfully')
}
async executeOrExit(prog, ...args) {
try {
return await this.execute(prog, ...args)
} catch (e) {
this.spinner.suffixText = ''
this.spinner.fail(`${this.spinner.text} - ${e.message}`)
console.log(this.allLines.join('\n'))
process.exit(1)
}
}
execute(prog, ...args) {
this.pushLine(`> ${prog} ${args.join(' ')}`)
const cmd = spawn(prog, args)
let output = ''
cmd.stdout.on('data', data => {
output += data
String(data).split('\n').map(x => this.pushLine(x))
})
cmd.stderr.on('data', data => {
output += data
String(data).split('\n').map(x => this.pushLine(x))
})
return new Promise((res, rej) => {
cmd.on('close', code => {
if ( code ) {
return rej(new Error('Process exited with code: ' + code))
} else {
res(output.trim())
}
})
})
}
}
const b= new Builder
b.addStep(
'Remove old build files',
b => b.executeOrExit('./node_modules/.bin/rimraf', 'lib'),
)
b.addStep(
'Build back-end TypeScript code',
b => b.executeOrExit('./node_modules/.bin/tsc', '-p', 'tsconfig.node.json'),
)
b.addStep(
'Copy resources to output bundle',
b => b.executeOrExit('./node_modules/.bin/fse', 'copy', '--all', '--dereference', '--preserveTimestamps', '--keepExisting=false', '--quiet', '--errorOnExist=false', 'src/app/resources', 'lib/app/resources'),
)
b.addStep(
'Build front-end TypeScript code',
b => b.executeOrExit('./node_modules/.bin/tsc', '-p', 'tsconfig.client.json'),
)
b.addStep(
'Create front-end output bundle',
b => b.executeOrExit('./node_modules/.bin/webpack', '--config', 'webpack.config.js'),
)
await b.build()
})();