Skip to content

Commit dfbb2f6

Browse files
authored
feat: initial setup (#1)
* feat: add initial version of script * fix: add fallback to undefined description and change default headers * fix: use start and end tags to replace content * refactor: move logic to inside generate folder * feat: add CLI interactivity * fix: properly handle errors when parsing snippets * chore: change package name * chore: add more config to package.json
1 parent b22e6ed commit dfbb2f6

File tree

6 files changed

+8409
-0
lines changed

6 files changed

+8409
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist
2+
node_modules
3+
.DS_Store

.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package-lock=false
2+
save-exact=true

package.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"name": "snippets-table",
3+
"version": "0.0.0-semantically-released",
4+
"description": "Tool to easily manage a table of snippets",
5+
"main": "dist/cli.js",
6+
"bin": {
7+
"snippets-table": "dist/cli.js"
8+
},
9+
"files": [
10+
"dist"
11+
],
12+
"scripts": {
13+
"build": "kcd-scripts build",
14+
"lint": "kcd-scripts lint"
15+
},
16+
"repository": {
17+
"type": "git",
18+
"url": "git+https://github.com/arthurdenner/snippets-table.git"
19+
},
20+
"keywords": [
21+
"snippets-table"
22+
],
23+
"author": "Arthur Denner <arthurdenner7@gmail.com>",
24+
"license": "MIT",
25+
"bugs": {
26+
"url": "https://github.com/arthurdenner/snippets-table/issues"
27+
},
28+
"homepage": "https://github.com/arthurdenner/snippets-table#readme",
29+
"devDependencies": {
30+
"kcd-scripts": "5.6.1"
31+
},
32+
"dependencies": {
33+
"@babel/runtime": "7.9.2",
34+
"chalk": "3.0.0",
35+
"inquirer": "7.1.0",
36+
"prettier": "2.0.2",
37+
"yargs": "15.3.1"
38+
},
39+
"eslintConfig": {
40+
"extends": "./node_modules/kcd-scripts/eslint.js",
41+
"rules": {
42+
"no-process-exit": "off"
43+
}
44+
}
45+
}

src/cli.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env node
2+
3+
const inquirer = require('inquirer');
4+
const yargs = require('yargs');
5+
const generate = require('./generate');
6+
7+
const yargv = yargs
8+
.help('help')
9+
.alias('h', 'help')
10+
.alias('v', 'version')
11+
.version()
12+
.recommendCommands()
13+
.command('generate', 'Generate the table of snippets')
14+
.usage('Usage: $0 generate')
15+
.default('pathToREADME', 'README.md')
16+
.default('pathToSnippets', 'snippets/snippets.json')
17+
.default('headers', ['Prefix', 'Name', 'Description']);
18+
19+
function promptForCommand({ argv }) {
20+
const questions = [
21+
{
22+
type: 'list',
23+
name: 'command',
24+
message: 'What do you want to do?',
25+
choices: [
26+
{
27+
name: 'Re-generate the table of snippets',
28+
value: 'generate',
29+
},
30+
],
31+
when: !argv._[0],
32+
default: 0,
33+
},
34+
];
35+
36+
return inquirer.prompt(questions).then(answers => {
37+
return answers.command || argv._[0];
38+
});
39+
}
40+
41+
promptForCommand(yargv).then(command => {
42+
switch (command) {
43+
case 'generate':
44+
return generate(yargv.parsed.argv);
45+
default:
46+
throw new Error(`Unknown command ${command}`);
47+
}
48+
});

src/generate/index.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* eslint-disable no-console */
2+
3+
const fs = require('fs');
4+
const chalk = require('chalk');
5+
const prettier = require('prettier');
6+
7+
const START_TAG =
8+
'<!-- SNIPPETS-TABLE:START - Do not remove or modify this line -->';
9+
const END_TAG = '<!-- SNIPPETS-TABLE:END -->';
10+
const readFile = path => fs.promises.readFile(path, 'utf8');
11+
const getPrefix = p => (Array.isArray(p) ? p.join(', ') : p);
12+
13+
function createTableLines(snippets, headers) {
14+
const separatorLine = headers.reduce(acc => acc.concat(`--- | `), '\n| ');
15+
const headersLine = headers.reduce((acc, h) => acc.concat(`${h} | `), '| ');
16+
const bodyLines = Object.keys(snippets).reduce((acc, key) => {
17+
const { description = '---', prefix } = snippets[key];
18+
const newLine = `\n| \`${getPrefix(prefix)}\` | ${key} | ${description} |`;
19+
20+
return acc.concat(newLine);
21+
}, '');
22+
const table = headersLine.concat(separatorLine, bodyLines);
23+
24+
return prettier.format(table, { parser: 'markdown' }).trim();
25+
}
26+
27+
async function generateTable({ pathToREADME, pathToSnippets, headers }) {
28+
try {
29+
const readme = await readFile(pathToREADME);
30+
const regex = RegExp(`${START_TAG}([\\s\\S]*?)${END_TAG}`);
31+
32+
if (!regex.test(readme)) {
33+
throw Error("Couldn't find start and end tags");
34+
}
35+
36+
let snippets = await readFile(pathToSnippets);
37+
38+
try {
39+
snippets = JSON.parse(snippets);
40+
} catch (err) {
41+
console.error(chalk.red(err.message));
42+
throw Error(`There was an error parsing ${pathToSnippets}`);
43+
}
44+
45+
const snippetsLines = createTableLines(snippets, headers);
46+
const replace = START_TAG.concat('\n\n', snippetsLines, '\n\n', END_TAG);
47+
const newReadme = readme.replace(regex, replace);
48+
49+
await fs.promises.writeFile(pathToREADME, newReadme, 'utf-8');
50+
51+
console.log(chalk.green(`${pathToREADME} updated!`));
52+
} catch (err) {
53+
console.error(chalk.red(err.message));
54+
process.exit(1);
55+
}
56+
}
57+
58+
module.exports = generateTable;

0 commit comments

Comments
 (0)