diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e9098e1..4b3810c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [4.34.3](https://github.com/diplodoc-platform/cli/compare/v4.34.2...v4.34.3) (2024-07-18) + + +### Bug Fixes + +* retry parsing existing metadata with duplicate key compatibility ([d1eff78](https://github.com/diplodoc-platform/cli/commit/d1eff78c0210765933b76ee1cf173966bcdc658a)) + ## [4.34.2](https://github.com/diplodoc-platform/cli/compare/v4.34.1...v4.34.2) (2024-07-15) diff --git a/package-lock.json b/package-lock.json index 82964110..db22da66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@diplodoc/cli", - "version": "4.34.2", + "version": "4.34.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@diplodoc/cli", - "version": "4.34.2", + "version": "4.34.3", "license": "MIT", "dependencies": { "@diplodoc/client": "^2.6.2", diff --git a/package.json b/package.json index ca2cdb85..bfffc7fe 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "author": "Yandex Data UI Team ", "description": "Make documentation using yfm-docs in Markdown and HTML formats", "license": "MIT", - "version": "4.34.2", + "version": "4.34.3", "repository": { "type": "git", "url": "git@github.com:diplodoc-platform/cli.git" diff --git a/src/services/metadata/addSourcePath.ts b/src/services/metadata/addSourcePath.ts index f54155bc..d29f0752 100644 --- a/src/services/metadata/addSourcePath.ts +++ b/src/services/metadata/addSourcePath.ts @@ -2,7 +2,7 @@ import {parseExistingMetadata} from './parse'; import {emplaceMetadata} from './utils'; export const addSourcePath = (fileContent: string, sourcePath: string) => { - const {metadata, metadataStrippedContent} = parseExistingMetadata(fileContent); + const {metadata, metadataStrippedContent} = parseExistingMetadata(fileContent, sourcePath); return emplaceMetadata(metadataStrippedContent, { ...metadata, diff --git a/src/services/metadata/enrich.ts b/src/services/metadata/enrich.ts index 8d2c74a3..433140e2 100644 --- a/src/services/metadata/enrich.ts +++ b/src/services/metadata/enrich.ts @@ -30,7 +30,11 @@ export const enrichWithFrontMatter = async ({ }: EnrichWithFrontMatterOptions) => { const {systemVars, metadataVars} = resolvedFrontMatterVars; const {resources, addSystemMeta, shouldAlwaysAddVCSPath, pathData} = metadataOptions; - const {metadata, metadataStrippedContent} = parseExistingMetadata(fileContent); + + const {metadata, metadataStrippedContent} = parseExistingMetadata( + fileContent, + pathData.pathToFile, + ); const vcsFrontMatter = metadataOptions.isContributorsEnabled ? await resolveVCSFrontMatter(metadata, metadataOptions, fileContent) diff --git a/src/services/metadata/parse.ts b/src/services/metadata/parse.ts index 1d360055..cb3a3b86 100644 --- a/src/services/metadata/parse.ts +++ b/src/services/metadata/parse.ts @@ -1,5 +1,6 @@ -import {dump, load} from 'js-yaml'; +import {YAMLException, dump, load} from 'js-yaml'; import {metadataBorder} from '../../constants'; +import {logger} from '../../utils'; export type FileMetadata = { [key: string]: unknown; @@ -33,6 +34,31 @@ const matchMetadata = (fileContent: string) => { return regexpParseFileContent.exec(fileContent); }; +const duplicateKeysCompatibleLoad = (yaml: string, filePath: string | undefined) => { + try { + return load(yaml); + } catch (e) { + if (e instanceof YAMLException) { + const duplicateKeysDeprecationWarning = ` + Encountered a YAML parsing exception when processing file metadata: ${e.reason}. + It's highly possible the input file contains duplicate mapping keys. + Will retry processing with necessary compatibility flags. + Please note that this behaviour is DEPRECATED and WILL be removed in a future version + without further notice, so the build WILL fail when supplied with YAML-incompatible meta. + ` + .replace(/^\s+/gm, '') + .replace(/\n/g, ' ') + .trim(); + + logger.warn(filePath ?? '', duplicateKeysDeprecationWarning); + + return load(yaml, {json: true}); + } + + throw e; + } +}; + /** * Temporary workaround to enable parsing YAML metadata from potentially * Liquid-aware source files @@ -52,14 +78,20 @@ const escapeLiquidSubstitutionSyntax = (content: string): string => const unescapeLiquidSubstitutionSyntax = (escapedContent: string): string => escapedContent.replace(/\(\({{/g, '{{').replace(/}}\)\)/g, '}}'); -export const parseExistingMetadata = (fileContent: string): ParseExistingMetadataReturn => { +export const parseExistingMetadata = ( + fileContent: string, + filePath?: string, +): ParseExistingMetadataReturn => { const matches = matchMetadata(fileContent); if (matches && matches.length > 0) { const [, metadata, , metadataStrippedContent] = matches; return { - metadata: load(escapeLiquidSubstitutionSyntax(metadata)) as FileMetadata, + metadata: duplicateKeysCompatibleLoad( + escapeLiquidSubstitutionSyntax(metadata), + filePath, + ) as FileMetadata, metadataStrippedContent, }; }