From da8d082ce027df0448917a1b77f0b8858a8176eb Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 16 Jan 2020 01:25:55 +0800 Subject: [PATCH] Add changelog lint script (#7320) * Add changelog lint script * Refactor lint script * spell * Fix indent * fix templateComment * add H4 check * Add category in title check * use array destructuring * Add space check --- .azure-pipelines/jobs/dev-lint.yml | 2 + changelog_unreleased/cli/pr-7210.md | 2 +- changelog_unreleased/handlebars/pr-7051.md | 2 +- changelog_unreleased/handlebars/pr-7157.md | 2 +- changelog_unreleased/javascript/pr-6984.md | 2 +- .../javascript/{pr-7003.md => pr-7010.md} | 0 changelog_unreleased/javascript/pr-7070.md | 2 +- changelog_unreleased/javascript/pr-7140.md | 2 +- changelog_unreleased/mdx/pr-6398.md | 2 +- changelog_unreleased/typescript/pr-7075.md | 2 +- changelog_unreleased/typescript/pr-7094.md | 2 +- changelog_unreleased/typescript/pr-7144.md | 2 +- .../typescript/{pr-7174.md => pr-7221.md} | 0 changelog_unreleased/vue/pr-7180.md | 2 +- cspell.json | 1 + package.json | 1 + scripts/lint-changelog.js | 131 ++++++++++++++++++ 17 files changed, 146 insertions(+), 11 deletions(-) rename changelog_unreleased/javascript/{pr-7003.md => pr-7010.md} (100%) rename changelog_unreleased/typescript/{pr-7174.md => pr-7221.md} (100%) create mode 100644 scripts/lint-changelog.js diff --git a/.azure-pipelines/jobs/dev-lint.yml b/.azure-pipelines/jobs/dev-lint.yml index 76f4fd4f3..1d72f61ca 100644 --- a/.azure-pipelines/jobs/dev-lint.yml +++ b/.azure-pipelines/jobs/dev-lint.yml @@ -11,3 +11,5 @@ steps: displayName: "Lint docs" - script: yarn spellcheck displayName: "Spellcheck" + - script: yarn lint-changelog + displayName: "Lint changelog" diff --git a/changelog_unreleased/cli/pr-7210.md b/changelog_unreleased/cli/pr-7210.md index 71a0b1fce..c05a53969 100644 --- a/changelog_unreleased/cli/pr-7210.md +++ b/changelog_unreleased/cli/pr-7210.md @@ -1,4 +1,4 @@ -#### Support file extensions `.cjs` and `.yaml.sed`([#7210](https://github.com/prettier/prettier/pull/7210) by [@sosukesuzuki](https://github.com/sosukesuzuki)) +#### Support file extensions `.cjs` and `.yaml.sed` ([#7210](https://github.com/prettier/prettier/pull/7210) by [@sosukesuzuki](https://github.com/sosukesuzuki)) ```sh # Prettier stable diff --git a/changelog_unreleased/handlebars/pr-7051.md b/changelog_unreleased/handlebars/pr-7051.md index 4318eed57..ac9a7cb9d 100644 --- a/changelog_unreleased/handlebars/pr-7051.md +++ b/changelog_unreleased/handlebars/pr-7051.md @@ -1,4 +1,4 @@ -#### handlebars: Fix superfluous line breaks in ConcatStatement ([7051](https://github.com/prettier/prettier/pull/7051) by [@dcyriller](https://github.com/dcyriller)) +#### Fix superfluous line breaks in ConcatStatement ([#7051](https://github.com/prettier/prettier/pull/7051) by [@dcyriller](https://github.com/dcyriller)) ```hbs diff --git a/changelog_unreleased/handlebars/pr-7157.md b/changelog_unreleased/handlebars/pr-7157.md index 6da450df9..03808ddb6 100644 --- a/changelog_unreleased/handlebars/pr-7157.md +++ b/changelog_unreleased/handlebars/pr-7157.md @@ -1,4 +1,4 @@ -#### handlebars: Improve MustacheStatement printing ([#7157](https://github.com/prettier/prettier/pull/7157) by [@dcyriller](https://github.com/dcyriller)) +#### Improve MustacheStatement printing ([#7157](https://github.com/prettier/prettier/pull/7157) by [@dcyriller](https://github.com/dcyriller)) ```hbs diff --git a/changelog_unreleased/javascript/pr-6984.md b/changelog_unreleased/javascript/pr-6984.md index 854baa2d8..18d45dbc1 100644 --- a/changelog_unreleased/javascript/pr-6984.md +++ b/changelog_unreleased/javascript/pr-6984.md @@ -1,4 +1,4 @@ -#### Fix formatting of labeled statements with comments ([#6994](https://github.com/prettier/prettier/pull/6984) by [@clement26695](https://github.com/clement26695)) +#### Fix formatting of labeled statements with comments ([#6984](https://github.com/prettier/prettier/pull/6984) by [@clement26695](https://github.com/clement26695)) Formatting of comments in labeled statements was not stable diff --git a/changelog_unreleased/javascript/pr-7003.md b/changelog_unreleased/javascript/pr-7010.md similarity index 100% rename from changelog_unreleased/javascript/pr-7003.md rename to changelog_unreleased/javascript/pr-7010.md diff --git a/changelog_unreleased/javascript/pr-7070.md b/changelog_unreleased/javascript/pr-7070.md index b2339474c..96d3aa80c 100644 --- a/changelog_unreleased/javascript/pr-7070.md +++ b/changelog_unreleased/javascript/pr-7070.md @@ -1,4 +1,4 @@ -# Format `throw` like `return` ([#7070](https://github.com/prettier/prettier/pull/7070) by [@sosukesuzuki](https://github.com/sosukesuzuki)) +#### Format `throw` like `return` ([#7070](https://github.com/prettier/prettier/pull/7070) by [@sosukesuzuki](https://github.com/sosukesuzuki)) ```js diff --git a/changelog_unreleased/javascript/pr-7140.md b/changelog_unreleased/javascript/pr-7140.md index d2fa480bc..cd4047758 100644 --- a/changelog_unreleased/javascript/pr-7140.md +++ b/changelog_unreleased/javascript/pr-7140.md @@ -1,4 +1,4 @@ -#### Fix moving semi for `return` to end of line-comment([#7140](https://github.com/prettier/prettier/pull/7140) by [@sosukesuzuki](https://github.com/sosukesuzuki)) +#### Fix moving semi for `return` to end of line-comment ([#7140](https://github.com/prettier/prettier/pull/7140) by [@sosukesuzuki](https://github.com/sosukesuzuki)) ```js diff --git a/changelog_unreleased/mdx/pr-6398.md b/changelog_unreleased/mdx/pr-6398.md index 8d04c8294..6d7a88374 100644 --- a/changelog_unreleased/mdx/pr-6398.md +++ b/changelog_unreleased/mdx/pr-6398.md @@ -1,4 +1,4 @@ -#### MDX: fix JSX Fragment format incorrectly ([#6398](https://github.com/prettier/prettier/pull/6398) by [@JounQin](https://github.com/JounQin)) +#### Fix JSX Fragment format incorrectly ([#6398](https://github.com/prettier/prettier/pull/6398) by [@JounQin](https://github.com/JounQin)) Previous versions format JSX Fragment incorrectly in mdx, this has been fixed in this version. diff --git a/changelog_unreleased/typescript/pr-7075.md b/changelog_unreleased/typescript/pr-7075.md index 144b32b07..9d8351dc8 100644 --- a/changelog_unreleased/typescript/pr-7075.md +++ b/changelog_unreleased/typescript/pr-7075.md @@ -1,4 +1,4 @@ -#### Don't print trailing commas after rest elements in tuples ([#7075](https://github.com/prettier/prettier/pull/7075) by [@thorn](https://github.com/thorn0)) +#### Don't print trailing commas after rest elements in tuples ([#7075](https://github.com/prettier/prettier/pull/7075) by [@thorn0](https://github.com/thorn0)) - A rest element is always the last element of a tuple type. Nothing can be added after it. - While TS is okay with this comma, [Babel doesn't parse it](https://github.com/babel/babel/issues/10769) diff --git a/changelog_unreleased/typescript/pr-7094.md b/changelog_unreleased/typescript/pr-7094.md index ee30e2bf4..08797e235 100644 --- a/changelog_unreleased/typescript/pr-7094.md +++ b/changelog_unreleased/typescript/pr-7094.md @@ -1,4 +1,4 @@ -#### Remove extra indentation for arrow function on variable declaration with comment([#7094](https://github.com/prettier/prettier/pull/7094) by [@sosukesuzuki](https://github.com/sosukesuzuki)) +#### Remove extra indentation for arrow function on variable declaration with comment ([#7094](https://github.com/prettier/prettier/pull/7094) by [@sosukesuzuki](https://github.com/sosukesuzuki)) ```ts diff --git a/changelog_unreleased/typescript/pr-7144.md b/changelog_unreleased/typescript/pr-7144.md index 73859bfb2..d508dbc5c 100644 --- a/changelog_unreleased/typescript/pr-7144.md +++ b/changelog_unreleased/typescript/pr-7144.md @@ -1,4 +1,4 @@ -#### Fix formatting comments for function-like nodes ([#6901](https://github.com/prettier/prettier/pull/7144) by [@armano2](https://github.com/armano2)) +#### Fix formatting comments for function-like nodes ([#7144](https://github.com/prettier/prettier/pull/7144) by [@armano2](https://github.com/armano2)) ```ts diff --git a/changelog_unreleased/typescript/pr-7174.md b/changelog_unreleased/typescript/pr-7221.md similarity index 100% rename from changelog_unreleased/typescript/pr-7174.md rename to changelog_unreleased/typescript/pr-7221.md diff --git a/changelog_unreleased/vue/pr-7180.md b/changelog_unreleased/vue/pr-7180.md index 36f957eea..cbd3958c4 100644 --- a/changelog_unreleased/vue/pr-7180.md +++ b/changelog_unreleased/vue/pr-7180.md @@ -1,4 +1,4 @@ -#### format vue SFC containing JSX script([#7180](https://github.com/prettier/prettier/pull/7180) by [@sosukesuzuki](https://github.com/sosukesuzuki)) +#### format vue SFC containing JSX script ([#7180](https://github.com/prettier/prettier/pull/7180) by [@sosukesuzuki](https://github.com/sosukesuzuki)) ```html diff --git a/cspell.json b/cspell.json index 44bb5ded4..bae5da214 100644 --- a/cspell.json +++ b/cspell.json @@ -122,6 +122,7 @@ "gitattributes", "githook", "gitignore", + "gitkeep", "Gitter", "glimmerjs", "globbing", diff --git a/package.json b/package.json index 9bbc7e0f9..9fac74dbe 100644 --- a/package.json +++ b/package.json @@ -122,6 +122,7 @@ "perf-benchmark": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-benchmark --loglevel debug ${PERF_FILE:-./index.js} > /dev/null", "check-types": "tsc", "lint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly", + "lint-changelog": "node ./scripts/lint-changelog.js", "lint-docs": "prettier {.,docs,website,website/blog,changelog_unreleased,changelog_unreleased/*}/*.md --check", "lint-dist": "eslint --no-eslintrc --no-ignore --env=browser \"dist/!(bin-prettier|index|third-party).js\"", "build": "node --max-old-space-size=3072 ./scripts/build/build.js", diff --git a/scripts/lint-changelog.js b/scripts/lint-changelog.js new file mode 100644 index 000000000..54cd2600f --- /dev/null +++ b/scripts/lint-changelog.js @@ -0,0 +1,131 @@ +"use strict"; +const fs = require("fs"); +const path = require("path"); + +const CHANGELOG_DIR = "changelog_unreleased"; +const TEMPLATE_FILE = "TEMPLATE.md"; +const CHANGELOG_CATEGORIES = [ + "angular", + "api", + "cli", + "css", + "flow", + "graphql", + "handlebars", + "html", + "javascript", + "json", + "less", + "lwc", + "markdown", + "mdx", + "scss", + "typescript", + "vue", + "yaml" +]; +const CHANGELOG_ROOT = path.join(__dirname, `../${CHANGELOG_DIR}`); +const showErrorMessage = message => { + console.error(message); + process.exitCode = 1; +}; + +const files = fs.readdirSync(CHANGELOG_ROOT); +for (const file of files) { + if (file !== TEMPLATE_FILE && !CHANGELOG_CATEGORIES.includes(file)) { + showErrorMessage(`Please remove "${file}" from "${CHANGELOG_DIR}".`); + } +} +for (const file of [TEMPLATE_FILE, ...CHANGELOG_CATEGORIES]) { + if (!files.includes(file)) { + showErrorMessage(`Please don't remove "${file}" from "${CHANGELOG_DIR}".`); + } +} + +const authorRegex = /by \[@(.*?)\]\(https:\/\/github\.com\/\1\)/; +const titleRegex = /^#{4} (.*?)\(\[#\d{4,}]/; + +const template = fs.readFileSync( + path.join(CHANGELOG_ROOT, TEMPLATE_FILE), + "utf8" +); +const [templateComment] = template.match(//); +const [templateAuthorLink] = template.match(authorRegex); + +for (const category of CHANGELOG_CATEGORIES) { + const files = fs.readdirSync(path.join(CHANGELOG_ROOT, category)); + if (!files.includes(".gitkeep")) { + showErrorMessage( + `Please don't remove ".gitkeep" from "${CHANGELOG_DIR}/${category}".` + ); + } + + for (const prFile of files) { + if (prFile === ".gitkeep") { + continue; + } + + const match = prFile.match(/^pr-(\d{4,})\.md$/); + const displayPath = `${CHANGELOG_DIR}/${category}/${prFile}`; + + if (!match) { + showErrorMessage( + `[${displayPath}]: Filename is not in form of "pr-{PR_NUMBER}.md".` + ); + continue; + } + const [, prNumber] = match; + const content = fs.readFileSync( + path.join(CHANGELOG_DIR, category, prFile), + "utf8" + ); + const prLink = `[#${prNumber}](https://github.com/prettier/prettier/pull/${prNumber})`; + + if (!content.includes(prLink)) { + showErrorMessage(`[${displayPath}]: PR link "${prLink}" is missing.`); + } + if (!authorRegex.test(content)) { + showErrorMessage(`[${displayPath}]: Author link is missing.`); + } + if (content.includes(templateComment)) { + showErrorMessage( + `[${displayPath}]: Please remove template comments at top.` + ); + } + if (content.includes(templateAuthorLink)) { + showErrorMessage( + `[${displayPath}]: Please change author link to your github account.` + ); + } + if (!content.startsWith("#### ")) { + showErrorMessage(`[${displayPath}]: Please use h4("####") for title.`); + } + const titleMatch = content.match(titleRegex); + if (!titleMatch) { + showErrorMessage(`[${displayPath}]: Something wrong in title.`); + continue; + } + const [, title] = titleMatch; + const categoryInTitle = title + .split(":") + .shift() + .trim(); + if (CHANGELOG_CATEGORIES.includes(categoryInTitle.toLowerCase())) { + showErrorMessage( + `[${displayPath}]: Please remove "${categoryInTitle}:" in title.` + ); + } + + if (title.startsWith(" ")) { + showErrorMessage( + `[${displayPath}]: Don't add extra space(s) at beginning of title.` + ); + } + + if (!title.endsWith(" ") || title.length - title.trimEnd().length !== 1) { + showErrorMessage( + `[${displayPath}]: Please put one space between title and PR link.` + ); + } + } +}