mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 12:53:03 -05:00
feat(generator): create generator to transform README files
This commit is contained in:
@@ -54,7 +54,7 @@ this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]
|
|||||||
4. **nx serve crud**
|
4. **nx serve crud**
|
||||||
5. _...work On it_
|
5. _...work On it_
|
||||||
6. Commit your work
|
6. Commit your work
|
||||||
7. Submit a PR with a title beginning with **Answer:3** that I will review and other dev can review.
|
7. Submit a PR with a title beginning with **Answer:5** that I will review and other dev can review.
|
||||||
|
|
||||||
<a href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A5+label%3Aanswer" target="_blank"><img src="https://img.shields.io/badge/-Solutions-green" alt="Crud solution"/></a>
|
<a href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A5+label%3Aanswer" target="_blank"><img src="https://img.shields.io/badge/-Solutions-green" alt="Crud solution"/></a>
|
||||||
<a href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A5+label%3A"answer+author"'><img src="https://img.shields.io/badge/-Author solution-important" alt="Crud solution author"/></a>
|
<a href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A5+label%3A"answer+author"'><img src="https://img.shields.io/badge/-Author solution-important" alt="Crud solution author"/></a>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ You can also do it with cypress.
|
|||||||
6. `npx nx component-test testing-todos-list --watch` to test your application with Cypress
|
6. `npx nx component-test testing-todos-list --watch` to test your application with Cypress
|
||||||
7. _...work on it_
|
7. _...work on it_
|
||||||
8. Commit your work
|
8. Commit your work
|
||||||
9. Submit a PR with a title beginning with **Answer:28** that I will review and other dev can review.
|
9. Submit a PR with a title beginning with **Answer:29** that I will review and other dev can review.
|
||||||
|
|
||||||
<a href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A28+label%3Aanswer"><img src="https://img.shields.io/badge/-Solutions-green" alt="todo list app testing"/></a>
|
<a href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A28+label%3Aanswer"><img src="https://img.shields.io/badge/-Solutions-green" alt="todo list app testing"/></a>
|
||||||
<a href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A285+label%3A"answer+author"'><img src="https://img.shields.io/badge/-Author solution-important" alt="todo list app testing solution author"/></a>
|
<a href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A285+label%3A"answer+author"'><img src="https://img.shields.io/badge/-Author solution-important" alt="todo list app testing solution author"/></a>
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
"factory": "./src/generators/app/generator",
|
"factory": "./src/generators/app/generator",
|
||||||
"schema": "./src/generators/app/schema.json",
|
"schema": "./src/generators/app/schema.json",
|
||||||
"description": "app generator"
|
"description": "app generator"
|
||||||
|
},
|
||||||
|
"readme": {
|
||||||
|
"factory": "./src/generators/readme/generator",
|
||||||
|
"schema": "./src/generators/readme/schema.json",
|
||||||
|
"description": "readme generator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
201
libs/cli/src/generators/readme/generator.ts
Normal file
201
libs/cli/src/generators/readme/generator.ts
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
import { Tree, formatFiles } from '@nx/devkit';
|
||||||
|
import { readFile, writeFile } from 'fs/promises';
|
||||||
|
|
||||||
|
const README_FILENAME = 'README.md';
|
||||||
|
const OMIT = ['memoized', 'projection', 'testing-table', 'testing-forms'];
|
||||||
|
|
||||||
|
function findReadMe(tree: Tree, path: string): string[] {
|
||||||
|
let result: string[] = [];
|
||||||
|
if (!tree.isFile(path)) {
|
||||||
|
tree.children(path).forEach((child) => {
|
||||||
|
if (!OMIT.includes(child)) {
|
||||||
|
if (child === README_FILENAME) {
|
||||||
|
result.push(path + '/' + child);
|
||||||
|
} else {
|
||||||
|
result = result.concat(findReadMe(tree, path + '/' + child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findDocFile(
|
||||||
|
tree: Tree,
|
||||||
|
path: string,
|
||||||
|
number: string,
|
||||||
|
result: string[]
|
||||||
|
) {
|
||||||
|
if (!tree.isFile(path)) {
|
||||||
|
tree.children(path).forEach((child) => {
|
||||||
|
if (child.startsWith(`${number}-`)) {
|
||||||
|
result.push(path + '/' + child);
|
||||||
|
} else {
|
||||||
|
findDocFile(tree, path + '/' + child, number, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findHref(href) {
|
||||||
|
const regexHref = new RegExp(/href=("|')(.+?)("|')/);
|
||||||
|
const matchHref = href.match(regexHref);
|
||||||
|
|
||||||
|
return matchHref[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function rewriteFile(tree: Tree, file: string) {
|
||||||
|
console.log('Current file', file);
|
||||||
|
const buffer = await readFile(file, { encoding: 'utf-8' });
|
||||||
|
|
||||||
|
const regex = new RegExp(/Answer:(\d+)/);
|
||||||
|
const match = buffer.match(regex);
|
||||||
|
|
||||||
|
if (!match) throw new Error('NO MATCH');
|
||||||
|
|
||||||
|
const number = parseInt(match[1], 10);
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
findDocFile(
|
||||||
|
tree,
|
||||||
|
'./docs/src/content/docs/challenges',
|
||||||
|
String(number),
|
||||||
|
result
|
||||||
|
);
|
||||||
|
const docFile = result[0];
|
||||||
|
|
||||||
|
const pathElts = docFile.split('/');
|
||||||
|
const link = `https://angular-challenges.vercel.app/challenges/${pathElts.at(
|
||||||
|
-2
|
||||||
|
)}/${pathElts.at(-1)}/`;
|
||||||
|
|
||||||
|
const doc = await readFile(docFile, { encoding: 'utf-8' });
|
||||||
|
|
||||||
|
const regexTitle = new RegExp(/title:\s(🟢|🟠|🔴)\s(.+?)\n/);
|
||||||
|
const matchTitle = doc.match(regexTitle);
|
||||||
|
const title = matchTitle[2];
|
||||||
|
|
||||||
|
const regexCommand = new RegExp(/npx nx serve\s(.+?)`\s/);
|
||||||
|
const matchCommand = buffer.match(regexCommand);
|
||||||
|
|
||||||
|
let command = '';
|
||||||
|
if (!matchCommand) {
|
||||||
|
const regexOldCommand = new RegExp(/nx serve\s(.+?)\*/);
|
||||||
|
command = buffer.match(regexOldCommand)[1];
|
||||||
|
} else {
|
||||||
|
command = matchCommand[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('commande:', command);
|
||||||
|
|
||||||
|
const finalText = `# ${title}
|
||||||
|
|
||||||
|
> Author: Thomas Laforge
|
||||||
|
|
||||||
|
### Run Application
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
npx nx serve ${command}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Documentation and Instruction
|
||||||
|
|
||||||
|
Challenge documentation is [here](${link}).
|
||||||
|
`;
|
||||||
|
|
||||||
|
await writeFile(file, finalText, { encoding: 'utf-8' });
|
||||||
|
|
||||||
|
///**** */
|
||||||
|
|
||||||
|
const regexHref = new RegExp(/<a href=("|')(.+?)("|')/, 'g');
|
||||||
|
const href = buffer.match(regexHref).map(findHref);
|
||||||
|
|
||||||
|
console.log('HREF', href);
|
||||||
|
|
||||||
|
let footerText = `:::note
|
||||||
|
Start the project by running: \`npx nx serve ${command}\`.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip[Reminder]
|
||||||
|
Your PR title must start with <b>Answer:${number}</b>.
|
||||||
|
:::
|
||||||
|
|
||||||
|
<div class="article-footer">
|
||||||
|
<a
|
||||||
|
href="${href[0]}"
|
||||||
|
alt="${title} community solutions">
|
||||||
|
❖ Community Answers
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href='${href[1]}'
|
||||||
|
alt="${title} solution author">
|
||||||
|
▶︎ Author Answer
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (href[2].startsWith('https://medium')) {
|
||||||
|
footerText = `${footerText}<a
|
||||||
|
href='${href[2]}'
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
alt="${title} blog article">
|
||||||
|
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||||
|
Blog Post
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
footerText = `${footerText}</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const regexHeader = new RegExp(/([\s\S]*?)\s:::note/);
|
||||||
|
const header = doc.match(regexHeader)[1];
|
||||||
|
|
||||||
|
console.log('header', header);
|
||||||
|
|
||||||
|
const regexContent = new RegExp(
|
||||||
|
/Author: Thomas Laforge([\s\S]*?)### Submitting your work/
|
||||||
|
);
|
||||||
|
const matchContent = buffer.match(regexContent);
|
||||||
|
|
||||||
|
let content = '';
|
||||||
|
if (!matchContent) {
|
||||||
|
const regexOldContent = new RegExp(
|
||||||
|
/Author: Thomas Laforge([\s\S]*?)## Submitting your work/
|
||||||
|
);
|
||||||
|
content = buffer.match(regexOldContent)[1];
|
||||||
|
} else {
|
||||||
|
content = matchContent[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullDocText = `${header}
|
||||||
|
|
||||||
|
:::note
|
||||||
|
WIP
|
||||||
|
:::
|
||||||
|
|
||||||
|
<div class="chip">Challenge #${number}</div>
|
||||||
|
|
||||||
|
${content}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
${footerText}
|
||||||
|
`;
|
||||||
|
|
||||||
|
await writeFile(docFile, fullDocText, { encoding: 'utf-8' });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function readmeGenerator(tree: Tree) {
|
||||||
|
const readmeFiles = findReadMe(tree, './apps');
|
||||||
|
|
||||||
|
for (const f of readmeFiles) {
|
||||||
|
// const f = './apps/performance/default-onpush/README.md';
|
||||||
|
await rewriteFile(tree, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default readmeGenerator;
|
||||||
7
libs/cli/src/generators/readme/schema.json
Normal file
7
libs/cli/src/generators/readme/schema.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"$id": "Readme",
|
||||||
|
"title": "",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user