From 722228a55d048e2c65ba487690f426d52319523f Mon Sep 17 00:00:00 2001 From: Ayush Nautiyal <78146753+ayushnau@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:26:23 +0530 Subject: [PATCH 1/5] fix: update the ignore dependency in the changeset config (#1238) Co-authored-by: Lukasz Gornicki --- .changeset/config.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/config.json b/.changeset/config.json index d86fcec82..2396f0ca7 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -6,7 +6,6 @@ "linked": [], "access": "public", "baseBranch": "master", - "ignore": ["@asyncapi/nunjucks-filters"], "updateInternalDependencies": "patch", "privatePackages": { "version": true, From ef865ad5adb67eace83d78aac71f5ff4f8671919 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Wed, 31 Jul 2024 15:10:20 +0200 Subject: [PATCH 2/5] chore(release): release and bump versions of packages (#1239) --- .changeset/proud-brooms-accept.md | 5 ----- apps/generator/CHANGELOG.md | 6 ++++++ apps/generator/package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/proud-brooms-accept.md diff --git a/.changeset/proud-brooms-accept.md b/.changeset/proud-brooms-accept.md deleted file mode 100644 index 8a8feff94..000000000 --- a/.changeset/proud-brooms-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@asyncapi/generator": patch ---- - -Updated the method for importing the Nunjucks filter dependency \ No newline at end of file diff --git a/apps/generator/CHANGELOG.md b/apps/generator/CHANGELOG.md index ea79756ba..635a5a223 100644 --- a/apps/generator/CHANGELOG.md +++ b/apps/generator/CHANGELOG.md @@ -1,5 +1,11 @@ # @asyncapi/generator +## 2.1.3 + +### Patch Changes + +- 93fb8e8: Updated the method for importing the Nunjucks filter dependency + ## 2.1.2 ### Patch Changes diff --git a/apps/generator/package.json b/apps/generator/package.json index 19aacaa8b..dd0f8fc5d 100644 --- a/apps/generator/package.json +++ b/apps/generator/package.json @@ -1,6 +1,6 @@ { "name": "@asyncapi/generator", - "version": "2.1.2", + "version": "2.1.3", "description": "The AsyncAPI generator. It can generate documentation, code, anything!", "main": "./lib/generator.js", "bin": { From 81dfd0c25d719d25c6ad3c76db510e2574061457 Mon Sep 17 00:00:00 2001 From: lmgyuan Date: Wed, 31 Jul 2024 09:34:48 -0400 Subject: [PATCH 3/5] feat: enable noOverwriteGlobs for templates based on react engine (#1234) Co-authored-by: Lukasz Gornicki --- .changeset/enable_noOverwriteGlobs.md | 5 +++ .gitignore | 1 + apps/generator/lib/generator.js | 2 +- apps/generator/lib/logMessages.js | 20 ++++++----- apps/generator/lib/renderer/react.js | 46 ++++++++++++++++--------- apps/generator/package.json | 5 ++- apps/generator/test/integration.test.js | 35 +++++++++++++++++-- 7 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 .changeset/enable_noOverwriteGlobs.md diff --git a/.changeset/enable_noOverwriteGlobs.md b/.changeset/enable_noOverwriteGlobs.md new file mode 100644 index 000000000..b9e40ab44 --- /dev/null +++ b/.changeset/enable_noOverwriteGlobs.md @@ -0,0 +1,5 @@ +--- +"@asyncapi/generator": minor +--- + +Enable `noOverwriteGlobs` option for templates based on react rendering engine. diff --git a/.gitignore b/.gitignore index ecb69486e..a53c05bd1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ coverage # Turbo .turbo +/.idea diff --git a/apps/generator/lib/generator.js b/apps/generator/lib/generator.js index 0e66e6f8f..a8fb6c102 100644 --- a/apps/generator/lib/generator.js +++ b/apps/generator/lib/generator.js @@ -852,7 +852,7 @@ class Generator { if (renderContent === undefined) { return; } else if (isReactTemplate(this.templateConfig)) { - await saveRenderedReactContent(renderContent, outputpath); + await saveRenderedReactContent(renderContent, outputpath, this.noOverwriteGlobs); } else { await writeFile(outputpath, renderContent); } diff --git a/apps/generator/lib/logMessages.js b/apps/generator/lib/logMessages.js index 40a0e77ce..2d6e855fa 100644 --- a/apps/generator/lib/logMessages.js +++ b/apps/generator/lib/logMessages.js @@ -6,22 +6,22 @@ const NODE_MODULES_INSTALL ='Remember that your local template must have its own const NPM_INSTALL_TRIGGER = 'Installation of template located on disk technically means symlink creation betweed node_modules of the generator and template sources. Your local template must have its own node_modules, "npm install" is not triggered.'; -function templateVersion(ver) { +function templateVersion(ver) { return `Version of used template is ${ver}.`; -} +} function templateSource(localHtmlTemplate) { return `Template sources taken from ${localHtmlTemplate}.`; -} +} function templateNotFound(templateName) { return `${templateName} not found in local dependencies but found it installed as a global package.`; -} +} function packageNotAvailable(packageDetails) { if (packageDetails && packageDetails.pkgPath) { return `Unable to resolve template location at ${packageDetails.pkgPath}. Package is not available locally.`; - } + } return `Template is not available locally and expected location is undefined. Known details are: ${JSON.stringify(packageDetails, null, 2)}`; } @@ -38,6 +38,10 @@ function relativeSourceFileNotGenerated(relativeSourceFile , subject) { return `${relativeSourceFile} was not generated because ${subject} specified in template configuration in conditionalFiles was not found in provided AsyncAPI specification file.`; } +function skipOverwrite(testFilePath) { + return `Skipping overwrite for: ${testFilePath}`; +} + function conditionalFilesMatched(relativeSourceFile) { return `${relativeSourceFile} was not generated because condition specified for this file in template configuration in conditionalFiles matched.`; } @@ -54,6 +58,6 @@ module.exports = { installationDebugMessage, templateSuccessfullyInstalled, relativeSourceFileNotGenerated, - conditionalFilesMatched - -}; \ No newline at end of file + conditionalFilesMatched, + skipOverwrite +}; diff --git a/apps/generator/lib/renderer/react.js b/apps/generator/lib/renderer/react.js index ab139254a..1a21c203c 100644 --- a/apps/generator/lib/renderer/react.js +++ b/apps/generator/lib/renderer/react.js @@ -1,5 +1,8 @@ const path = require('path'); const AsyncReactSDK = require('@asyncapi/generator-react-sdk'); +const minimatch = require('minimatch'); +const logMessage = require('../logMessages.js'); +const log = require('loglevel'); const { writeFile } = require('../utils'); @@ -8,7 +11,7 @@ const reactExport = module.exports; /** * Configures React templating system, this handles all the transpilation work. - * + * * @private * @param {string} templateLocation located for thetemplate * @param {string} templateContentDir where the template content are located @@ -23,9 +26,9 @@ reactExport.configureReact = async (templateLocation, templateContentDir, transp /** * Renders the template with react and returns the content and meta data for the file. - * + * * @private - * @param {AsyncAPIDocument} asyncapiDocument + * @param {AsyncAPIDocument} asyncapiDocument * @param {string} filePath path to the template file * @param {Object} extraTemplateData Extra data to pass to the template. * @param {string} templateLocation located for thetemplate @@ -33,34 +36,34 @@ reactExport.configureReact = async (templateLocation, templateContentDir, transp * @param {string} transpiledTemplateLocation folder for the transpiled code * @param {Object} templateParams provided template parameters * @param {boolean} debug flag - * @param {string} originalAsyncAPI + * @param {string} originalAsyncAPI * @return {Promise} */ reactExport.renderReact = async (asyncapiDocument, filePath, extraTemplateData, templateLocation, templateContentDir, transpiledTemplateLocation, templateParams, debug, originalAsyncAPI) => { extraTemplateData = extraTemplateData || {}; filePath = filePath.replace(templateContentDir, path.resolve(templateLocation, transpiledTemplateLocation)); return await AsyncReactSDK.renderTemplate( - filePath, + filePath, { asyncapi: asyncapiDocument, params: templateParams, originalAsyncAPI, ...extraTemplateData - }, + }, debug ); }; /** * Save the single rendered react content based on the meta data available. - * + * * @private * @param {TemplateRenderResult} renderedContent the react content rendered * @param {String} outputPath Path to the file being rendered. */ -const saveContentToFile = async (renderedContent, outputPath) => { +const saveContentToFile = async (renderedContent, outputPath, noOverwriteGlobs = []) => { let filePath = outputPath; - // Might be the same as in the `fs` package, but is an active choice for our default file permission for any rendered files. + // Might be the same as in the `fs` package, but is an active choice for our default file permission for any rendered files. let permissions = 0o666; const content = renderedContent.content; @@ -78,21 +81,32 @@ const saveContentToFile = async (renderedContent, outputPath) => { } } - await writeFile(filePath, content, { - mode: permissions - }); + // get the final file name of the file + const finalFileName = path.basename(filePath); + // check whether the filename should be ignored based on user's inputs + const shouldOverwrite = !noOverwriteGlobs.some(globExp => minimatch(finalFileName, globExp)); + + // Write the file only if it should not be skipped + if (shouldOverwrite) { + await writeFile(filePath, content, { + mode: permissions + }); + } else { + await log.debug(logMessage.skipOverwrite(filePath)); + } }; /** * Save the rendered react content based on the meta data available. - * + * * @private * @param {TemplateRenderResult[] | TemplateRenderResult} renderedContent the react content rendered * @param {String} outputPath Path to the file being rendered. + * @param noOverwriteGlobs Array of globs to skip overwriting files. */ -reactExport.saveRenderedReactContent = async (renderedContent, outputPath) => { +reactExport.saveRenderedReactContent = async (renderedContent, outputPath, noOverwriteGlobs = []) => { if (Array.isArray(renderedContent)) { - return Promise.all(renderedContent.map(content => saveContentToFile(content, outputPath))); + return Promise.all(renderedContent.map(content => saveContentToFile(content, outputPath, noOverwriteGlobs))); } - return saveContentToFile(renderedContent, outputPath); + return await saveContentToFile(renderedContent, outputPath, noOverwriteGlobs); }; diff --git a/apps/generator/package.json b/apps/generator/package.json index dd0f8fc5d..284c2d9a8 100644 --- a/apps/generator/package.json +++ b/apps/generator/package.json @@ -15,9 +15,8 @@ "test": "npm run test:unit && npm run test:integration && npm run test:cli", "test:unit": "jest --coverage --testPathIgnorePatterns=integration --testPathIgnorePatterns=test-project", "test:dev": "npm run test:unit -- --watchAll", - "test:integration": "npm run test:cleanup && jest --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__'", - "test:integration:update": "jest --updateSnapshot --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__'", - "test:cli": "node cli.js ./test/docs/dummy.yml ./test/test-templates/react-template -o test/output --force-write --debug && test -e test/output/test-file.md", + "test:integration": "npm run test:cleanup && jest --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'", + "test:integration:update": "jest --updateSnapshot --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'", "test:cli": "node cli.js ./test/docs/dummy.yml ./test/test-templates/react-template -o test/output --force-write --debug && test -e test/output/test-file.md", "test:cleanup": "rimraf \"test/temp\"", "docs": "jsdoc2md --partial docs/jsdoc2md-handlebars/custom-sig-name.hbs docs/jsdoc2md-handlebars/main.hbs docs/jsdoc2md-handlebars/docs.hbs docs/jsdoc2md-handlebars/header.hbs docs/jsdoc2md-handlebars/defaultvalue.hbs docs/jsdoc2md-handlebars/link.hbs docs/jsdoc2md-handlebars/params-table.hbs --files lib/generator.js > docs/api.md", "docker:build": "docker build -t asyncapi/generator:latest .", diff --git a/apps/generator/test/integration.test.js b/apps/generator/test/integration.test.js index 81c9f4a67..d627ca9e7 100644 --- a/apps/generator/test/integration.test.js +++ b/apps/generator/test/integration.test.js @@ -2,7 +2,7 @@ * @jest-environment node */ -const { readFile } = require('fs').promises; +const { mkdir, writeFile, readFile } = require('fs').promises; const path = require('path'); const Generator = require('../lib/generator'); const dummySpecPath = path.resolve(__dirname, './docs/dummy.yml'); @@ -24,7 +24,7 @@ describe('Integration testing generateFromFile() to make sure the result of the it('generated using Nunjucks template', async () => { const outputDir = generateFolderName(); - const generator = new Generator(nunjucksTemplate, outputDir, { + const generator = new Generator(nunjucksTemplate, outputDir, { forceWrite: true, templateParams: { version: 'v1', mode: 'production' } }); @@ -35,7 +35,7 @@ describe('Integration testing generateFromFile() to make sure the result of the it('generate using React template', async () => { const outputDir = generateFolderName(); - const generator = new Generator(reactTemplate, outputDir, { + const generator = new Generator(reactTemplate, outputDir, { forceWrite: true , templateParams: { version: 'v1', mode: 'production' } }); @@ -55,4 +55,33 @@ describe('Integration testing generateFromFile() to make sure the result of the const file = await readFile(path.join(outputDir, testOutputFile), 'utf8'); expect(file).toMatchSnapshot(); }); + + it('should ignore specified files with noOverwriteGlobs', async () => { + const outputDir = generateFolderName(); + // Manually create a file to test if it's not overwritten + await mkdir(outputDir, { recursive: true }); + // Create a variable to store the file content + const testContent = ''; + // eslint-disable-next-line sonarjs/no-duplicate-string + const testFilePath = path.normalize(path.resolve(outputDir, testOutputFile)); + await writeFile(testFilePath, testContent); + + // Manually create an output first, before generation, with additional custom file to validate if later it is still there, not overwritten + const generator = new Generator(reactTemplate, outputDir, { + forceWrite: true, + noOverwriteGlobs: [`**/${testOutputFile}`], + debug: true, + }); + + await generator.generateFromFile(dummySpecPath); + + // Read the file to confirm it was not overwritten + const fileContent = await readFile(testFilePath, 'utf8'); + // Check if the files have been overwritten + expect(fileContent).toBe(testContent); + // Check if the log debug message was printed + /*TODO: + Include log message test in the future to ensure that the log.debug for skipping overwrite is called + */ + }); }); From 8501f8d7264942246ba6417fd1361709a9ab93ac Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Wed, 31 Jul 2024 15:49:08 +0200 Subject: [PATCH 4/5] chore(release): release and bump versions of packages (#1241) --- .changeset/enable_noOverwriteGlobs.md | 5 ----- apps/generator/CHANGELOG.md | 6 ++++++ apps/generator/package.json | 5 +++-- 3 files changed, 9 insertions(+), 7 deletions(-) delete mode 100644 .changeset/enable_noOverwriteGlobs.md diff --git a/.changeset/enable_noOverwriteGlobs.md b/.changeset/enable_noOverwriteGlobs.md deleted file mode 100644 index b9e40ab44..000000000 --- a/.changeset/enable_noOverwriteGlobs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@asyncapi/generator": minor ---- - -Enable `noOverwriteGlobs` option for templates based on react rendering engine. diff --git a/apps/generator/CHANGELOG.md b/apps/generator/CHANGELOG.md index 635a5a223..e6a67972f 100644 --- a/apps/generator/CHANGELOG.md +++ b/apps/generator/CHANGELOG.md @@ -1,5 +1,11 @@ # @asyncapi/generator +## 2.2.0 + +### Minor Changes + +- 81dfd0c: Enable `noOverwriteGlobs` option for templates based on react rendering engine. + ## 2.1.3 ### Patch Changes diff --git a/apps/generator/package.json b/apps/generator/package.json index 284c2d9a8..2f3ee8c29 100644 --- a/apps/generator/package.json +++ b/apps/generator/package.json @@ -1,6 +1,6 @@ { "name": "@asyncapi/generator", - "version": "2.1.3", + "version": "2.2.0", "description": "The AsyncAPI generator. It can generate documentation, code, anything!", "main": "./lib/generator.js", "bin": { @@ -16,7 +16,8 @@ "test:unit": "jest --coverage --testPathIgnorePatterns=integration --testPathIgnorePatterns=test-project", "test:dev": "npm run test:unit -- --watchAll", "test:integration": "npm run test:cleanup && jest --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'", - "test:integration:update": "jest --updateSnapshot --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'", "test:cli": "node cli.js ./test/docs/dummy.yml ./test/test-templates/react-template -o test/output --force-write --debug && test -e test/output/test-file.md", + "test:integration:update": "jest --updateSnapshot --testPathPattern=integration --modulePathIgnorePatterns='./__mocks__(?!\\/loglevel\\.js$)'", + "test:cli": "node cli.js ./test/docs/dummy.yml ./test/test-templates/react-template -o test/output --force-write --debug && test -e test/output/test-file.md", "test:cleanup": "rimraf \"test/temp\"", "docs": "jsdoc2md --partial docs/jsdoc2md-handlebars/custom-sig-name.hbs docs/jsdoc2md-handlebars/main.hbs docs/jsdoc2md-handlebars/docs.hbs docs/jsdoc2md-handlebars/header.hbs docs/jsdoc2md-handlebars/defaultvalue.hbs docs/jsdoc2md-handlebars/link.hbs docs/jsdoc2md-handlebars/params-table.hbs --files lib/generator.js > docs/api.md", "docker:build": "docker build -t asyncapi/generator:latest .", From b093dbc2072cc54b079491171f067e4ae4a8be5d Mon Sep 17 00:00:00 2001 From: Ayush Nautiyal <78146753+ayushnau@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:22:41 +0530 Subject: [PATCH 5/5] chore: update the readme file path for docker hub (#1243) Co-authored-by: Lukasz Gornicki --- .github/workflows/release-docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index 93f6615eb..69017e23c 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -54,4 +54,5 @@ jobs: user: ${{ secrets.DOCKER_USERNAME }} pass: ${{ secrets.DOCKER_PASSWORD }} slug: asyncapi/generator + readme: ../../README.md description: Use your AsyncAPI definition to generate literally anything. Markdown documentation, Node.js code, HTML documentation, anything!