feat(runner): add parallel building
This commit is contained in:
@@ -1,18 +1,18 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { appendSync, readSync } from './file.js'
|
import { appendSync, readSync } from './file.js'
|
||||||
|
|
||||||
export function appendReadme() {
|
export function appendReadme(operatorName) {
|
||||||
const operatorConfig = __config.operators[__operator_name]
|
const operatorConfig = __config.operators[operatorName]
|
||||||
const projectJson = JSON.parse(readSync(path.join(__dirname, __config.folder.operator, __operator_name, 'project.json')))
|
const projectJson = JSON.parse(readSync(path.join(__dirname, __config.folder.operator, operatorName, 'project.json')))
|
||||||
appendSync(
|
appendSync(
|
||||||
`\n| ${operatorConfig.title.split(' - ')[0].split('Arknights: ')[1]} | [Link](https://arknights.halyul.dev/${operatorConfig.link}/) | [Link](https://steamcommunity.com/sharedfiles/filedetails/?id=${projectJson.workshopid}) |`,
|
`\n| ${operatorConfig.title.split(' - ')[0].split('Arknights: ')[1]} | [Link](https://arknights.halyul.dev/${operatorConfig.link}/) | [Link](https://steamcommunity.com/sharedfiles/filedetails/?id=${projectJson.workshopid}) |`,
|
||||||
path.join(__dirname, 'README.md')
|
path.join(__dirname, 'README.md')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function appendMainConfig() {
|
export function appendMainConfig(operatorName) {
|
||||||
appendSync(
|
appendSync(
|
||||||
`\n ${__operator_name}: !include config/${__operator_name}.yaml`,
|
`\n ${operatorName}: !include config/${operatorName}.yaml`,
|
||||||
path.join(__dirname, 'config.yaml')
|
path.join(__dirname, 'config.yaml')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -5,19 +5,21 @@ import AlphaComposite from './alpha_composite.js'
|
|||||||
export default class AssetsProcessor {
|
export default class AssetsProcessor {
|
||||||
#operatorSourceFolder
|
#operatorSourceFolder
|
||||||
#alphaCompositer
|
#alphaCompositer
|
||||||
|
#operatorName
|
||||||
|
|
||||||
constructor() {
|
constructor(operatorName) {
|
||||||
this.#operatorSourceFolder = path.join(__dirname, __config.folder.operator)
|
this.#operatorSourceFolder = path.join(__dirname, __config.folder.operator)
|
||||||
this.#alphaCompositer = new AlphaComposite()
|
this.#alphaCompositer = new AlphaComposite()
|
||||||
|
this.#operatorName = operatorName
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(extractedDir) {
|
async process(extractedDir) {
|
||||||
const BASE64_BINARY_PREFIX = 'data:application/octet-stream;base64,'
|
const BASE64_BINARY_PREFIX = 'data:application/octet-stream;base64,'
|
||||||
const BASE64_PNG_PREFIX = 'data:image/png;base64,'
|
const BASE64_PNG_PREFIX = 'data:image/png;base64,'
|
||||||
const assetsJson = {}
|
const assetsJson = {}
|
||||||
const skelFilename = `${__config.operators[__operator_name].filename}.skel`
|
const skelFilename = `${__config.operators[this.#operatorName].filename}.skel`
|
||||||
const skel = await read(path.join(extractedDir, skelFilename), null)
|
const skel = await read(path.join(extractedDir, skelFilename), null)
|
||||||
const atlasFilename = `${__config.operators[__operator_name].filename}.atlas`
|
const atlasFilename = `${__config.operators[this.#operatorName].filename}.atlas`
|
||||||
const atlas = await read(path.join(extractedDir, atlasFilename))
|
const atlas = await read(path.join(extractedDir, atlasFilename))
|
||||||
const dimensions = atlas.match(new RegExp(/^size:(.*),(.*)/gm))[0].replace('size: ', '').split(',')
|
const dimensions = atlas.match(new RegExp(/^size:(.*),(.*)/gm))[0].replace('size: ', '').split(',')
|
||||||
const matches = atlas.match(new RegExp(/(.*).png/g))
|
const matches = atlas.match(new RegExp(/(.*).png/g))
|
||||||
@@ -28,9 +30,9 @@ export default class AssetsProcessor {
|
|||||||
assetsJson[`./assets/${skelFilename.replace('#', '%23')}`] = BASE64_BINARY_PREFIX + skel.toString('base64')
|
assetsJson[`./assets/${skelFilename.replace('#', '%23')}`] = BASE64_BINARY_PREFIX + skel.toString('base64')
|
||||||
assetsJson[`./assets/${atlasFilename.replace('#', '%23')}`] = BASE64_BINARY_PREFIX + Buffer.from(atlas).toString('base64')
|
assetsJson[`./assets/${atlasFilename.replace('#', '%23')}`] = BASE64_BINARY_PREFIX + Buffer.from(atlas).toString('base64')
|
||||||
|
|
||||||
const fallbackFilename = `${__config.operators[__operator_name].fallback_name}.png`
|
const fallbackFilename = `${__config.operators[this.#operatorName].fallback_name}.png`
|
||||||
const fallbackBuffer = await this.#alphaCompositer.process(fallbackFilename, extractedDir)
|
const fallbackBuffer = await this.#alphaCompositer.process(fallbackFilename, extractedDir)
|
||||||
await write(fallbackBuffer, path.join(this.#operatorSourceFolder, __operator_name, fallbackFilename))
|
await write(fallbackBuffer, path.join(this.#operatorSourceFolder, this.#operatorName, fallbackFilename))
|
||||||
return {
|
return {
|
||||||
dimensions,
|
dimensions,
|
||||||
assetsJson
|
assetsJson
|
||||||
|
|||||||
@@ -2,8 +2,5 @@ import path from 'path'
|
|||||||
import { read } from './yaml.js'
|
import { read } from './yaml.js'
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
return {
|
return read(path.join(__dirname, 'config.yaml'))
|
||||||
basedir: __dirname,
|
|
||||||
...read(path.join(__dirname, 'config.yaml'))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,8 @@ export default class EnvGenerator {
|
|||||||
#assets
|
#assets
|
||||||
#operatorConfig
|
#operatorConfig
|
||||||
|
|
||||||
constructor(assets) {
|
constructor(operatorName, assets) {
|
||||||
this.#operatorConfig = __config.operators[__operator_name]
|
this.#operatorConfig = __config.operators[operatorName]
|
||||||
this.#assets = assets
|
this.#assets = assets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { read as readYAML } from './yaml.js'
|
|||||||
import { mkdir, writeSync } from './file.js'
|
import { mkdir, writeSync } from './file.js'
|
||||||
import { appendMainConfig } from './append.js'
|
import { appendMainConfig } from './append.js'
|
||||||
|
|
||||||
export default function init(extractedDir) {
|
export default function init(operatorName, extractedDir) {
|
||||||
mkdir(extractedDir)
|
mkdir(extractedDir)
|
||||||
const date = new Date()
|
const date = new Date()
|
||||||
const template = readYAML(path.join(__dirname, 'config', '_template.yaml'))
|
const template = readYAML(path.join(__dirname, 'config', '_template.yaml'))
|
||||||
template.link = __operator_name
|
template.link = operatorName
|
||||||
template.date = `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0') }`
|
template.date = `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0') }`
|
||||||
writeSync(stringify(template), path.join(__dirname, 'config', `${__operator_name}.yaml`))
|
writeSync(stringify(template), path.join(__dirname, 'config', `${operatorName}.yaml`))
|
||||||
appendMainConfig(__operator_name, __dirname)
|
appendMainConfig(operatorName)
|
||||||
}
|
}
|
||||||
@@ -5,15 +5,14 @@ import { read as readYAML } from './yaml.js'
|
|||||||
|
|
||||||
export default class ProjectJson {
|
export default class ProjectJson {
|
||||||
#json
|
#json
|
||||||
#config
|
|
||||||
#operatorName
|
#operatorName
|
||||||
#operatorSourceFolder
|
#operatorSourceFolder
|
||||||
#operatorShareFolder
|
#operatorShareFolder
|
||||||
#assets
|
#assets
|
||||||
#rootDir
|
|
||||||
#template
|
#template
|
||||||
|
|
||||||
constructor(operatorShareFolder, assets) {
|
constructor(operatorName, operatorShareFolder, assets) {
|
||||||
|
this.#operatorName = operatorName
|
||||||
this.#operatorSourceFolder = path.join(__dirname, __config.folder.operator)
|
this.#operatorSourceFolder = path.join(__dirname, __config.folder.operator)
|
||||||
this.#operatorShareFolder = operatorShareFolder
|
this.#operatorShareFolder = operatorShareFolder
|
||||||
this.#assets = assets
|
this.#assets = assets
|
||||||
@@ -29,7 +28,7 @@ export default class ProjectJson {
|
|||||||
|
|
||||||
#getPath() {
|
#getPath() {
|
||||||
// if exists, do not use the template
|
// if exists, do not use the template
|
||||||
const defaultPath = path.join(this.#operatorSourceFolder, __operator_name, 'project.json')
|
const defaultPath = path.join(this.#operatorSourceFolder, this.#operatorName, 'project.json')
|
||||||
if (exists(defaultPath)) {
|
if (exists(defaultPath)) {
|
||||||
return defaultPath
|
return defaultPath
|
||||||
} else {
|
} else {
|
||||||
@@ -41,7 +40,7 @@ export default class ProjectJson {
|
|||||||
this.#json = {
|
this.#json = {
|
||||||
...this.#json,
|
...this.#json,
|
||||||
description: this.#template.description,
|
description: this.#template.description,
|
||||||
title: __config.operators[__operator_name].title,
|
title: __config.operators[this.#operatorName].title,
|
||||||
general: {
|
general: {
|
||||||
...this.#json.general,
|
...this.#json.general,
|
||||||
localization: this.#template.localization,
|
localization: this.#template.localization,
|
||||||
@@ -54,7 +53,7 @@ export default class ProjectJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#processYAML(template) {
|
#processYAML(template) {
|
||||||
const matcher = new Matcher(template.description, '${', '}', __config.operators[__operator_name])
|
const matcher = new Matcher(template.description, '${', '}', __config.operators[this.#operatorName])
|
||||||
if (matcher.match() !== null) {
|
if (matcher.match() !== null) {
|
||||||
template.description = matcher.process()
|
template.description = matcher.process()
|
||||||
}
|
}
|
||||||
@@ -74,25 +73,25 @@ export default class ProjectJson {
|
|||||||
{
|
{
|
||||||
key: "paddingleft",
|
key: "paddingleft",
|
||||||
value: {
|
value: {
|
||||||
value: __config.operators[__operator_name].viewport_left
|
value: __config.operators[this.#operatorName].viewport_left
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "paddingright",
|
key: "paddingright",
|
||||||
value: {
|
value: {
|
||||||
value: __config.operators[__operator_name].viewport_right
|
value: __config.operators[this.#operatorName].viewport_right
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "paddingtop",
|
key: "paddingtop",
|
||||||
value: {
|
value: {
|
||||||
value: __config.operators[__operator_name].viewport_top
|
value: __config.operators[this.#operatorName].viewport_top
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "paddingbottom",
|
key: "paddingbottom",
|
||||||
value: {
|
value: {
|
||||||
value: __config.operators[__operator_name].viewport_bottom
|
value: __config.operators[this.#operatorName].viewport_bottom
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
39
libs/vite.js
39
libs/vite.js
@@ -1,39 +0,0 @@
|
|||||||
import path from 'path'
|
|
||||||
import { createServer, build } from 'vite'
|
|
||||||
|
|
||||||
export default class Vite {
|
|
||||||
|
|
||||||
dev() {
|
|
||||||
; (async () => {
|
|
||||||
const server = await createServer(this.#viteConfig)
|
|
||||||
await server.listen()
|
|
||||||
|
|
||||||
server.printUrls()
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
|
|
||||||
async build() {
|
|
||||||
await build(this.#viteConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
get #viteConfig() {
|
|
||||||
return {
|
|
||||||
base: "",
|
|
||||||
publicDir: path.resolve(__dirname, __config.folder.release, __operator_name),
|
|
||||||
root: path.resolve(__dirname),
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, './src'),
|
|
||||||
'!': path.resolve(__dirname, __config.folder.operator, __operator_name),
|
|
||||||
'#': path.resolve(__config.basedir, __config.folder.operator, __operator_name, `${__config.operators[__operator_name].filename}.json`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
outDir: path.resolve(__dirname, __config.folder.release, __operator_name),
|
|
||||||
emptyOutDir: false,
|
|
||||||
chunkSizeWarningLimit: 10000,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
35
runner.js
35
runner.js
@@ -1,14 +1,14 @@
|
|||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
|
import { fork } from 'child_process';
|
||||||
import getConfig from './libs/config.js'
|
import getConfig from './libs/config.js'
|
||||||
import ProjectJson from './libs/project_json.js'
|
import ProjectJson from './libs/project_json.js'
|
||||||
import EnvGenerator from './libs/env_generator.js'
|
import EnvGenerator from './libs/env_generator.js'
|
||||||
import { write, rmdir, copy, writeSync, rm } from './libs/file.js'
|
import { write, rmdir, copy, writeSync } from './libs/file.js'
|
||||||
import AssetsProcessor from './libs/assets_processor.js'
|
import AssetsProcessor from './libs/assets_processor.js'
|
||||||
import init from './libs/initializer.js'
|
import init from './libs/initializer.js'
|
||||||
import directory from './libs/directory.js'
|
import directory from './libs/directory.js'
|
||||||
import Vite from './libs/vite.js'
|
|
||||||
import { appendReadme } from './libs/append.js'
|
import { appendReadme } from './libs/append.js'
|
||||||
import Background from './libs/background.js'
|
import Background from './libs/background.js'
|
||||||
|
|
||||||
@@ -44,7 +44,6 @@ async function main() {
|
|||||||
assert(OPERATOR_NAMES.length !== 0, 'Please set the operator name.')
|
assert(OPERATOR_NAMES.length !== 0, 'Please set the operator name.')
|
||||||
|
|
||||||
for (const OPERATOR_NAME of OPERATOR_NAMES) {
|
for (const OPERATOR_NAME of OPERATOR_NAMES) {
|
||||||
global.__operator_name = OPERATOR_NAME
|
|
||||||
const OPERATOR_SOURCE_FOLDER = path.join(__dirname, __config.folder.operator)
|
const OPERATOR_SOURCE_FOLDER = path.join(__dirname, __config.folder.operator)
|
||||||
const OPERATOR_RELEASE_FOLDER = path.join(__dirname, __config.folder.release, OPERATOR_NAME)
|
const OPERATOR_RELEASE_FOLDER = path.join(__dirname, __config.folder.release, OPERATOR_NAME)
|
||||||
const SHOWCASE_PUBLIC_ASSSETS_FOLDER = path.join(OPERATOR_RELEASE_FOLDER, "assets")
|
const SHOWCASE_PUBLIC_ASSSETS_FOLDER = path.join(OPERATOR_RELEASE_FOLDER, "assets")
|
||||||
@@ -58,10 +57,10 @@ async function main() {
|
|||||||
*/
|
*/
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 'init':
|
case 'init':
|
||||||
init(EXTRACTED_FOLDER)
|
init(OPERATOR_NAME, EXTRACTED_FOLDER)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
case 'readme':
|
case 'readme':
|
||||||
appendReadme()
|
appendReadme(OPERATOR_NAME)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@@ -69,14 +68,14 @@ async function main() {
|
|||||||
|
|
||||||
rmdir(OPERATOR_RELEASE_FOLDER)
|
rmdir(OPERATOR_RELEASE_FOLDER)
|
||||||
|
|
||||||
const projectJson = new ProjectJson(OPERATOR_SHARE_FOLDER, {
|
const projectJson = new ProjectJson(OPERATOR_NAME, OPERATOR_SHARE_FOLDER, {
|
||||||
backgrounds
|
backgrounds
|
||||||
})
|
})
|
||||||
projectJson.load().then((content) => {
|
projectJson.load().then((content) => {
|
||||||
write(JSON.stringify(content, null, 2), path.join(OPERATOR_RELEASE_FOLDER, 'project.json'))
|
write(JSON.stringify(content, null, 2), path.join(OPERATOR_RELEASE_FOLDER, 'project.json'))
|
||||||
})
|
})
|
||||||
|
|
||||||
const assetsProcessor = new AssetsProcessor()
|
const assetsProcessor = new AssetsProcessor(OPERATOR_NAME)
|
||||||
assetsProcessor.process(EXTRACTED_FOLDER).then((content) => {
|
assetsProcessor.process(EXTRACTED_FOLDER).then((content) => {
|
||||||
write(JSON.stringify(content.assetsJson, null), path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, `${__config.operators[OPERATOR_NAME].filename}.json`))
|
write(JSON.stringify(content.assetsJson, null), path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, `${__config.operators[OPERATOR_NAME].filename}.json`))
|
||||||
})
|
})
|
||||||
@@ -108,27 +107,11 @@ async function main() {
|
|||||||
copy(path.join(file.source, file.filename), path.join(file.target, file.filename))
|
copy(path.join(file.source, file.filename), path.join(file.target, file.filename))
|
||||||
})
|
})
|
||||||
|
|
||||||
const envPath = path.join(__dirname, '.env')
|
const envPath = path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, '.env')
|
||||||
writeSync((new EnvGenerator({
|
writeSync((new EnvGenerator(OPERATOR_NAME, {
|
||||||
backgrounds
|
backgrounds
|
||||||
})).generate(), envPath)
|
})).generate(), envPath)
|
||||||
/**
|
fork(path.join(__dirname, 'vite.js'), [op, OPERATOR_NAME])
|
||||||
* dev: run dev server
|
|
||||||
* build: build assets
|
|
||||||
*/
|
|
||||||
const vite = new Vite(__config, OPERATOR_NAME, __dirname)
|
|
||||||
switch (op) {
|
|
||||||
case 'dev':
|
|
||||||
vite.dev()
|
|
||||||
break
|
|
||||||
case 'build':
|
|
||||||
case 'build-all':
|
|
||||||
await vite.build()
|
|
||||||
rm(envPath)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
80
vite.js
Normal file
80
vite.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import { fileURLToPath } from 'url'
|
||||||
|
import { createServer, build, loadEnv } from 'vite'
|
||||||
|
import getConfig from './libs/config.js'
|
||||||
|
import { rm } from './libs/file.js'
|
||||||
|
|
||||||
|
global.__dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
export default class Vite {
|
||||||
|
#operatorName = process.argv[3]
|
||||||
|
#config = getConfig()
|
||||||
|
|
||||||
|
dev() {
|
||||||
|
; (async () => {
|
||||||
|
this.#loadEnvFromEnvFile('development')
|
||||||
|
const server = await createServer(this.#viteConfig)
|
||||||
|
await server.listen()
|
||||||
|
|
||||||
|
server.printUrls()
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
; (async () => {
|
||||||
|
this.#loadEnvFromEnvFile('production')
|
||||||
|
console.log("Building", this.#operatorName, "...")
|
||||||
|
await build({
|
||||||
|
...this.#viteConfig,
|
||||||
|
logLevel: 'silent',
|
||||||
|
})
|
||||||
|
})()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#loadEnvFromEnvFile(mode) {
|
||||||
|
const envPath = path.join(__dirname, this.#config.folder.operator, this.#operatorName)
|
||||||
|
process.env = { ...loadEnv(mode, envPath) }
|
||||||
|
rm(path.join(envPath, '.env'))
|
||||||
|
}
|
||||||
|
|
||||||
|
get #viteConfig() {
|
||||||
|
return {
|
||||||
|
base: "",
|
||||||
|
publicDir: path.resolve(__dirname, this.#config.folder.release, this.#operatorName),
|
||||||
|
root: path.resolve(__dirname),
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, './src'),
|
||||||
|
'!': path.resolve(__dirname, this.#config.folder.operator, this.#operatorName),
|
||||||
|
'#': path.resolve(__dirname, this.#config.folder.operator, this.#operatorName, `${this.#config.operators[this.#operatorName].filename}.json`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: path.resolve(__dirname, this.#config.folder.release, this.#operatorName),
|
||||||
|
emptyOutDir: false,
|
||||||
|
chunkSizeWarningLimit: 10000,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const MODE = process.argv[2]
|
||||||
|
const vite = new Vite()
|
||||||
|
|
||||||
|
switch (MODE) {
|
||||||
|
case 'dev':
|
||||||
|
vite.dev()
|
||||||
|
break
|
||||||
|
case 'build':
|
||||||
|
case 'build-all':
|
||||||
|
vite.build()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user