From c0cc79f9955dd1cd0aa46f88a4b2c49745fcf2c2 Mon Sep 17 00:00:00 2001 From: Fienny Angelina Date: Tue, 25 Sep 2018 19:18:42 +0800 Subject: [PATCH] add contributor list to each document --- v2/lib/load/docs/metadata.js | 35 +++++++++++++++++++++++++++++++---- v2/lib/theme/Docs/index.js | 18 +++++++++++++++++- v2/lib/theme/Docs/styles.css | 6 +++++- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/v2/lib/load/docs/metadata.js b/v2/lib/load/docs/metadata.js index 4f147743c548..44d2fdb8d04e 100644 --- a/v2/lib/load/docs/metadata.js +++ b/v2/lib/load/docs/metadata.js @@ -1,6 +1,7 @@ const fs = require('fs-extra'); const path = require('path'); const {getSubFolder, idx, parse} = require('../utils'); +const execSync = require("child_process").execSync; function getLanguage(filepath, refDir, env) { const translationEnabled = idx(env, ['translation', 'enabled']); @@ -60,6 +61,32 @@ module.exports = async function processMetadata( metadata.title = metadata.id; } + /* set metadata author */ + const authorRegex = /(\d+) author (.+)$/g; + const results = execSync( + `git blame --line-porcelain ${filepath} \ + | grep -I "^author " | sort | uniq -c | sort -nr; \ + ` + ).toString().split('\n'); + let authorData; + const authors = []; + let totalLineCount = 0; + results.forEach(result => { + if ((authorData = authorRegex.exec(result)) !== null) { + const lineCount = parseInt(authorData[1]); + const name = authorData[2]; + authors.push({ + lineCount, + name, + }); + totalLineCount += lineCount; + } + authorRegex.lastIndex = 0; + }); + + metadata.authors = authors; + metadata.totalLineCount = totalLineCount; + /* language */ const language = getLanguage(filepath, refDir, env); metadata.language = language; @@ -77,7 +104,7 @@ module.exports = async function processMetadata( const versionPart = (version && version !== latestVersion && `${version}/`) || ''; - /* + /* Convert temporarily metadata.id to the form of dirname/id without version/lang prefix ex: file `versioned_docs/version-1.0.0/en/foo/bar.md` with id `version-1.0.0-bar` => `foo/bar` */ @@ -105,16 +132,16 @@ module.exports = async function processMetadata( } } - /* + /* The docs absolute file source - e.g: `/end/docs/hello.md` or `/end/website/versioned_docs/version-1.0.0/hello.md` + e.g: `/end/docs/hello.md` or `/end/website/versioned_docs/version-1.0.0/hello.md` */ metadata.source = path.join(refDir, source); /* Build the permalink */ const {baseUrl, docsUrl} = siteConfig; - /* + /* if user has own custom permalink defined in frontmatter e.g: :baseUrl:docsUrl/:langPart/:versionPart/endiliey/:id */ diff --git a/v2/lib/theme/Docs/index.js b/v2/lib/theme/Docs/index.js index 3aff930ce506..733eb26ff869 100644 --- a/v2/lib/theme/Docs/index.js +++ b/v2/lib/theme/Docs/index.js @@ -73,7 +73,23 @@ export default class Docs extends React.Component { )} -
{this.props.children}
+
+ {this.props.children} + {metadata && + metadata.authors && + metadata.totalLineCount && ( +
+ {metadata.authors + .map(({name, lineCount}) => { + const contribution = + ((lineCount / metadata.totalLineCount) * 100).toFixed(2) + + '%'; + return `${name} (${contribution})`; + }) + .join(', ')} +
+ )} +
); } diff --git a/v2/lib/theme/Docs/styles.css b/v2/lib/theme/Docs/styles.css index 52f2cff1653c..d5c2782850b6 100644 --- a/v2/lib/theme/Docs/styles.css +++ b/v2/lib/theme/Docs/styles.css @@ -7,4 +7,8 @@ margin-left: auto; margin-right: auto; justify-content: center; -} \ No newline at end of file +} +.authorList { + min-width: 100%; + text-align: center; +}