mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-03-21 17:50:29 -05:00
At this point, we might as well use babel-core directly. New system supports source maps for `battledata` and `graphics`! Woo! It also logs the compile step.
190 lines
6.4 KiB
JavaScript
Executable File
190 lines
6.4 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* This script parses index.html and sets the version query string of each
|
|
* resource to be the MD5 hash of that resource.
|
|
* It also updates news and the learnsets-g6.js file.
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const crypto = require('crypto');
|
|
const child_process = require('child_process');
|
|
const compiler = require('./compiler');
|
|
|
|
const thisDir = __dirname;
|
|
const rootDir = path.resolve(thisDir, '..');
|
|
process.chdir(rootDir);
|
|
|
|
const AUTOCONFIG_START = '/*** Begin automatically generated configuration ***/';
|
|
const AUTOCONFIG_END = '/*** End automatically generated configuration ***/';
|
|
|
|
function escapeRegex(string) {
|
|
return string.replace(/[\/\*\.]/g, '\\$&');
|
|
}
|
|
|
|
/*********************************************************
|
|
* Update version number
|
|
*********************************************************/
|
|
|
|
process.stdout.write("Updating version... ");
|
|
|
|
let version = require('../package.json').version;
|
|
try {
|
|
let commit = child_process.execSync('git rev-parse HEAD', {
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
});
|
|
const head = ('' + commit).trim();
|
|
commit = child_process.execSync('git merge-base origin/master HEAD', {
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
});
|
|
const origin = ('' + commit).trim();
|
|
version += ` (${head.slice(0, 8)}${head !== origin ? `/${origin.slice(0, 8)}` : ''})`;
|
|
} catch (e) {}
|
|
|
|
const routes = JSON.parse(fs.readFileSync('config/routes.json'));
|
|
const autoconfigRegex = new RegExp(`${escapeRegex(AUTOCONFIG_START)}[^]+${escapeRegex(AUTOCONFIG_END)}`);
|
|
const autoconfig = `${AUTOCONFIG_START}
|
|
Config.version = ${JSON.stringify(version)};
|
|
|
|
Config.routes = {
|
|
root: '${routes.root}',
|
|
client: '${routes.client}',
|
|
dex: '${routes.dex}',
|
|
replays: '${routes.replays}',
|
|
users: '${routes.users}',
|
|
};
|
|
${AUTOCONFIG_END}`;
|
|
|
|
// remove old automatically generated configuration and add the new one
|
|
let configBuf = fs.readFileSync('config/config.js', {encoding: 'utf8'});
|
|
if (autoconfigRegex.test(configBuf)) {
|
|
configBuf = configBuf.replace(autoconfigRegex, autoconfig);
|
|
} else {
|
|
configBuf += autoconfig;
|
|
}
|
|
fs.writeFileSync('config/config.js', configBuf);
|
|
console.log("DONE");
|
|
|
|
/*********************************************************
|
|
* Compile TS files
|
|
*********************************************************/
|
|
|
|
process.stdout.write("Compiling TS files... ");
|
|
|
|
let compileStartTime = process.hrtime();
|
|
let compiledFiles = 0;
|
|
|
|
let compileOpts = {
|
|
incremental: true,
|
|
ignore: ['src/battle-animations.js', 'src/battle-animations-moves.js'],
|
|
};
|
|
if (process.argv[2] === 'full') {
|
|
delete compileOpts.ignore;
|
|
} else {
|
|
try {
|
|
fs.statSync('data/graphics.js');
|
|
// graphics.js exists, recompile it
|
|
delete compileOpts.ignore;
|
|
} catch (e) {}
|
|
}
|
|
|
|
compiledFiles += compiler.compileToDir(`src`, `js`, compileOpts);
|
|
|
|
compiledFiles += compiler.compileToDir(`src`, `js`, compileOpts);
|
|
|
|
compiledFiles += compiler.compileToFile(
|
|
['src/battle-dex.ts', 'src/battle-dex-data.ts', 'src/battle-log.ts', 'src/battle-log-misc.js', 'data/text.js', 'src/battle-text-parser.ts'],
|
|
'js/battledata.js',
|
|
compileOpts
|
|
);
|
|
|
|
if (!compileOpts.ignore) {
|
|
compiledFiles += compiler.compileToFile(
|
|
['src/battle-animations.ts', 'src/battle-animations-moves.ts'],
|
|
'data/graphics.js',
|
|
compileOpts
|
|
);
|
|
}
|
|
|
|
const diff = process.hrtime(compileStartTime);
|
|
console.log(
|
|
`(${compiledFiles} ${compiledFiles !== 1 ? "files" : "file"} in ${diff[0] + Math.round(diff[1] / 1e6) / 1e3}s) DONE`
|
|
);
|
|
|
|
/*********************************************************
|
|
* Update cachebuster and News
|
|
*********************************************************/
|
|
|
|
process.stdout.write("Updating cachebuster and URLs... ");
|
|
|
|
const URL_REGEX = /(src|href)="\/(.*?)(\?[a-z0-9]*?)?"/g;
|
|
|
|
function updateURL(a, b, c, d) {
|
|
c = c.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/');
|
|
c = c.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/');
|
|
c = c.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/');
|
|
c = c.replace('/pokemonshowdown.com/', '/' + routes.root + '/');
|
|
|
|
if (d) {
|
|
let hash = Math.random(); // just in case creating the hash fails
|
|
try {
|
|
const filename = c.replace('/' + routes.client + '/', '');
|
|
const fstr = fs.readFileSync(filename, {encoding: 'utf8'});
|
|
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
|
|
} catch (e) {}
|
|
|
|
return b + '="/' + c + '?' + hash + '"';
|
|
} else {
|
|
return b + '="/' + c + '"';
|
|
}
|
|
}
|
|
|
|
function writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents) {
|
|
fs.writeFileSync('index.html', indexContents);
|
|
fs.writeFileSync('preactalpha.html', preactIndexContents);
|
|
fs.writeFileSync('crossprotocol.html', crossprotocolContents);
|
|
fs.writeFileSync('js/replay-embed.js', replayEmbedContents);
|
|
console.log("DONE");
|
|
}
|
|
|
|
function updateFiles() {
|
|
// add hashes to js and css files and rewrite URLs
|
|
let indexContents = fs.readFileSync('index.template.html', {encoding: 'utf8'});
|
|
indexContents = indexContents.replace(URL_REGEX, updateURL);
|
|
let preactIndexContents = fs.readFileSync('preactalpha.template.html', {encoding: 'utf8'});
|
|
preactIndexContents = preactIndexContents.replace(URL_REGEX, updateURL);
|
|
let crossprotocolContents = fs.readFileSync('crossprotocol.template.html', {encoding: 'utf8'});
|
|
crossprotocolContents = crossprotocolContents.replace(URL_REGEX, updateURL);
|
|
let replayEmbedContents = fs.readFileSync('js/replay-embed.template.js', {encoding: 'utf8'});
|
|
replayEmbedContents = replayEmbedContents.replace(/play\.pokemonshowdown\.com/g, routes.client);
|
|
|
|
// add news, only if it's actually likely to exist
|
|
if (__dirname.endsWith('play.pokemonshowdown.com/build-tools')) {
|
|
process.stdout.write("and news... ");
|
|
child_process.exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) {
|
|
let newsData = [0, '[failed to retrieve news]'];
|
|
if (!error && !stderr) {
|
|
try {
|
|
newsData = JSON.parse(stdout);
|
|
} catch (e) {
|
|
console.log("git hook failed to retrieve news (parsing JSON failed):\n" + e.stack);
|
|
}
|
|
} else {
|
|
console.log("git hook failed to retrieve news (exec command failed):\n" + (error + stderr + stdout));
|
|
}
|
|
|
|
indexContents = indexContents.replace(/<!-- newsid -->/g, newsData[0]);
|
|
indexContents = indexContents.replace(/<!-- news -->/g, newsData[1]);
|
|
|
|
writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents);
|
|
});
|
|
} else {
|
|
writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents);
|
|
}
|
|
}
|
|
|
|
updateFiles();
|