diff --git a/README.MD b/README.MD index 12e2869..6e2223e 100644 --- a/README.MD +++ b/README.MD @@ -280,7 +280,7 @@ Markers in the document describe where the content should be inserted, existing | **insertCodeAbove** | | string | A marker in the file to insert code above. | | **copyCodeBelow** | | string | A marker in the file being inserted to say only copy code below this line | | **copyCodeAbove** | | string | A marker in the file being inserted to say only copy code above this line | -| **jsFile** | **j** | string[] | jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple file can be specified. | +| **jsFile** | **j** | string[] | jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple files can be specified. | | **configImportName** | **c** | string[] | Export name of the 'UsageGuideConfig' object. Defaults to 'usageGuideInfo'. Multiple exports can be specified. | | **verify** | **v** | boolean | Verify the markdown file. Does not update the file but returns a non zero exit code if the markdown file is not correct. Useful for a pre-publish script. | | **configFile** | **f** | string | Optional config file to load config from. package.json can be used if jsonPath specified as well | @@ -350,12 +350,34 @@ You can also surround the inserted code with a triple backticks by including `co [//]: # (ts-command-line-args_write-markdown_insertCodeBelow file="path/from/markdown/to/file.ts" codeComment="typescript" ) ``` -Areas to to include from the file that is being inserted can be designated with more markers within the file. For example: +Areas to include from the file that is being inserted can be designated with more markers within the file. For example: -[//]: # (ts-command-line-args_write-markdown_insertCodeBelow file="" codeComment=typescript ) -[//]: # (ts-command-line-args_write-markdown_insertCodeAbove ) +```ts +export const someExport = "not copied"; +// ts-command-line-args_write-markdown_copyCodeBelow; +export function (){ + //this function will be copied +} +// ts-command-line-args_write-markdown_copyCodeAbove; +``` + +Insert code can also be performed in code: + +[//]: # (ts-command-line-args_readme-generation_insertCodeBelow file="src\example\insert-code.example.ts" codeComment="typescript" ) +```typescript +async function insertSampleCode() { + // this function is inserted into markdown from a ts file using insertCode + await insertCode('src/example/insert-code-sample.md', { + insertCodeBelow: insertCodeBelowDefault, + insertCodeAbove: insertCodeAboveDefault, + copyCodeBelow: copyCodeBelowDefault, + copyCodeAbove: copyCodeAboveDefault, + }); +} +``` +[//]: # (ts-command-line-args_readme-generation_insertCodeAbove) - ### String Formatting +### String Formatting The only chalk modifiers supported when converting to markdown are `bold` and `italic`. For example: diff --git a/package.json b/package.json index 0f97141..451f72e 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,8 @@ "markdownPath": "README.MD", "jsFile": "dist/write-markdown.constants.js", "verifyMessage": "'{fileName}' is out of date. Please regenerate by running 'npm run write-markdown'", - "removeDoubleBlankLines": true + "removeDoubleBlankLines": true, + "insertCodeBelow": "[//]: # (ts-command-line-args_readme-generation_insertCodeBelow", + "insertCodeAbove": "[//]: # (ts-command-line-args_readme-generation_insertCodeAbove)" } } diff --git a/src/contracts.ts b/src/contracts.ts index f33594a..c71a9f6 100644 --- a/src/contracts.ts +++ b/src/contracts.ts @@ -307,7 +307,7 @@ export type JsImport = { jsFile: string; importName: string }; export interface IWriteMarkDown extends IReplaceOptions, IInsertCodeOptions { markdownPath: string; - jsFile: string[]; + jsFile?: string[]; configImportName: string[]; help: boolean; verify: boolean; diff --git a/src/example/insert-code.example.ts b/src/example/insert-code.example.ts index 7abae34..c33b4ef 100644 --- a/src/example/insert-code.example.ts +++ b/src/example/insert-code.example.ts @@ -8,6 +8,7 @@ import { // ts-command-line-args_write-markdown_copyCodeBelow async function insertSampleCode() { + // this function is inserted into markdown from a ts file using insertCode await insertCode('src/example/insert-code-sample.md', { insertCodeBelow: insertCodeBelowDefault, insertCodeAbove: insertCodeAboveDefault, diff --git a/src/helpers/insert-code.helper.spec.ts b/src/helpers/insert-code.helper.spec.ts index f2f4996..8b7c27d 100644 --- a/src/helpers/insert-code.helper.spec.ts +++ b/src/helpers/insert-code.helper.spec.ts @@ -32,6 +32,9 @@ describe(`(${insertCode.name}) insert-code.helper`, () => { setupFunction('readFile', ((_path: string, callback: (err: Error | null, data: Buffer) => void) => { callback(null, Buffer.from(`${insertLineOne}${EOL}${insertLineTwo}`)); }) as any), + setupFunction('writeFile', ((_path: string, _data: any, callback: () => void) => { + callback(); + }) as any), ); registerMock(originalFs, mockedFs.mock); @@ -113,13 +116,18 @@ describe(`(${insertCode.name}) insert-code.helper`, () => { } }) as any); - const result = await insertCode(`${sampleDirName}/'originalFilePath.ts`, createOptions()); + const result = await insertCode(`${sampleDirName}/originalFilePath.ts`, createOptions()); expect( mockedFs.withFunction('readFile').withParameters(resolve(sampleDirName, 'someFile.ts'), any()), ).wasCalledOnce(); expect( - mockedFs.withFunction('readFile').withParameters(resolve(`${sampleDirName}/'originalFilePath.ts`), any()), + mockedFs.withFunction('readFile').withParameters(resolve(`${sampleDirName}/originalFilePath.ts`), any()), + ).wasCalledOnce(); + expect( + mockedFs + .withFunction('writeFile') + .withParameters(resolve(`${sampleDirName}/originalFilePath.ts`), any(), any()), ).wasCalledOnce(); const expectedContent = [ diff --git a/src/helpers/insert-code.helper.ts b/src/helpers/insert-code.helper.ts index 0f56c1b..3dd5a55 100644 --- a/src/helpers/insert-code.helper.ts +++ b/src/helpers/insert-code.helper.ts @@ -13,6 +13,11 @@ export type FileDetails = { fileContent: string; }; +/** + * Loads content from other files and inserts it into the target file + * @param input - if a string is provided the target file is loaded from that path AND saved to that path once content has been inserted. If a `FileDetails` object is provided the content is not saved when done. + * @param partialOptions - optional. changes the default tokens + */ export async function insertCode( input: FileDetails | string, partialOptions?: Partial, diff --git a/src/helpers/markdown.helper.spec.ts b/src/helpers/markdown.helper.spec.ts index 12dc3de..4457a4b 100644 --- a/src/helpers/markdown.helper.spec.ts +++ b/src/helpers/markdown.helper.spec.ts @@ -118,7 +118,7 @@ Markers in the document describe where the content should be inserted, existing | **insertCodeAbove** | | string | A marker in the file to insert code above. | | **copyCodeBelow** | | string | A marker in the file being inserted to say only copy code below this line | | **copyCodeAbove** | | string | A marker in the file being inserted to say only copy code above this line | -| **jsFile** | **j** | string[] | jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple file can be specified. | +| **jsFile** | **j** | string[] | jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple files can be specified. | | **configImportName** | **c** | string[] | Export name of the 'UsageGuideConfig' object. Defaults to 'usageGuideInfo'. Multiple exports can be specified. | | **verify** | **v** | boolean | Verify the markdown file. Does not update the file but returns a non zero exit code if the markdown file is not correct. Useful for a pre-publish script. | | **configFile** | **f** | string | Optional config file to load config from. package.json can be used if jsonPath specified as well | diff --git a/src/helpers/markdown.helper.ts b/src/helpers/markdown.helper.ts index 52021d0..9d6e895 100644 --- a/src/helpers/markdown.helper.ts +++ b/src/helpers/markdown.helper.ts @@ -143,7 +143,14 @@ export function getType(option: CommandLineOption): string { return `${type}${multiple} `; } -export function generateUsageGuides(args: IWriteMarkDown): string[] { +export function generateUsageGuides(args: IWriteMarkDown): string[] | undefined { + if (args.jsFile == null) { + console.log( + `No jsFile defined for usage guide generation. See 'write-markdown -h' for details on generating usage guides.`, + ); + return undefined; + } + function mapJsImports(imports: JsImport[], jsFile: string) { return [...imports, ...args.configImportName.map((importName) => ({ jsFile, importName }))]; } diff --git a/src/write-markdown.constants.ts b/src/write-markdown.constants.ts index a46da4d..22ec68a 100644 --- a/src/write-markdown.constants.ts +++ b/src/write-markdown.constants.ts @@ -13,6 +13,7 @@ export const argumentConfig: ArgumentConfig = { markdownPath: { type: String, alias: 'm', + defaultOption: true, description: 'The file to write to. Without replacement markers the whole file content will be replaced. Path can be absolute or relative.', }, @@ -54,8 +55,9 @@ export const argumentConfig: ArgumentConfig = { }, jsFile: { type: String, + optional: true, alias: 'j', - description: `jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple file can be specified.`, + description: `jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple files can be specified.`, multiple: true, }, configImportName: { diff --git a/src/write-markdown.ts b/src/write-markdown.ts index 514fe20..4575f47 100644 --- a/src/write-markdown.ts +++ b/src/write-markdown.ts @@ -4,25 +4,32 @@ import { parse } from './parse'; import { IWriteMarkDown } from './contracts'; import { resolve, relative } from 'path'; import { readFileSync, writeFileSync } from 'fs'; -import { addCommandLineArgsFooter, addContent, generateUsageGuides } from './helpers'; +import { addCommandLineArgsFooter, addContent, generateUsageGuides, insertCode } from './helpers'; import { argumentConfig, parseOptions } from './write-markdown.constants'; import format from 'string-format'; import chalk from 'chalk'; -function writeMarkdown() { +async function writeMarkdown() { const args = parse(argumentConfig, parseOptions); const markdownPath = resolve(args.markdownPath); - console.log(`Loading existing file from '${markdownPath}'`); + console.log(`Loading existing file from '${chalk.blue(markdownPath)}'`); const markdownFileContent = readFileSync(markdownPath).toString(); const usageGuides = generateUsageGuides(args); - let modifiedFileContent = addContent(markdownFileContent, usageGuides, args); - if (!args.skipFooter) { - modifiedFileContent = addCommandLineArgsFooter(modifiedFileContent); + + let modifiedFileContent = markdownFileContent; + + if (usageGuides != null) { + modifiedFileContent = addContent(markdownFileContent, usageGuides, args); + if (!args.skipFooter) { + modifiedFileContent = addCommandLineArgsFooter(modifiedFileContent); + } } + modifiedFileContent = await insertCode({ fileContent: modifiedFileContent, filePath: markdownPath }, args); + const action = args.verify === true ? `verify` : `write`; const contentMatch = markdownFileContent === modifiedFileContent ? `match` : `nonMatch`; @@ -48,7 +55,7 @@ function writeMarkdown() { console.log(chalk.blue(`'${relativePath}' content not modified, not writing to file.`)); break; case 'write_nonMatch': - console.log(chalk.green(`Writing file to '${relativePath}'`)); + console.log(`Writing modified file to '${chalk.blue(relativePath)}'`); writeFileSync(relativePath, modifiedFileContent); break; }