Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recognize mdx jsx comments #5

Merged
merged 3 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ You can install this package via npm:

## Tagging your Code as a Best Practice

You can tag blocks of code as best practices with specially formatted
comments:
You can tag blocks of code as best practices with specially formatted comments:

```tsx
// @BestPractice React Components
Expand Down Expand Up @@ -108,6 +107,11 @@ like to insert a best practice:
<!-- @BestPractice.insert insertIntoStaticDocs -->
<!-- @BestPractice.end -->

If your file is a `.mdx` Markdown file, use `JSX` style comments instead:

{/* @BestPractice.insert insertIntoStaticDocs */}
{/* @BestPractice.end */}

It's important to have both the start and end lines, as these will be used as
boundaries of the program to know where to replace the code.

Expand Down
2 changes: 1 addition & 1 deletion lib/cjs/types/utils/replace.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 19 additions & 5 deletions lib/cjs/utils/replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,15 @@ exports.insertBestPracticesIntoDoc = insertBestPracticesIntoDoc;
* Given lines from a file, return new lines with best practices inserted.
*/
const replaceBestPractices = (filename, lines, index, getBestPracticeLines) => {
const [startRe, endRe] = getInsertREs(filename);
let inBestPractice = false;
let lineNumber = 0;
const newLines = [];
const insertedIds = [];
for (const line of lines) {
lineNumber += 1;
if (inBestPractice) {
if (INSERT_END_RE.test(line)) {
if (endRe.test(line)) {
inBestPractice = false;
// Do not continue, we want to write out the end line
}
Expand All @@ -85,9 +86,9 @@ const replaceBestPractices = (filename, lines, index, getBestPracticeLines) => {
}
}
newLines.push(line);
if (INSERT_START_RE.test(line)) {
if (startRe.test(line)) {
inBestPractice = true;
const [, bestPracticeId] = INSERT_START_RE.exec(line);
const [, bestPracticeId] = startRe.exec(line);
if (!index.has(bestPracticeId)) {
throw new Error(`Missing best practice: file ${filename} at line ${lineNumber} expects best practice ID: ${bestPracticeId}. No best practice with this ID was found.`);
}
Expand All @@ -98,5 +99,18 @@ const replaceBestPractices = (filename, lines, index, getBestPracticeLines) => {
return [newLines, new Set(insertedIds)];
};
exports.replaceBestPractices = replaceBestPractices;
const INSERT_START_RE = /^\s*<!-- @BestPractice.insert (\S+) -->$/;
const INSERT_END_RE = /^\s*<!-- @BestPractice.end -->$/;
/**
* Get the regexp to match insertion comments in a documentation file.
*
* .mdx files use jsx comments rather than html comments.
*/
const getInsertREs = (filename) => {
if (/\.mdx$/.test(filename)) {
return [MDX_INSERT_START_RE, MDX_INSERT_END_RE];
}
return [MD_INSERT_START_RE, MD_INSERT_END_RE];
};
const MD_INSERT_START_RE = /^\s*<!-- @BestPractice.insert (\S+) -->$/;
const MD_INSERT_END_RE = /^\s*<!-- @BestPractice.end -->$/;
const MDX_INSERT_START_RE = /^\s*{\/\* @BestPractice.insert (\S+) \*\/}$/;
const MDX_INSERT_END_RE = /^\s*{\/\* @BestPractice.end \*\/}$/;
2 changes: 1 addition & 1 deletion lib/esm/types/utils/replace.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 19 additions & 5 deletions lib/esm/utils/replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ exports.insertBestPracticesIntoDoc = insertBestPracticesIntoDoc;
* Given lines from a file, return new lines with best practices inserted.
*/
const replaceBestPractices = (filename, lines, index, getBestPracticeLines) => {
const [startRe, endRe] = getInsertREs(filename);
let inBestPractice = false;
let lineNumber = 0;
const newLines = [];
const insertedIds = [];
for (const line of lines) {
lineNumber += 1;
if (inBestPractice) {
if (INSERT_END_RE.test(line)) {
if (endRe.test(line)) {
inBestPractice = false;
// Do not continue, we want to write out the end line
}
Expand All @@ -56,9 +57,9 @@ const replaceBestPractices = (filename, lines, index, getBestPracticeLines) => {
}
}
newLines.push(line);
if (INSERT_START_RE.test(line)) {
if (startRe.test(line)) {
inBestPractice = true;
const [, bestPracticeId] = INSERT_START_RE.exec(line);
const [, bestPracticeId] = startRe.exec(line);
if (!index.has(bestPracticeId)) {
throw new Error(`Missing best practice: file ${filename} at line ${lineNumber} expects best practice ID: ${bestPracticeId}. No best practice with this ID was found.`);
}
Expand All @@ -69,5 +70,18 @@ const replaceBestPractices = (filename, lines, index, getBestPracticeLines) => {
return [newLines, new Set(insertedIds)];
};
exports.replaceBestPractices = replaceBestPractices;
const INSERT_START_RE = /^\s*<!-- @BestPractice.insert (\S+) -->$/;
const INSERT_END_RE = /^\s*<!-- @BestPractice.end -->$/;
/**
* Get the regexp to match insertion comments in a documentation file.
*
* .mdx files use jsx comments rather than html comments.
*/
const getInsertREs = (filename) => {
if (/\.mdx$/.test(filename)) {
return [MDX_INSERT_START_RE, MDX_INSERT_END_RE];
}
return [MD_INSERT_START_RE, MD_INSERT_END_RE];
};
const MD_INSERT_START_RE = /^\s*<!-- @BestPractice.insert (\S+) -->$/;
const MD_INSERT_END_RE = /^\s*<!-- @BestPractice.end -->$/;
const MDX_INSERT_START_RE = /^\s*{\/\* @BestPractice.insert (\S+) \*\/}$/;
const MDX_INSERT_END_RE = /^\s*{\/\* @BestPractice.end \*\/}$/;
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@closeio/best-practices-documentation",
"version": "0.4.1",
"version": "0.4.2",
"description": "Tooling to document best practices in your code base.",
"author": "Trey Cucco",
"main": "index.js",
Expand Down
74 changes: 58 additions & 16 deletions src/utils/replace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ import BestPractice from '../BestPractice';
import { replaceBestPractices } from './replace';

describe(replaceBestPractices, () => {
test('replaces best practices correctly', () => {
const getBestPracticeLines = (bestPractice: BestPractice) => {
return [
`\`\`\`${bestPractice.getFileType()}`,
...bestPractice.codeLines,
'```',
];
};

const bestPractices = [
mockBestPractice({ meta: { id: ['sample_id_1'] } }),
mockBestPractice({
codeLines: ['const c = a + b'],
meta: { id: ['sample_id_2'] },
}),
const getBestPracticeLines = (bestPractice: BestPractice) => {
return [
`\`\`\`${bestPractice.getFileType()}`,
...bestPractice.codeLines,
'```',
];
const index = new Map(bestPractices.map((bp) => [bp.getMeta('id'), bp]));
};

const bestPractices = [
mockBestPractice({ meta: { id: ['sample_id_1'] } }),
mockBestPractice({
codeLines: ['const c = a + b'],
meta: { id: ['sample_id_2'] },
}),
];
const index = new Map(bestPractices.map((bp) => [bp.getMeta('id'), bp]));

test('replaces .md best practices correctly', () => {
const oldLines = [
'## A Title',
'',
Expand Down Expand Up @@ -62,4 +62,46 @@ describe(replaceBestPractices, () => {

expect(insertedIds).toEqual(new Set(['sample_id_1']));
});

test('replaces .mdx best practices correctly', () => {
const oldLines = [
'## A Title',
'',
"Hello and here's the thing.",
'',
'{/* @BestPractice.insert sample_id_1 */}',
'this is',
'lines that were',
'inserted before',
'{/* @BestPractice.end */}',
'',
"And here's some stuff after",
];

const [newLines, insertedIds] = replaceBestPractices(
'someDocumentation.mdx',
oldLines,
index,
getBestPracticeLines,
);

expect(newLines).toEqual([
'## A Title',
'',
"Hello and here's the thing.",
'',
'{/* @BestPractice.insert sample_id_1 */}',
'```ts',
' const add = (a: number) => (b: number) => {',
' return a + b;',
' };',
' return add(5);',
'```',
'{/* @BestPractice.end */}',
'',
"And here's some stuff after",
]);

expect(insertedIds).toEqual(new Set(['sample_id_1']));
});
});
25 changes: 20 additions & 5 deletions src/utils/replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const replaceBestPractices = (
index: Map<string, BestPractice>,
getBestPracticeLines: (bestPractices: BestPractice) => string[],
): [newLines: string[], insertedIds: Set<string>] => {
const [startRe, endRe] = getInsertREs(filename);
let inBestPractice = false;
let lineNumber = 0;

Expand All @@ -73,7 +74,7 @@ export const replaceBestPractices = (
lineNumber += 1;

if (inBestPractice) {
if (INSERT_END_RE.test(line)) {
if (endRe.test(line)) {
inBestPractice = false;
// Do not continue, we want to write out the end line
} else {
Expand All @@ -83,10 +84,10 @@ export const replaceBestPractices = (

newLines.push(line);

if (INSERT_START_RE.test(line)) {
if (startRe.test(line)) {
inBestPractice = true;

const [, bestPracticeId] = INSERT_START_RE.exec(line)!;
const [, bestPracticeId] = startRe.exec(line)!;

if (!index.has(bestPracticeId)) {
throw new Error(
Expand All @@ -102,5 +103,19 @@ export const replaceBestPractices = (
return [newLines, new Set(insertedIds)];
};

const INSERT_START_RE = /^\s*<!-- @BestPractice.insert (\S+) -->$/;
const INSERT_END_RE = /^\s*<!-- @BestPractice.end -->$/;
/**
* Get the regexp to match insertion comments in a documentation file.
*
* .mdx files use jsx comments rather than html comments.
*/
const getInsertREs = (filename: string): [start: RegExp, end: RegExp] => {
if (/\.mdx$/.test(filename)) {
return [MDX_INSERT_START_RE, MDX_INSERT_END_RE];
}
return [MD_INSERT_START_RE, MD_INSERT_END_RE];
};

const MD_INSERT_START_RE = /^\s*<!-- @BestPractice.insert (\S+) -->$/;
const MD_INSERT_END_RE = /^\s*<!-- @BestPractice.end -->$/;
const MDX_INSERT_START_RE = /^\s*{\/\* @BestPractice.insert (\S+) \*\/}$/;
const MDX_INSERT_END_RE = /^\s*{\/\* @BestPractice.end \*\/}$/;