Skip to content
Permalink
97216ef432
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
173 lines (154 sloc) 4.71 KB
const fs = require('fs');
const toml = require('toml');
const groupBy = require('lodash/groupBy');
const sortBy = require('lodash/sortBy');
const compact = require('lodash/compact');
const find = require('lodash/find');
const { camelizeKeys } = require('humps');
const Xray = require('x-ray');
const Handlebars = require('handlebars');
const moment = require('moment');
const glob = require('glob');
const readmeTemplate = Handlebars.compile(
fs.readFileSync('./README.md.hbs').toString()
);
const x = Xray({
filters: {
removeCommas(value) {
return value && value.replace(',', '');
},
trim(value) {
return value && value.trim();
},
toInt(value) {
return value && parseInt(value, 10);
},
toMoment(value) {
return moment(value);
},
},
});
// From https://git.io/viRqj
const anchorify = (text) => (
text.toLowerCase()
.split(/ /)
.join('-')
.split(/\t/)
.join('--')
.split(/[|$&`~=\\\/@+*!?({[\]})<>=.,;:'"^]/)
.join('')
);
const GITHUB_URL = 'https://github.com';
const numberWithCommas = (n) => (
n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
);
const fetchGitHubDetails = (githubURL) => (
new Promise((resolve, reject) => {
x(githubURL, {
starCount: '.js-social-count | trim | removeCommas | toInt',
lastCommit: 'relative-time@datetime | trim | toMoment',
})((err, data) => {
if (err) {
console.error(`Error scraping ${githubURL}`, err);
return reject(err);
}
return resolve(data);
});
})
);
// Find duplicate entries in an array of objects for a given key.
const duplicatesForKey = (objectArray, key) => (
objectArray.filter((object, index) => (
object[key] && find(objectArray.slice(index + 1), [key, object[key]])
)).map((object) => object[key])
);
const generateReadme = () => {
const startedAt = moment();
const metaContents = fs.readFileSync('./meta.toml');
const meta = camelizeKeys(toml.parse(metaContents));
const dataFiles = glob.sync('data/*.toml');
const allCMSES = dataFiles.map((dataFile) => (
camelizeKeys(toml.parse(fs.readFileSync(dataFile)))
));
const duplicateURLS = duplicatesForKey(allCMSES, 'url');
const duplicateGithubRepos = duplicatesForKey(allCMSES, 'githubRepo');
if (duplicateURLS.length) {
console.error(`Duplciate url found: ${duplicateURLS}`);
}
if (duplicateGithubRepos.length) {
console.error(`Duplciate github_repo found: ${duplicateGithubRepos}`);
}
const { languagesToHuman } = meta;
const cmsesByLanguage = groupBy(allCMSES, 'language');
const languageKeys = Object.keys(cmsesByLanguage).sort();
const tocEntries = languageKeys.map((key) => {
let humanName = languagesToHuman[key];
if (!humanName) {
console.error(
`Human name missing for "${key}" language. Add it to meta.toml`
);
humanName = key;
}
return {
text: humanName,
anchor: anchorify(humanName),
};
});
Promise.all(languageKeys.map((key) => {
const cmsesForLanguage = cmsesByLanguage[key];
const cmsPromises = cmsesForLanguage.map(
({ awesomeRepo, name, description, githubRepo, url }) => {
const githubURL = githubRepo && `${GITHUB_URL}/${githubRepo}`;
const awesomeURL = awesomeRepo && `${GITHUB_URL}/${awesomeRepo}`;
if (githubRepo) {
return fetchGitHubDetails(githubURL).then(({ starCount, lastCommit }) => ({
awesomeURL,
name,
githubURL,
starCount,
starCountText: numberWithCommas(starCount),
lastCommit: lastCommit.format('YYYY/MM/DD'),
url,
description,
}));
}
return {
awesomeURL,
name,
url,
description,
};
}
);
return Promise.all(cmsPromises).then((cmses) => {
// Sort by star count or name if starCount not available.
const sortedCMSES = cmses[0].githubURL ?
sortBy(cmses, ({ starCount }) => starCount).reverse()
:
sortBy(cmses, ({ name }) => name.toLowerCase());
return {
name: languagesToHuman[key],
headerColumns: compact([
'Name',
'Description',
]),
cmses: sortedCMSES,
};
});
})).then((cmsGroups) => {
fs.writeFileSync('README.md', readmeTemplate({
cmsCount: allCMSES.length,
cmsGroups,
generationTime: moment().format('MMMM Do, YYYY'),
tocEntries,
}));
const milliseconds = moment().diff(startedAt);
console.log(
`Finished README.md generation for ${allCMSES.length}` +
` CMSes in ${milliseconds / 1000.0} seconds.`
);
}).catch((error) => {
console.error('Error generating readme', error);
});
};
generateReadme();