From 9c8a25b61350011f69ef58fe4cc34e93841a427d Mon Sep 17 00:00:00 2001 From: Vitalii Perehonchuk Date: Thu, 23 Nov 2023 17:40:21 +0200 Subject: [PATCH] fix: loop exit cond --- .github/workflows/spellcheck.yml | 9 +- scripts/send-comments.js | 200 +++++++++++++++++-------------- 2 files changed, 116 insertions(+), 93 deletions(-) diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index dbeb16c5e1..96de2c7105 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -70,15 +70,16 @@ jobs: name: Convert markdown to plain text run: | file=${{ needs.prepare-translation.outputs.translation }} + tmpHtmlFile=$(echo $file | sed 's/\.md/\.html/') + pandoc -f markdown -t html -o $tmpHtmlFile $file newFileName=$(echo $file | sed 's/\.md/\.txt/') - pandoc -f markdown -t plain -o $newFileName $file + pandoc -f html -t plain -o $newFileName $tmpHtmlFile echo "translation=$newFileName" >> $GITHUB_OUTPUT echo $newFileName - # Error if translation file is not found - if: steps.md2txt.outputs.translation == '' name: Check translation is found run: echo "No translation file found" && exit 1 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: "temurin" java-version: "8" @@ -98,6 +99,7 @@ jobs: run: | cd LanguageTool-6.3 java -jar languagetool-commandline.jar -d ${{steps.disabled-rules.outputs.disabled_rules}} -l uk --json ../${{ steps.md2txt.outputs.translation }} > ../result.json + cat ../result.json matches=$(cat ../result.json | jq '.matches') # Check if matches equal [] echo "has_matches=$(if [ "$matches" == "[]" ]; then echo "false"; else echo "true"; fi)" >> $GITHUB_OUTPUT @@ -142,5 +144,6 @@ jobs: PR_NUMBER: ${{ github.event.pull_request.number }} name: Send results run: node scripts/send-comments.js ${{ needs.prepare-translation.outputs.translation }} + timeout-minutes: 5 - name: Exit with error run: echo "Spelling errors found" && cat result.json && exit 1 diff --git a/scripts/send-comments.js b/scripts/send-comments.js index 1f4a3e0973..9404d39b76 100644 --- a/scripts/send-comments.js +++ b/scripts/send-comments.js @@ -1,24 +1,12 @@ import { execSync } from "child_process"; import { readFileSync } from "fs"; -const results = JSON.parse(readFileSync("./result.json")); -const MARKDOWN_FILE_ARG_INDEX = 2; -/** - * @type {Record} - */ -const mapping = JSON.parse(readFileSync("./mapping.json")); -const markdownFile = process.argv[MARKDOWN_FILE_ARG_INDEX]; -const markdown = readFileSync(markdownFile, "utf8"); - -const markdownRunes = Array.from(markdown); - const MARKDOWN_ESCAPE_REGEX = /([!"#'()*+.[\\\]_`{}-])/g; - function escapeTextForMarkdown(text) { return text.replaceAll(MARKDOWN_ESCAPE_REGEX, "\\$1"); } -function convertOffsetToLineAndColumn(offset) { +function convertOffsetToLineAndColumn(markdownRunes, offset) { let line = 1; let column = 1; for (let index = 0; index < offset; index += 1) { @@ -32,86 +20,118 @@ function convertOffsetToLineAndColumn(offset) { } return [line, column]; } +try { + const results = JSON.parse(readFileSync("./result.json")); + const MARKDOWN_FILE_ARG_INDEX = 2; + /** + * @type {Record} + */ + const mapping = JSON.parse(readFileSync("./mapping.json")); + const markdownFile = process.argv[MARKDOWN_FILE_ARG_INDEX]; + const markdown = readFileSync(markdownFile, "utf8"); -// eslint-disable-next-line no-restricted-syntax -for (const match of results.matches) { - const { context, message, replacements, rule, sentence, shortMessage } = - match; - let { length, offset } = match; - let start; - length += 1; - while (!start) { - offset += 1; - length -= 1; - start = Number.parseInt(mapping[offset], 10); - } - let endOffset = offset + length; - let end; - endOffset -= 1; - length -= 1; - while (!end) { - endOffset += 1; + const markdownRunes = Array.from(markdown); + + const TOTAL_TIMEOUT = 180_000; + const timeout = setTimeout(() => { + throw new Error("Timeout"); + }, TOTAL_TIMEOUT); + const mappingMaxOffset = Math.max(...Object.keys(mapping)); + + // eslint-disable-next-line no-restricted-syntax + for (const match of results.matches) { + const { context, message, replacements, rule, sentence, shortMessage } = + match; + let { length, offset } = match; + let start; length += 1; - end = Number.parseInt(mapping[endOffset], 10); - } - console.error(start, end); - const [startLine, startColumn] = convertOffsetToLineAndColumn(start); - const [endLine, endColumn] = convertOffsetToLineAndColumn(end); - if (endLine < startLine) { - console.error(startLine, endLine); - throw new Error(`Line not found in source file: ${sentence}`); - } - if (endLine === startLine && endColumn < startColumn) { - console.error(startColumn, endColumn); - throw new Error(`Column not found in source file: ${sentence}`); - } - // const errorformatLine = `${markdownFile}:${startLine}:${startColumn}:${endLine}:${endColumn}: ${message}`; - let comment = ""; - if (shortMessage || rule.description) { - comment += `### ${escapeTextForMarkdown( - shortMessage || rule.description, - )}\n\n`; - } - comment += `${escapeTextForMarkdown(message)}\n${rule.category.id}/${ - rule.id - }: ${escapeTextForMarkdown(rule.description)}\n`; - // console.log(`\`${markdownFile}:${startLine}:${startColumn}\n\``); - comment += `> ${escapeTextForMarkdown( - context.text.slice(0, context.offset), - )}**${escapeTextForMarkdown( - context.text.slice(context.offset, context.offset + context.length), - )}**${escapeTextForMarkdown( - context.text.slice(context.offset + context.length), - )}`; - if (replacements?.length) { - comment += "\n\n#### Варіанти заміни\n"; + while (!start && offset <= mappingMaxOffset) { + offset += 1; + length -= 1; + start = Number.parseInt(mapping[offset], 10); + } + let endOffset = offset + length; + let end; + endOffset -= 1; + length -= 1; + while (!end && endOffset <= mappingMaxOffset) { + endOffset += 1; + length += 1; + end = Number.parseInt(mapping[endOffset], 10); + } + console.error(start, end); + const [startLine, startColumn] = convertOffsetToLineAndColumn( + markdownRunes, + start, + ); + const [endLine, endColumn] = convertOffsetToLineAndColumn( + markdownRunes, + end, + ); + if (endLine < startLine) { + console.error(startLine, endLine); + throw new Error(`Line not found in source file: ${sentence}`); + } + if (endLine === startLine && endColumn < startColumn) { + console.error(startColumn, endColumn); + throw new Error(`Column not found in source file: ${sentence}`); + } + // const errorformatLine = `${markdownFile}:${startLine}:${startColumn}:${endLine}:${endColumn}: ${message}`; + let comment = ""; + if (shortMessage || rule.description) { + comment += `### ${escapeTextForMarkdown( + shortMessage || rule.description, + )}\n\n`; + } + comment += `${escapeTextForMarkdown(message)}\n${rule.category.id}/${ + rule.id + }: ${escapeTextForMarkdown(rule.description)}\n`; + // console.log(`\`${markdownFile}:${startLine}:${startColumn}\n\``); + comment += `> ${escapeTextForMarkdown( + context.text.slice(0, context.offset), + )}**${escapeTextForMarkdown( + context.text.slice(context.offset, context.offset + context.length), + )}**${escapeTextForMarkdown( + context.text.slice(context.offset + context.length), + )}`; + if (replacements?.length) { + comment += "\n\n#### Варіанти заміни\n"; + // eslint-disable-next-line no-restricted-syntax + for (const replacement of replacements) { + // console.log(`- ${replacement.value}`); + comment += `- ${escapeTextForMarkdown(replacement.value)}\n`; + } + } + const parameters = { + body: comment, + commit_id: process.env.COMMIT_ID, + line: endLine, + path: markdownFile, + side: "RIGHT", + }; + if (startLine !== endLine) { + parameters.start_line = startLine; + parameters.start_side = "RIGHT"; + } + let command = `gh api repos/${process.env.GITHUB_REPOSITORY}/pulls/${process.env.PR_NUMBER}/comments`; // eslint-disable-next-line no-restricted-syntax - for (const replacement of replacements) { - // console.log(`- ${replacement.value}`); - comment += `- ${escapeTextForMarkdown(replacement.value)}\n`; + for (const [key, value] of Object.entries(parameters)) { + command += + typeof value === "number" + ? ` -F ${key}=${value}` + : ` -f ${key}="${value}"`; } + console.log(command); + // command = command.replaceAll("\n", "\\\n"); + console.log(`GH_TOKEN=${process.env.GH_TOKEN} ${command}`); + execSync(command, { stdio: "inherit", timeout: 60_000 }); } - const parameters = { - body: comment, - commit_id: process.env.COMMIT_ID, - line: endLine, - path: markdownFile, - side: "RIGHT", - }; - if (startLine !== endLine) { - parameters.start_line = startLine; - parameters.start_side = "RIGHT"; - } - let command = `gh api repos/${process.env.GITHUB_REPOSITORY}/pulls/${process.env.PR_NUMBER}/comments`; - // eslint-disable-next-line no-restricted-syntax - for (const [key, value] of Object.entries(parameters)) { - command += - typeof value === "number" - ? ` -F ${key}=${value}` - : ` -f ${key}="${value}"`; - } - console.log(command); - // command = command.replaceAll("\n", "\\\n"); - console.log(`GH_TOKEN=${process.env.GH_TOKEN} ${command}`); - execSync(command, { stdio: "inherit" }); + clearTimeout(timeout); +} catch (error) { + console.error(error); + process.exit(1); } +process.on("unhandledRejection", (error) => { + console.error(error); + process.exit(1); +});