Consistency for tools
This commit is contained in:
@ -7,7 +7,8 @@ Here's what you can do to help:
|
|||||||
- [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified.
|
- [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified.
|
||||||
- Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby).
|
- Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby).
|
||||||
- Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines).
|
- Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines).
|
||||||
- Fix typos in existing snippets or run `npm run lint "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with).
|
- Fix typos in existing snippets or run `npm run linter "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with).
|
||||||
|
- Tag untagged snippets by running `npm run tagger` and adding the appropriate tag next to the script name in `tag_database`.
|
||||||
|
|
||||||
### Snippet submission and Pull request guidelines
|
### Snippet submission and Pull request guidelines
|
||||||
|
|
||||||
|
|||||||
@ -15,9 +15,9 @@
|
|||||||
"chalk": "^2.3.0"
|
"chalk": "^2.3.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build-list": "node ./scripts/builder.js",
|
"builder": "node ./scripts/build-script.js",
|
||||||
"lint": "node ./scripts/lintSnippet.js",
|
"linter": "node ./scripts/lint-script.js",
|
||||||
"tag": "node ./scripts/tagger.js",
|
"tagger": "node ./scripts/tag-script.js",
|
||||||
"start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\""
|
"start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\""
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
79
scripts/build-script.js
Normal file
79
scripts/build-script.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
This is the builder script that generates the README file.
|
||||||
|
Run using `npm run builder`.
|
||||||
|
*/
|
||||||
|
// Load modules
|
||||||
|
const fs = require('fs-extra'), path = require('path'), chalk = require('chalk');
|
||||||
|
// Set variables for paths
|
||||||
|
const snippetsPath = './snippets', staticPartsPath = './static-parts';
|
||||||
|
// Set variables for script
|
||||||
|
let snippets = {}, startPart = '', endPart = '', output = '', tagDbData = {};
|
||||||
|
// Load helper functions (these are from existing snippets in 30 seconds of code!)
|
||||||
|
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
|
||||||
|
const capitalize = (str, lowerRest = false) => str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
|
||||||
|
// Start the timer of the script
|
||||||
|
console.time('Builder');
|
||||||
|
// Synchronously read all snippets and sort them as necessary (case-insensitive)
|
||||||
|
try {
|
||||||
|
let snippetFilenames = fs.readdirSync(snippetsPath);
|
||||||
|
snippetFilenames.sort((a, b) => {
|
||||||
|
a = a.toLowerCase();
|
||||||
|
b = b.toLowerCase();
|
||||||
|
if (a < b) return -1;
|
||||||
|
if (a > b) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
// Store the data read from each snippet in the appropriate object
|
||||||
|
for(let snippet of snippetFilenames) snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8');
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Load static parts for the README file
|
||||||
|
try {
|
||||||
|
startPart = fs.readFileSync(path.join(staticPartsPath,'README-start.md'),'utf8');
|
||||||
|
endPart = fs.readFileSync(path.join(staticPartsPath,'README-end.md'),'utf8');
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Load tag data from the database
|
||||||
|
try {
|
||||||
|
tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2)));
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Create the output for the README file
|
||||||
|
try {
|
||||||
|
// Add the start static part
|
||||||
|
output += `${startPart+'\n'}`;
|
||||||
|
// Loop over tags and snippets to create the table of contents
|
||||||
|
for(let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){
|
||||||
|
output +=`### ${capitalize(tag, true)}\n`;
|
||||||
|
for(let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
|
||||||
|
output += `* [${taggedSnippet[0][0].toUpperCase() + taggedSnippet[0].replace(/-/g,' ').slice(1)}](#${taggedSnippet[0].replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n`
|
||||||
|
output += '\n';
|
||||||
|
}
|
||||||
|
// Loop over tags and snippets to create the list of snippets
|
||||||
|
for(let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){
|
||||||
|
output +=`## ${capitalize(tag, true)}\n`;
|
||||||
|
for(let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
|
||||||
|
output += `\n${snippets[taggedSnippet[0]+'.md']+'\n[⬆ back to top](#table-of-contents)\n'}`;
|
||||||
|
}
|
||||||
|
// Add the ending static part
|
||||||
|
output += `\n${endPart+'\n'}`;
|
||||||
|
// Write to the README file
|
||||||
|
fs.writeFileSync('README.md', output);
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During README generation: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Log a success message
|
||||||
|
console.log(`${chalk.green('SUCCESS!')} README file generated!`);
|
||||||
|
// Log the time taken
|
||||||
|
console.timeEnd('Builder');
|
||||||
@ -1,74 +0,0 @@
|
|||||||
var fs = require('fs-extra');
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
var snippetsPath = './snippets';
|
|
||||||
var staticPartsPath = './static-parts';
|
|
||||||
|
|
||||||
var snippets = {}, startPart = '', endPart = '', output = '', tagDbData = {};
|
|
||||||
|
|
||||||
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
|
|
||||||
const capitalize = (str, lowerRest = false) => str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
|
|
||||||
|
|
||||||
console.time('Builder');
|
|
||||||
|
|
||||||
try {
|
|
||||||
var snippetFilenames = fs.readdirSync(snippetsPath);
|
|
||||||
snippetFilenames.sort((a, b) => {
|
|
||||||
a = a.toLowerCase();
|
|
||||||
b = b.toLowerCase();
|
|
||||||
if (a < b) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (a > b) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
for(var snippet of snippetFilenames){
|
|
||||||
snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during snippet loading: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
startPart = fs.readFileSync(path.join(staticPartsPath,'README-start.md'),'utf8');
|
|
||||||
endPart = fs.readFileSync(path.join(staticPartsPath,'README-end.md'),'utf8');
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during static part loading: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2)));
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during tag database loading: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
output += `${startPart+'\n'}`;
|
|
||||||
for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){
|
|
||||||
output +=`### ${capitalize(tag, true)}\n`;
|
|
||||||
for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
|
|
||||||
output += `* [${taggedSnippet[0][0].toUpperCase() + taggedSnippet[0].replace(/-/g,' ').slice(1)}](#${taggedSnippet[0].replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n`
|
|
||||||
output += '\n';
|
|
||||||
}
|
|
||||||
for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){
|
|
||||||
output +=`## ${capitalize(tag, true)}\n`;
|
|
||||||
for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag))
|
|
||||||
output += `\n${snippets[taggedSnippet[0]+'.md']+'\n[⬆ back to top](#table-of-contents)\n'}`;
|
|
||||||
}
|
|
||||||
output += `\n${endPart+'\n'}`;
|
|
||||||
fs.writeFileSync('README.md', output);
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during README generation: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.timeEnd('Builder');
|
|
||||||
67
scripts/tag-script.js
Normal file
67
scripts/tag-script.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
This is the tagger script that updates the tag_databse file and logs stats for snippet tags.
|
||||||
|
Run using `npm run tagger`.
|
||||||
|
*/
|
||||||
|
// Load modules
|
||||||
|
const fs = require('fs-extra'), path = require('path'), chalk = require('chalk');
|
||||||
|
// Set variables for paths
|
||||||
|
const snippetsPath = './snippets';
|
||||||
|
// Set variables for script
|
||||||
|
let snippets = {}, output = '', tagDbData = {}, missingTags = 0, tagDbStats = {};
|
||||||
|
// Load helper functions (these are from existing snippets in 30 seconds of code!)
|
||||||
|
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
|
||||||
|
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
|
||||||
|
// Start the timer of the script
|
||||||
|
console.time('Tagger');
|
||||||
|
// Synchronously read all snippets and sort them as necessary (case-insensitive)
|
||||||
|
try {
|
||||||
|
let snippetFilenames = fs.readdirSync(snippetsPath);
|
||||||
|
snippetFilenames.sort((a, b) => {
|
||||||
|
a = a.toLowerCase();
|
||||||
|
b = b.toLowerCase();
|
||||||
|
if (a < b) return -1;
|
||||||
|
if (a > b) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
// Store the data read from each snippet in the appropriate object
|
||||||
|
for(let snippet of snippetFilenames) snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8');
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Load tag data from the database
|
||||||
|
try {
|
||||||
|
tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2)));
|
||||||
|
tagDbStats = Object.entries(tagDbData).sort((a,b) => a[1].localeCompare(b[1])).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {});
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Update the listing of snippets in tag_database and log the statistics, along with missing scripts
|
||||||
|
try {
|
||||||
|
for(let snippet of Object.entries(snippets))
|
||||||
|
if(tagDbData.hasOwnProperty(snippet[0].slice(0,-3)) && tagDbData[snippet[0].slice(0,-3)].trim())
|
||||||
|
output += `${snippet[0].slice(0,-3)}:${tagDbData[snippet[0].slice(0,-3)].trim()}\n`;
|
||||||
|
else {
|
||||||
|
output += `${snippet[0].slice(0,-3)}:\n`;
|
||||||
|
missingTags++;
|
||||||
|
console.log(`${chalk.yellow('Tag missing:')} ${snippet[0].slice(0,-3)}`);
|
||||||
|
}
|
||||||
|
// Write to tag_database
|
||||||
|
fs.writeFileSync('tag_database', output);
|
||||||
|
}
|
||||||
|
catch (err){ // Handle errors (hopefully not!)
|
||||||
|
console.log(`${chalk.red('ERROR!')} During tag_database generation: ${err}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// Log statistics for the tag_database file
|
||||||
|
console.log(`\n${chalk.bgWhite(chalk.black('=== TAG STATS ==='))}`)
|
||||||
|
for(let tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined'))
|
||||||
|
console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`);
|
||||||
|
console.log(`${chalk.blue('Untagged snippets:')} ${missingTags}\n`);
|
||||||
|
// Log a success message
|
||||||
|
console.log(`${chalk.green('SUCCESS!')} tag_database file updated!`);
|
||||||
|
// Log the time taken
|
||||||
|
console.timeEnd('Tagger');
|
||||||
@ -1,67 +0,0 @@
|
|||||||
var fs = require('fs-extra');
|
|
||||||
var path = require('path');
|
|
||||||
var chalk = require('chalk');
|
|
||||||
|
|
||||||
var snippetsPath = './snippets';
|
|
||||||
|
|
||||||
var snippets = {}, output = '', tagDbData = {}, missingTags = 0, tagDbStats = {};
|
|
||||||
|
|
||||||
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
|
|
||||||
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
console.time('Tagger');
|
|
||||||
|
|
||||||
try {
|
|
||||||
var snippetFilenames = fs.readdirSync(snippetsPath);
|
|
||||||
snippetFilenames.sort((a, b) => {
|
|
||||||
a = a.toLowerCase();
|
|
||||||
b = b.toLowerCase();
|
|
||||||
if (a < b) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (a > b) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
for(var snippet of snippetFilenames){
|
|
||||||
snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during snippet loading: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2)));
|
|
||||||
tagDbStats = Object.entries(tagDbData).sort((a,b) => a[1].localeCompare(b[1])).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {});
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during tag database loading: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
for(var snippet of Object.entries(snippets))
|
|
||||||
if(tagDbData.hasOwnProperty(snippet[0].slice(0,-3)) && tagDbData[snippet[0].slice(0,-3)].trim())
|
|
||||||
output += `${snippet[0].slice(0,-3)}:${tagDbData[snippet[0].slice(0,-3)].trim()}\n`;
|
|
||||||
else {
|
|
||||||
output += `${snippet[0].slice(0,-3)}:\n`;
|
|
||||||
missingTags++;
|
|
||||||
console.log(`${chalk.red('Tag missing:')} ${snippet[0].slice(0,-3)}`);
|
|
||||||
}
|
|
||||||
fs.writeFileSync('tag_database', output);
|
|
||||||
}
|
|
||||||
catch (err){
|
|
||||||
console.log('Error during README generation: '+err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.log(`\n=== TAG STATS ===`)
|
|
||||||
for(var tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined')){
|
|
||||||
console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`);
|
|
||||||
}
|
|
||||||
console.log(`${chalk.blue('Untagged snippets:')} ${missingTags}\n`);
|
|
||||||
|
|
||||||
console.timeEnd('Tagger');
|
|
||||||
Reference in New Issue
Block a user