From 8585eacd7dd2dccb64675cc002a648a2d153e8aa Mon Sep 17 00:00:00 2001 From: Rachael Sewell Date: Thu, 30 Mar 2023 14:50:17 -0700 Subject: [PATCH] fix markdown content generation in codeql cli manual pages (#36014) --- .../lib/update-markdown.js | 21 +++++++++++++---- .../scripts/convert-markdown-for-docs.js | 23 +++++++++++++++++++ src/codeql-cli/scripts/sync.js | 8 +++---- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/automated-pipelines/lib/update-markdown.js b/src/automated-pipelines/lib/update-markdown.js index c675ccd509..68b07a1857 100644 --- a/src/automated-pipelines/lib/update-markdown.js +++ b/src/automated-pipelines/lib/update-markdown.js @@ -87,14 +87,27 @@ async function updateMarkdownFile( // update only the versions property of the file, assuming // the other properties have already been added and edited const { data, content } = matter(await readFile(file, 'utf-8')) - if (isEqual(sourceData.versions, data.versions)) { + + // Double check that the comment delimiter is only used once + const matcher = new RegExp(commentDelimiter, 'g') + const matches = content.match(matcher) + if (matches && matches.length > 1) { + throw new Error(`Error: ${file} has multiple comment delimiters`) + } + + // Only proceed if the content or versions have changed + const [manuallyCreatedContent, automatedContent] = content.split(commentDelimiter) + const isContentSame = automatedContent === sourceContent + const isVersionsSame = isEqual(sourceData.versions, data.versions) + if (isContentSame && isVersionsSame) { return } + + // Create a new object so that we don't mutate the original data const newData = { ...data } - // Keep all frontmatter currently in the Markdown file on disk - // except replace the versions property with the new versions + // Only modify the versions property when a file already existss newData.versions = sourceData.versions - const targetContent = content.replace(commentDelimiter, sourceContent) + const targetContent = manuallyCreatedContent + commentDelimiter + sourceContent await writeFile(file, matter.stringify(targetContent, newData)) } else { await createDirectory(path.dirname(file)) diff --git a/src/codeql-cli/scripts/convert-markdown-for-docs.js b/src/codeql-cli/scripts/convert-markdown-for-docs.js index 3813f63a68..4e535c1d29 100644 --- a/src/codeql-cli/scripts/convert-markdown-for-docs.js +++ b/src/codeql-cli/scripts/convert-markdown-for-docs.js @@ -174,6 +174,29 @@ export async function convertContentToDocs(content, frontmatterDefaults = {}) { if (node.type === 'link' && node.url.includes('aka.ms')) { akaMsLinkMatches.push(node) } + + // There are example links in the format https://containers.GHEHOSTNAME + // that we don't want our link checker to check so we need to make them + // inline code instead of links. Ideally, this should be done in the + // Java program that generates the rst files, but we can do it here for now. + // See https://github.com/syntax-tree/mdast#inlinecode + if (node.type === 'link' && node.url.startsWith('https://containers')) { + // The nodes before and after contain double quotes that we want to remove + const nodeBefore = ancestors[ancestors.length - 1].children[0] + const nodeAfter = ancestors[ancestors.length - 1].children[2] + if (nodeBefore.value.endsWith('"')) { + nodeBefore.value = nodeBefore.value.slice(0, -1) + } + if (nodeAfter.value.startsWith('"')) { + nodeAfter.value = nodeAfter.value.slice(1) + } + // Change the node to an inline code node + node.type = 'inlineCode' + node.value = node.url + node.title = undefined + node.url = undefined + node.children = undefined + } }) // Convert all aka.ms links to the docs.github.com relative path diff --git a/src/codeql-cli/scripts/sync.js b/src/codeql-cli/scripts/sync.js index 76889b87d1..cb9779a605 100755 --- a/src/codeql-cli/scripts/sync.js +++ b/src/codeql-cli/scripts/sync.js @@ -9,10 +9,7 @@ import path from 'path' import matter from 'gray-matter' import rimraf from 'rimraf' -import { - updateContentDirectory, - MARKDOWN_COMMENT, -} from '../../automated-pipelines/lib/update-markdown.js' +import { updateContentDirectory } from '../../automated-pipelines/lib/update-markdown.js' import { convertContentToDocs } from './convert-markdown-for-docs.js' const { targetDirectory, sourceDirectory, frontmatterDefaults, markdownPrefix } = JSON.parse( @@ -20,6 +17,7 @@ const { targetDirectory, sourceDirectory, frontmatterDefaults, markdownPrefix } ) const SOURCE_REPO = sourceDirectory.split('/')[0] const TEMP_DIRECTORY = path.join(SOURCE_REPO, 'tempCliDocs') +const MARKDOWN_PREFIX = `${markdownPrefix}\n\n` main() @@ -41,7 +39,7 @@ async function main() { await writeFile(file, matter.stringify(content, data)) const targetFilename = path.join(targetDirectory, path.basename(file)) const sourceData = { ...data, ...frontmatterDefaults } - const finalSourceContent = MARKDOWN_COMMENT + `${markdownPrefix}\n\n` + content + const finalSourceContent = MARKDOWN_PREFIX + content cliMarkdownContents[targetFilename] = { data: sourceData, content: finalSourceContent } } // Begin updating Markdown files in the content directory