From 313c8f9a3343989aef42faf8fd8e8dfd401a29d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Wed, 8 Jan 2020 23:01:15 +0800 Subject: [PATCH] chore: Add log generate (#20777) * chore: Add log generate * add author support * fix: only one author --- package.json | 1 + scripts/print-changelog.js | 164 +++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 scripts/print-changelog.js diff --git a/package.json b/package.json index 58b1bed435..398abc359e 100644 --- a/package.json +++ b/package.json @@ -196,6 +196,7 @@ "immutability-helper": "^3.0.0", "intersection-observer": "^0.7.0", "jest": "^24.8.0", + "jquery": "^3.4.1", "jsdom": "^15.1.1", "jsonml.js": "^0.1.0", "less-vars-to-js": "^1.3.0", diff --git a/scripts/print-changelog.js b/scripts/print-changelog.js new file mode 100644 index 0000000000..510bb000fa --- /dev/null +++ b/scripts/print-changelog.js @@ -0,0 +1,164 @@ +/* eslint-disable no-await-in-loop */ +const chalk = require('chalk'); +const jsdom = require('jsdom'); +const jQuery = require('jquery'); +const fetch = require('node-fetch'); +const simpleGit = require('simple-git/promise'); + +const { JSDOM } = jsdom; +const { window } = new JSDOM(); +const { document } = new JSDOM('').window; +global.document = document; + +const $ = jQuery(window); + +const QUERY_TITLE = '.gh-header-title .js-issue-title'; +const QUERY_DESCRIPTION_LINES = '.comment-body table tbody tr'; +const QUERY_AUTHOR = '.timeline-comment-header-text .author:first'; +const MAINTAINERS = ['zombiej', 'afc163', 'chenshuai2144']; + +const fromVersion = process.argv[process.argv.length - 2]; +const toVersion = process.argv[process.argv.length - 1]; +const cwd = process.cwd(); +const git = simpleGit(cwd); + +function getDescription(row = '') { + return row + .trim() + .replace('🇺🇸 English', '') + .replace('🇨🇳 Chinese', '') + .trim(); +} + +async function printLog() { + if (!/\d+\.\d+\.\d+/.test(fromVersion)) { + console.log( + chalk.red( + '🤪 Not pass validate tags. Please execute like `print-changelog.js 3.26.0 master` instead.', + ), + ); + } + + const logs = await git.log({ from: fromVersion, to: toVersion }); + + let prList = []; + + for (let i = 0; i < logs.all.length; i += 1) { + const { message, body, hash } = logs.all[i]; + + const text = `${message} ${body}`; + + const match = text.match(/#\d+/g); + const prs = (match || []).map(pr => pr.slice(1)); + const validatePRs = []; + + console.log( + `[${i + 1}/${logs.all.length}]`, + hash.slice(0, 6), + '-', + prs.length ? prs.map(pr => `#${pr}`).join(',') : '?', + ); + for (let j = 0; j < prs.length; j += 1) { + const pr = prs[j]; + + // Use jquery to get full html page since it don't need auth token + const res = await fetch(`https://github.com/ant-design/ant-design/pull/${pr}`); + if (res.url.includes('/issues/')) { + continue; + } + + const html = await res.text(); + + const $html = $(html); + + const prTitle = $html + .find(QUERY_TITLE) + .text() + .trim(); + const prAuthor = $html + .find(QUERY_AUTHOR) + .text() + .trim(); + const prLines = $html.find(QUERY_DESCRIPTION_LINES); + + const lines = []; + prLines.each(function getDesc() { + lines.push( + $(this) + .text() + .trim(), + ); + }); + + const english = getDescription(lines.find(line => line.includes('🇺🇸 English'))); + const chinese = getDescription(lines.find(line => line.includes('🇨🇳 Chinese'))); + + validatePRs.push({ + pr, + hash, + title: prTitle, + author: prAuthor, + english: english || prTitle, + chinese: chinese || prTitle, + }); + } + + if (validatePRs.length === 1) { + console.log(chalk.cyan(' - Match PR:', `#${validatePRs[0].pr}`)); + prList = prList.concat(validatePRs); + } else if (message.includes('docs:')) { + console.log(chalk.cyan(' - Skip document!')); + } else { + console.log(chalk.yellow(' - Miss match!')); + prList.push({ + hash, + title: message, + }); + } + } + + console.log('\n', chalk.green('Done. Here is the log:')); + + function printPR(lang, postLang) { + prList.forEach(entity => { + const { pr, author, hash, title } = entity; + if (pr) { + const str = postLang(entity[lang]); + let icon = ''; + if (str.toLowerCase().includes('fix') || str.includes('修复')) { + icon = '🐞'; + } + + let authorText = ''; + if (!MAINTAINERS.includes(author)) { + authorText = ` [@${author}](https://github.com/${author})`; + } + + console.log( + `- ${icon} ${str}[#${pr}](https://github.com/ant-design/ant-design/pull/${pr})${authorText}`, + ); + } else { + console.log( + `🆘 Miss Match: ${title} -> https://github.com/ant-design/ant-design/commit/${hash}`, + ); + } + }); + } + + // Chinese + printPR('chinese', chinese => (chinese[chinese.length - 1] === '。' ? chinese : `${chinese}。`)); + + console.log('-----'); + + // English + printPR('english', english => { + english = english.trim(); + if (english[english.length - 1] !== '.') { + english = `${english}.`; + } + return `${english} `; + }); +} + +printLog(); +/* eslint-enable */