diff --git a/build.ts b/build.ts index 0cfa38f..33a5c8c 100644 --- a/build.ts +++ b/build.ts @@ -1,8 +1,7 @@ -import { spawn } from 'child_process'; import * as chokidar from 'chokidar'; -import { writeFile } from 'fs'; import * as path from 'path'; import * as prettier from 'prettier'; +import { spawnPromise, writeFilePromise } from './utils'; const ROOT_DIR = __dirname; const TYPESCRIPT_FILENAME = 'index.d.ts'; @@ -85,27 +84,3 @@ function typecheck() { ), ]); } - -function writeFilePromise(filename: string, content: string) { - return new Promise((resolve, reject) => { - writeFile(filename, content, 'utf-8', error => { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); -} - -function spawnPromise(command: string, ...args: string[]) { - return new Promise((resolve, reject) => { - const cp = spawn(command, args, { - cwd: ROOT_DIR, - }); - let out = ''; - cp.stdout.on('data', data => (out += data)); - cp.on('close', code => (code === 0 ? resolve() : reject(out))); - cp.on('error', reject); - }); -} diff --git a/package.json b/package.json index bc41cbd..bdfa5cd 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "typescript": "^2.8.3" }, "scripts": { + "update": "ts-node update.ts", "build": "ts-node build.ts", "watch": "ts-node build.ts --watch", "lint": "tslint --exclude node_modules/**/* --exclude **/*.d.ts --fix **/*.ts", diff --git a/src/comment.ts b/src/comment.ts index 13dda0a..e6be602 100644 --- a/src/comment.ts +++ b/src/comment.ts @@ -72,7 +72,9 @@ export function composeCommentBlock( return rows.length > 1 ? '/**\n * ' + rows.join('\n * ') + '\n */' - : rows.length === 1 ? '/** ' + rows[0] + ' */' : null; + : rows.length === 1 + ? '/** ' + rows[0] + ' */' + : null; } function supportVersion(supports: MDN.Support | MDN.Support[] | undefined): string[] { @@ -125,7 +127,9 @@ function supportVersion(supports: MDN.Support | MDN.Support[] | undefined): stri (supportsStandard ? (supportsPrefixed.version_added as string) : `**${supportsPrefixed.version_added}**`) + (supportsPrefixed.prefix ? ` _-x-_` - : supportsPrefixed.alternative_name ? ` _(${supportsPrefixed.alternative_name})_` : ''), + : supportsPrefixed.alternative_name + ? ` _(${supportsPrefixed.alternative_name})_` + : ''), ); } diff --git a/update.ts b/update.ts new file mode 100644 index 0000000..6530edd --- /dev/null +++ b/update.ts @@ -0,0 +1,76 @@ +// @ts-ignore +import * as packageJson from './package.json'; +import { getJson, spawnPromise, writeFilePromise } from './utils'; + +(async () => { + if ((await spawnPromise('git', 'status', '--porcelain')) !== '') { + console.error('Your working directory needs to be clean!'); + process.exit(1); + } + + console.info('Checks for updates...'); + + const MDN_DATA = 'mdn-data'; + const MDN_COMPAT = 'mdn-browser-compat-data'; + + const [mdnDataRepo, currentMdnDataCommit] = packageJson.devDependencies[MDN_DATA].split('#'); + const [mdnCompatRepo, currentMdnCompatCommit] = packageJson.devDependencies[MDN_COMPAT].split('#'); + + const [mdnDataMaster, mdnCompatMaster] = [ + await getJson({ + hostname: 'api.github.com', + path: '/repos/mdn/data/branches/master', + headers: { 'User-Agent': 'NodeJS' }, + }), + await getJson({ + hostname: 'api.github.com', + path: '/repos/mdn/browser-compat-data/branches/master', + headers: { 'User-Agent': 'NodeJS' }, + }), + ]; + + const latestMdnDataCommit = mdnDataMaster.commit.sha; + const latestMdnCompatCommit = mdnCompatMaster.commit.sha; + + if (latestMdnDataCommit !== currentMdnDataCommit || latestMdnCompatCommit !== currentMdnCompatCommit) { + console.info('Update found, upgrading and building...'); + + packageJson.devDependencies[MDN_DATA] = `${mdnDataRepo}#${latestMdnDataCommit}`; + packageJson.devDependencies[MDN_COMPAT] = `${mdnCompatRepo}#${latestMdnCompatCommit}`; + + await writeFilePromise('./package.json', JSON.stringify(packageJson, null, 2) + '\n'); + + try { + await spawnPromise('yarn.cmd', '--silent', '--no-progress'); + } catch (e) { + console.error(e); + process.exit(1); + } + + const [indexDtsDiff, indexFlowDiff] = [ + await spawnPromise('git', '--no-pager', 'diff', 'index.d.ts'), + await spawnPromise('git', '--no-pager', 'diff', 'index.js.flow'), + ]; + + if (indexDtsDiff !== '' || indexFlowDiff !== '') { + await spawnPromise('git', 'commit', '-am', 'Bump MDN'); + + const [major, minor, patch] = packageJson.version.split('.'); + const version = `${major}.${minor}.${Number(patch) + 1}`; + + packageJson.version = version; + await writeFilePromise('./package.json', JSON.stringify(packageJson, null, 2) + '\n'); + await spawnPromise('git', 'commit', '-am', `v${version}`); + await spawnPromise('git', 'tag', `v${version}`); + + console.info('Changes detected! The changes are committed and tagged. You just need to:'); + console.info('- `git push origin HEAD --tags`'); + console.info('- `npm publish`'); + } else { + console.info('No changes detected, resetting...'); + await spawnPromise('git', 'reset', '--hard'); + } + } else { + console.info('Nothing to update!'); + } +})(); diff --git a/utils.ts b/utils.ts new file mode 100644 index 0000000..6ca98ae --- /dev/null +++ b/utils.ts @@ -0,0 +1,48 @@ +import { spawn } from 'child_process'; +import { writeFile } from 'fs'; +import { get, RequestOptions } from 'https'; + +const ROOT_DIR = __dirname; + +export function writeFilePromise(filename: string, content: string) { + return new Promise((resolve, reject) => { + writeFile(filename, content, 'utf-8', error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); +} + +export function spawnPromise(command: string, ...args: string[]) { + return new Promise((resolve, reject) => { + const cp = spawn(command, args, { + cwd: ROOT_DIR, + }); + let data = ''; + cp.stdout.on('data', chunk => (data += chunk)); + cp.on('close', code => (code === 0 ? resolve(data) : reject(data))); + cp.on('error', reject); + }); +} + +export function getJson(url: RequestOptions): Promise { + return new Promise((resolve, reject) => { + const req = get(url, res => { + let data = ''; + res.on('data', chunk => (data += chunk)); + res.on('end', () => { + try { + const json = JSON.parse(data); + resolve(json); + } catch (e) { + reject(e); + } + }); + }); + req.on('error', reject); + req.end(); + }); +}