From 3e757353b5da919f7ad137f0640b350e2b393b44 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 12 Apr 2022 15:31:56 +0200 Subject: [PATCH 01/18] chore(ci): add pre-commit hook to unstage generated codes --- .husky/pre-commit | 4 ++++ package.json | 4 +++- yarn.lock | 10 ++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100755 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000000..f836758dbc --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +echo "Running a git pre-commit hook." diff --git a/package.json b/package.json index ab067c4be2..c69b44addc 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "specs:fix": "eslint --ext=yml specs/$0 --fix", "specs:lint": "eslint --ext=yml specs/$0", "website:build": "yarn workspace website build", - "website": "yarn workspace website start --host 0.0.0.0" + "website": "yarn workspace website start --host 0.0.0.0", + "prepare": "husky install" }, "devDependencies": { "@experimental-api-clients-automation/openapi-generator-cli": "0.0.1", @@ -47,6 +48,7 @@ "eslint-plugin-prettier": "4.0.0", "eslint-plugin-unused-imports": "2.0.0", "eslint-plugin-yml": "0.14.0", + "husky": "7.0.4", "json": "11.0.0", "mustache": "4.2.0", "prettier": "2.6.2", diff --git a/yarn.lock b/yarn.lock index 48432d1030..92b7ab9fa7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,6 +25,7 @@ __metadata: eslint-plugin-prettier: 4.0.0 eslint-plugin-unused-imports: 2.0.0 eslint-plugin-yml: 0.14.0 + husky: 7.0.4 json: 11.0.0 mustache: 4.2.0 prettier: 2.6.2 @@ -12203,6 +12204,15 @@ __metadata: languageName: node linkType: hard +"husky@npm:7.0.4": + version: 7.0.4 + resolution: "husky@npm:7.0.4" + bin: + husky: lib/bin.js + checksum: c6ec4af63da2c9522da8674a20ad9b48362cc92704896cc8a58c6a2a39d797feb2b806f93fbd83a6d653fbdceb2c3b6e0b602c6b2e8565206ffc2882ef7db9e9 + languageName: node + linkType: hard + "iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" From 227edcc431a101b09f5ed7ef283ab4bb58dfd7c8 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 12 Apr 2022 15:32:46 +0200 Subject: [PATCH 02/18] chore: test commit --- .husky/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index f836758dbc..f95d701d31 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -echo "Running a git pre-commit hook." +echo "Running a git pre-commit hook.." From 9167fc9c1ba47ad78f3169f813606304893b0da9 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Thu, 14 Apr 2022 18:04:42 +0200 Subject: [PATCH 03/18] chore: implement pre-commit script --- .husky/pre-commit | 2 +- scripts/ci/husky/__tests__/pre-commit.test.js | 24 +++++ scripts/ci/husky/pre-commit.js | 91 +++++++++++++++++++ scripts/package.json | 3 + yarn.lock | 38 ++++++-- 5 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 scripts/ci/husky/__tests__/pre-commit.test.js create mode 100755 scripts/ci/husky/pre-commit.js diff --git a/.husky/pre-commit b/.husky/pre-commit index f95d701d31..40af2335e2 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -echo "Running a git pre-commit hook.." +yarn workspace scripts pre-commit \ No newline at end of file diff --git a/scripts/ci/husky/__tests__/pre-commit.test.js b/scripts/ci/husky/__tests__/pre-commit.test.js new file mode 100644 index 0000000000..5e4a6a272e --- /dev/null +++ b/scripts/ci/husky/__tests__/pre-commit.test.js @@ -0,0 +1,24 @@ +/* eslint-disable import/no-commonjs */ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { createMemoizedMicromatchMatcher } = require('../pre-commit'); + +describe('createMemoizedMicromatchMatcher', () => { + it('matches correctly', () => { + const matcher = createMemoizedMicromatchMatcher([ + 'clients/**/*', + '!clients/README.md', + ]); + + expect(matcher('clients/README.md')).toEqual(false); + expect(matcher('clients/CONTRIBUTING.md')).toEqual(true); + }); + + it('prioritizes the exact match when two patterns conflict', () => { + const matcher = createMemoizedMicromatchMatcher([ + '!lib/Configuration/*', + 'lib/Configuration/Configuration.php', + ]); + + expect(matcher('lib/Configuration/Configuration.php')).toEqual(true); + }); +}); diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js new file mode 100755 index 0000000000..756adc6f0d --- /dev/null +++ b/scripts/ci/husky/pre-commit.js @@ -0,0 +1,91 @@ +#!/usr/bin/env node +/* eslint-disable import/no-commonjs */ +/* eslint-disable no-console */ +/* eslint-disable @typescript-eslint/no-var-requires */ +const execa = require('execa'); +const micromatch = require('micromatch'); + +const GENERATED_FILE_PATTERNS = [ + // Ignore the roots and go down the tree by negating hand written files + 'clients/**/*', + '!clients/README.md', + '!clients/**/.openapi-generator-ignore', + + // Java + '!clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/exceptions/*', + '!clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/*', + 'clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/echo/EchoResponse.java', + + // JavaScript + '!clients/algoliasearch-client-javascript/*', + '!clients/algoliasearch-client-javascript/.github/**/*', + '!clients/algoliasearch-client-javascript/.yarn/**/*', + '!clients/algoliasearch-client-javascript/scripts/**/*', + '!clients/algoliasearch-client-javascript/packages/algoliasearch/**/*', + '!clients/algoliasearch-client-javascript/packages/requester-*/**/*', + '!clients/algoliasearch-client-javascript/packages/client-common/**/*', + + // PHP + '!clients/algoliasearch-client-php/lib/Configuration/*', + 'clients/algoliasearch-client-php/lib/*.php', + 'clients/algoliasearch-client-php/lib/Api/*', + 'clients/algoliasearch-client-php/lib/Configuration/Configuration.php', +]; + +const run = async (command, { cwd } = {}) => { + return ( + (await execa.command(command, { shell: 'bash', all: true, cwd })).all ?? '' + ); +}; + +function createMemoizedMicromatchMatcher(patterns = []) { + const exactMatchers = []; + const positiveMatchers = []; + const negativeMatchers = []; + + patterns.forEach((pattern) => { + if (pattern.charCodeAt(0) === 33) { + // Patterns starting with `!` are negated + negativeMatchers.push(micromatch.matcher(pattern.slice(1))); + } else if (!pattern.includes('*')) { + exactMatchers.push(micromatch.matcher(pattern)); + } else { + positiveMatchers.push(micromatch.matcher(pattern)); + } + }); + + return function matcher(str) { + if (exactMatchers.some((match) => match(str))) { + return true; + } + + // As `some` returns false on empty array, test will always fail if we only + // provide `negativeMatchers`. We fallback to `true` is it's the case. + const hasPositiveMatchers = + Boolean(positiveMatchers.length === 0 && negativeMatchers.length) || + positiveMatchers.some((match) => match(str)); + + return hasPositiveMatchers && !negativeMatchers.some((match) => match(str)); + }; +} + +async function preCommit() { + const stagedFiles = (await run(`git diff --name-only --cached`)).split('\n'); + const matcher = createMemoizedMicromatchMatcher(GENERATED_FILE_PATTERNS); + if (stagedFiles.some((file) => matcher(file))) { + const generatedFiles = stagedFiles.filter((file) => matcher(file)); + throw new Error( + `You cannot include gnerated files in the commit. Please unstage the following:\n\n${generatedFiles + .map((file) => ` - ${file}`) + .join('\n')}` + ); + } +} + +if (require.main === module) { + preCommit(); +} + +module.exports = { + createMemoizedMicromatchMatcher, +}; diff --git a/scripts/package.json b/scripts/package.json index 681eee89f5..c9d500a600 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -10,6 +10,7 @@ "spreadGeneration": "ts-node ci/codegen/spreadGeneration.ts", "upsertGenerationComment": "ts-node ci/codegen/upsertGenerationComment.ts", "setRunVariables": "ts-node ci/setRunVariables.ts", + "pre-commit": "./ci/husky/pre-commit.js", "test": "jest" }, "devDependencies": { @@ -19,6 +20,7 @@ "@types/inquirer": "8.2.1", "@types/jest": "27.4.1", "@types/js-yaml": "4.0.5", + "@types/micromatch": "4.0.2", "@types/mustache": "4.1.2", "@types/node": "16.11.26", "@types/semver": "7.3.9", @@ -31,6 +33,7 @@ "inquirer": "8.2.2", "jest": "27.5.1", "js-yaml": "4.1.0", + "micromatch": "4.0.5", "mustache": "4.2.0", "openapi-types": "10.0.0", "ora-classic": "5.4.2", diff --git a/yarn.lock b/yarn.lock index 92b7ab9fa7..e5cb4d0245 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5516,6 +5516,13 @@ __metadata: languageName: node linkType: hard +"@types/braces@npm:*": + version: 3.0.1 + resolution: "@types/braces@npm:3.0.1" + checksum: 3749f7673a03d498ddb2f199b222bb403e53e78ac05a599c757c2049703ece802602c78640af0ff826be0fd2ea8b03daff04ce18806ed739592302195b7a569b + languageName: node + linkType: hard + "@types/connect-history-api-fallback@npm:^1.3.5": version: 1.3.5 resolution: "@types/connect-history-api-fallback@npm:1.3.5" @@ -5734,6 +5741,15 @@ __metadata: languageName: node linkType: hard +"@types/micromatch@npm:4.0.2": + version: 4.0.2 + resolution: "@types/micromatch@npm:4.0.2" + dependencies: + "@types/braces": "*" + checksum: 6c678e9c625d5b422c6d2c1001da1c502ecc4457248343bbd324b79fd798a6563e336a4d79630d80e8202312013dd7cf8b4440afa644d04477abd26fde6fba24 + languageName: node + linkType: hard + "@types/mime@npm:^1": version: 1.3.2 resolution: "@types/mime@npm:1.3.2" @@ -14673,6 +14689,16 @@ __metadata: languageName: node linkType: hard +"micromatch@npm:4.0.5, micromatch@npm:^4.0.5": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: ^3.0.2 + picomatch: ^2.3.1 + checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc + languageName: node + linkType: hard + "micromatch@npm:^4.0.2, micromatch@npm:^4.0.4": version: 4.0.4 resolution: "micromatch@npm:4.0.4" @@ -14683,16 +14709,6 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.5": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" - dependencies: - braces: ^3.0.2 - picomatch: ^2.3.1 - checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc - languageName: node - linkType: hard - "miller-rabin@npm:^4.0.0": version: 4.0.1 resolution: "miller-rabin@npm:4.0.1" @@ -18997,6 +19013,7 @@ __metadata: "@types/inquirer": 8.2.1 "@types/jest": 27.4.1 "@types/js-yaml": 4.0.5 + "@types/micromatch": 4.0.2 "@types/mustache": 4.1.2 "@types/node": 16.11.26 "@types/semver": 7.3.9 @@ -19009,6 +19026,7 @@ __metadata: inquirer: 8.2.2 jest: 27.5.1 js-yaml: 4.1.0 + micromatch: 4.0.5 mustache: 4.2.0 openapi-types: 10.0.0 ora-classic: 5.4.2 From b9d10571e0ffc6b9e3ddcd0a1303c650749c3f09 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Thu, 14 Apr 2022 18:11:24 +0200 Subject: [PATCH 04/18] chore: fix lint error --- .husky/pre-commit | 2 +- scripts/ci/husky/pre-commit.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 40af2335e2..2376d55800 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -yarn workspace scripts pre-commit \ No newline at end of file +yarn workspace scripts pre-commit diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index 756adc6f0d..cd5a2449ba 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -1,6 +1,5 @@ #!/usr/bin/env node /* eslint-disable import/no-commonjs */ -/* eslint-disable no-console */ /* eslint-disable @typescript-eslint/no-var-requires */ const execa = require('execa'); const micromatch = require('micromatch'); From 054c0310a14cd3ddfeabb44a9373ea87fa6aa22e Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Thu, 14 Apr 2022 18:22:23 +0200 Subject: [PATCH 05/18] chore: fix lint error --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1215f62c77..485a4d108d 100644 --- a/package.json +++ b/package.json @@ -24,14 +24,14 @@ "github-actions:lint": "eslint --ext=yml .github/", "postinstall": "yarn workspace eslint-plugin-automation-custom build", "playground:browser": "yarn workspace javascript-browser-playground start", + "prepare": "husky install", "release": "yarn workspace scripts createReleaseIssue", "scripts:lint": "eslint --ext=ts scripts/", "scripts:test": "yarn workspace scripts test", "specs:fix": "eslint --ext=yml specs/$0 --fix", "specs:lint": "eslint --ext=yml specs/$0", "website": "yarn workspace website start --host 0.0.0.0", - "website:build": "yarn workspace website build", - "prepare": "husky install" + "website:build": "yarn workspace website build" }, "devDependencies": { "@experimental-api-clients-automation/openapi-generator-cli": "0.0.1", From 3fe4723dab86672e282013dbca30eea458e8d48c Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 15 Apr 2022 10:33:18 +0200 Subject: [PATCH 06/18] chore: call js file directly --- .husky/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 2376d55800..78a740046e 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -yarn workspace scripts pre-commit +./scripts/ci/husky/pre-commit.js From 40cbd5e462e71fb644e9d6ea6bacef0cdf018a89 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 15 Apr 2022 14:04:43 +0200 Subject: [PATCH 07/18] chore: update .cache_version --- .github/.cache_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.cache_version b/.github/.cache_version index 8b22a322d0..215aacb452 100644 --- a/.github/.cache_version +++ b/.github/.cache_version @@ -1 +1 @@ -8.0.2 +8.0.3 From c8c3c6ec778ec9e3b16fc776dfbf94a2942940fb Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 19 Apr 2022 10:25:36 +0200 Subject: [PATCH 08/18] Update scripts/ci/husky/pre-commit.js Co-authored-by: Pierre Millot --- scripts/ci/husky/pre-commit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index cd5a2449ba..5da3460dd1 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -74,7 +74,7 @@ async function preCommit() { if (stagedFiles.some((file) => matcher(file))) { const generatedFiles = stagedFiles.filter((file) => matcher(file)); throw new Error( - `You cannot include gnerated files in the commit. Please unstage the following:\n\n${generatedFiles + `You cannot include generated files in the commit. Please unstage the following:\n\n${generatedFiles .map((file) => ` - ${file}`) .join('\n')}` ); From 0b07721f724ab1083212c1a3f4bf56a148c23c4e Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 19 Apr 2022 10:25:43 +0200 Subject: [PATCH 09/18] Update scripts/ci/husky/pre-commit.js Co-authored-by: Pierre Millot --- scripts/ci/husky/pre-commit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index 5da3460dd1..275df80b4d 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -43,7 +43,7 @@ function createMemoizedMicromatchMatcher(patterns = []) { const negativeMatchers = []; patterns.forEach((pattern) => { - if (pattern.charCodeAt(0) === 33) { + if (pattern.startsWith('!')) { // Patterns starting with `!` are negated negativeMatchers.push(micromatch.matcher(pattern.slice(1))); } else if (!pattern.includes('*')) { From 4dc5a019bbe56b5c4c33c7a6e79851d10840b7cf Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 19 Apr 2022 10:42:16 +0200 Subject: [PATCH 10/18] chore: use postinstall instead of prepare --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 485a4d108d..a6ac06e8ea 100644 --- a/package.json +++ b/package.json @@ -22,9 +22,8 @@ "docker:setup": "yarn docker:clean && yarn docker:build && yarn docker:mount", "fix:json": "eslint --ext=json . --fix", "github-actions:lint": "eslint --ext=yml .github/", - "postinstall": "yarn workspace eslint-plugin-automation-custom build", + "postinstall": "husky install && yarn workspace eslint-plugin-automation-custom build", "playground:browser": "yarn workspace javascript-browser-playground start", - "prepare": "husky install", "release": "yarn workspace scripts createReleaseIssue", "scripts:lint": "eslint --ext=ts scripts/", "scripts:test": "yarn workspace scripts test", From 202169c08dc88d3b902faf79031fa82df21928cb Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 19 Apr 2022 10:42:31 +0200 Subject: [PATCH 11/18] chore: better error message --- scripts/ci/husky/pre-commit.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index 275df80b4d..8d5b4f4554 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -1,4 +1,6 @@ #!/usr/bin/env node +/* eslint-disable no-process-exit */ +/* eslint-disable no-console */ /* eslint-disable import/no-commonjs */ /* eslint-disable @typescript-eslint/no-var-requires */ const execa = require('execa'); @@ -71,13 +73,17 @@ function createMemoizedMicromatchMatcher(patterns = []) { async function preCommit() { const stagedFiles = (await run(`git diff --name-only --cached`)).split('\n'); const matcher = createMemoizedMicromatchMatcher(GENERATED_FILE_PATTERNS); - if (stagedFiles.some((file) => matcher(file))) { - const generatedFiles = stagedFiles.filter((file) => matcher(file)); - throw new Error( + const generatedFiles = stagedFiles.filter((file) => matcher(file)); + + if (generatedFiles.length > 0) { + console.log( + '\x1b[41m%s\x1b[0m', + '[ERROR]', `You cannot include generated files in the commit. Please unstage the following:\n\n${generatedFiles .map((file) => ` - ${file}`) .join('\n')}` ); + process.exit(1); } } From 6d34e740f1e9f7d23979b7c133e9d3d18085b37e Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 19 Apr 2022 15:39:07 +0200 Subject: [PATCH 12/18] chore: fix patterns --- scripts/ci/husky/__tests__/pre-commit.test.js | 2 +- scripts/ci/husky/pre-commit.js | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/ci/husky/__tests__/pre-commit.test.js b/scripts/ci/husky/__tests__/pre-commit.test.js index 5e4a6a272e..bad3774922 100644 --- a/scripts/ci/husky/__tests__/pre-commit.test.js +++ b/scripts/ci/husky/__tests__/pre-commit.test.js @@ -5,7 +5,7 @@ const { createMemoizedMicromatchMatcher } = require('../pre-commit'); describe('createMemoizedMicromatchMatcher', () => { it('matches correctly', () => { const matcher = createMemoizedMicromatchMatcher([ - 'clients/**/*', + 'clients/**', '!clients/README.md', ]); diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index 8d5b4f4554..ebd96cf3d4 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -8,7 +8,7 @@ const micromatch = require('micromatch'); const GENERATED_FILE_PATTERNS = [ // Ignore the roots and go down the tree by negating hand written files - 'clients/**/*', + 'clients/**', '!clients/README.md', '!clients/**/.openapi-generator-ignore', @@ -19,12 +19,12 @@ const GENERATED_FILE_PATTERNS = [ // JavaScript '!clients/algoliasearch-client-javascript/*', - '!clients/algoliasearch-client-javascript/.github/**/*', - '!clients/algoliasearch-client-javascript/.yarn/**/*', - '!clients/algoliasearch-client-javascript/scripts/**/*', - '!clients/algoliasearch-client-javascript/packages/algoliasearch/**/*', - '!clients/algoliasearch-client-javascript/packages/requester-*/**/*', - '!clients/algoliasearch-client-javascript/packages/client-common/**/*', + '!clients/algoliasearch-client-javascript/.github/**', + '!clients/algoliasearch-client-javascript/.yarn/**', + '!clients/algoliasearch-client-javascript/scripts/**', + '!clients/algoliasearch-client-javascript/packages/algoliasearch/**', + '!clients/algoliasearch-client-javascript/packages/requester-*/**', + '!clients/algoliasearch-client-javascript/packages/client-common/**', // PHP '!clients/algoliasearch-client-php/lib/Configuration/*', From 62c75febfe8e16c8ac172caa3c0a01f14af6d254 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Tue, 19 Apr 2022 16:13:41 +0200 Subject: [PATCH 13/18] chore: unstage files automatically and exit with 0 --- scripts/ci/husky/pre-commit.js | 21 ++++++++++++--------- scripts/package.json | 1 + yarn.lock | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index ebd96cf3d4..680e2c3b00 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -/* eslint-disable no-process-exit */ /* eslint-disable no-console */ /* eslint-disable import/no-commonjs */ /* eslint-disable @typescript-eslint/no-var-requires */ +const chalk = require('chalk'); const execa = require('execa'); const micromatch = require('micromatch'); @@ -73,17 +73,20 @@ function createMemoizedMicromatchMatcher(patterns = []) { async function preCommit() { const stagedFiles = (await run(`git diff --name-only --cached`)).split('\n'); const matcher = createMemoizedMicromatchMatcher(GENERATED_FILE_PATTERNS); - const generatedFiles = stagedFiles.filter((file) => matcher(file)); + const filesToUnstage = stagedFiles.filter((file) => matcher(file)); - if (generatedFiles.length > 0) { + for (const fileToUnstage of filesToUnstage) { + await run(`git restore --staged ${fileToUnstage}`); + } + + if (filesToUnstage.length > 0) { console.log( - '\x1b[41m%s\x1b[0m', - '[ERROR]', - `You cannot include generated files in the commit. Please unstage the following:\n\n${generatedFiles - .map((file) => ` - ${file}`) - .join('\n')}` + chalk.bgYellow('[INFO]'), + "The following files are excluded from the commit because they're auto-generated." ); - process.exit(1); + console.log(''); + console.log(filesToUnstage.map((file) => ` > ${file}`).join('\n')); + console.log(''); } } diff --git a/scripts/package.json b/scripts/package.json index 8f6c955cbf..ff0262be5c 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -24,6 +24,7 @@ "@types/mustache": "4.1.2", "@types/node": "16.11.26", "@types/semver": "7.3.9", + "chalk": "4.1.2", "commander": "9.1.0", "dotenv": "16.0.0", "eslint": "8.12.0", diff --git a/yarn.lock b/yarn.lock index 705aae2b5c..5f8597aae7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19062,6 +19062,7 @@ __metadata: "@types/mustache": 4.1.2 "@types/node": 16.11.26 "@types/semver": 7.3.9 + chalk: 4.1.2 commander: 9.1.0 dotenv: 16.0.0 eslint: 8.12.0 From fc73866e222e905724d4168e5c09f698678c5e15 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Thu, 21 Apr 2022 16:29:25 +0200 Subject: [PATCH 14/18] chore: change loop --- scripts/ci/husky/pre-commit.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index 680e2c3b00..e456ae26a6 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -73,24 +73,22 @@ function createMemoizedMicromatchMatcher(patterns = []) { async function preCommit() { const stagedFiles = (await run(`git diff --name-only --cached`)).split('\n'); const matcher = createMemoizedMicromatchMatcher(GENERATED_FILE_PATTERNS); - const filesToUnstage = stagedFiles.filter((file) => matcher(file)); - for (const fileToUnstage of filesToUnstage) { - await run(`git restore --staged ${fileToUnstage}`); - } + for (const stagedFile of stagedFiles) { + if (!matcher(stagedFile)) { + continue; + } - if (filesToUnstage.length > 0) { console.log( chalk.bgYellow('[INFO]'), - "The following files are excluded from the commit because they're auto-generated." + `Generated file found, unstaging: ${stagedFile}` ); - console.log(''); - console.log(filesToUnstage.map((file) => ` > ${file}`).join('\n')); - console.log(''); + + await run(`git restore --staged ${stagedFile}`); } } -if (require.main === module) { +if (require.main === module && !process.env.CI) { preCommit(); } From d5fa011fc489b2717eefcadd24c80217634eedb1 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Thu, 21 Apr 2022 16:39:04 +0200 Subject: [PATCH 15/18] chore: skip deleted files --- scripts/ci/husky/pre-commit.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index e456ae26a6..dd519612f4 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -72,9 +72,17 @@ function createMemoizedMicromatchMatcher(patterns = []) { async function preCommit() { const stagedFiles = (await run(`git diff --name-only --cached`)).split('\n'); + const deletedFiles = new Set( + (await run(`git ls-files --deleted`)).split('\n') + ); const matcher = createMemoizedMicromatchMatcher(GENERATED_FILE_PATTERNS); for (const stagedFile of stagedFiles) { + // keep the deleted files staged even if they were generated before. + if (deletedFiles.has(stagedFile)) { + continue; + } + if (!matcher(stagedFile)) { continue; } From 73528a051eb62deae0180262f0411ca0e2d24e20 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 22 Apr 2022 14:26:06 +0200 Subject: [PATCH 16/18] chore: split config to a separate file --- config/generation.config.js | 30 ++++++++++++++++++++++++++++++ scripts/ci/husky/pre-commit.js | 28 ++-------------------------- 2 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 config/generation.config.js diff --git a/config/generation.config.js b/config/generation.config.js new file mode 100644 index 0000000000..d325f85548 --- /dev/null +++ b/config/generation.config.js @@ -0,0 +1,30 @@ +// eslint-disable-next-line import/no-commonjs +module.exports = { + patterns: [ + // Ignore the roots and go down the tree by negating hand written files + 'clients/**', + '!clients/README.md', + '!clients/**/.openapi-generator-ignore', + + // Java + '!clients/algoliasearch-client-java-2/algoliasearch-core/src/com/algolia/exceptions/*', + '!clients/algoliasearch-client-java-2/algoliasearch-core/src/com/algolia/utils/*', + 'clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/echo/EchoResponse*.java', + '!clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/echo/EchoResponseInterface.java', + + // JavaScript + '!clients/algoliasearch-client-javascript/*', + '!clients/algoliasearch-client-javascript/.github/**', + '!clients/algoliasearch-client-javascript/.yarn/**', + '!clients/algoliasearch-client-javascript/scripts/**', + '!clients/algoliasearch-client-javascript/packages/algoliasearch/**', + '!clients/algoliasearch-client-javascript/packages/requester-*/**', + '!clients/algoliasearch-client-javascript/packages/client-common/**', + + // PHP + '!clients/algoliasearch-client-php/lib/Configuration/*', + 'clients/algoliasearch-client-php/lib/*.php', + 'clients/algoliasearch-client-php/lib/Api/*', + 'clients/algoliasearch-client-php/lib/Configuration/Configuration.php', + ], +}; diff --git a/scripts/ci/husky/pre-commit.js b/scripts/ci/husky/pre-commit.js index dd519612f4..4004b4cb96 100755 --- a/scripts/ci/husky/pre-commit.js +++ b/scripts/ci/husky/pre-commit.js @@ -6,32 +6,8 @@ const chalk = require('chalk'); const execa = require('execa'); const micromatch = require('micromatch'); -const GENERATED_FILE_PATTERNS = [ - // Ignore the roots and go down the tree by negating hand written files - 'clients/**', - '!clients/README.md', - '!clients/**/.openapi-generator-ignore', - - // Java - '!clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/exceptions/*', - '!clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/*', - 'clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/echo/EchoResponse.java', - - // JavaScript - '!clients/algoliasearch-client-javascript/*', - '!clients/algoliasearch-client-javascript/.github/**', - '!clients/algoliasearch-client-javascript/.yarn/**', - '!clients/algoliasearch-client-javascript/scripts/**', - '!clients/algoliasearch-client-javascript/packages/algoliasearch/**', - '!clients/algoliasearch-client-javascript/packages/requester-*/**', - '!clients/algoliasearch-client-javascript/packages/client-common/**', - - // PHP - '!clients/algoliasearch-client-php/lib/Configuration/*', - 'clients/algoliasearch-client-php/lib/*.php', - 'clients/algoliasearch-client-php/lib/Api/*', - 'clients/algoliasearch-client-php/lib/Configuration/Configuration.php', -]; +const GENERATED_FILE_PATTERNS = + require('../../../config/generation.config').patterns; const run = async (command, { cwd } = {}) => { return ( From b7e752eb9c3d6a0547c006d6b966f28709c3590e Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 22 Apr 2022 14:40:13 +0200 Subject: [PATCH 17/18] chore: update docs --- website/docs/commitAndPullRequest.md | 17 +++++++++++++++++ website/docs/introduction.md | 2 +- website/docs/pullRequest.md | 7 ------- website/sidebars.js | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 website/docs/commitAndPullRequest.md delete mode 100644 website/docs/pullRequest.md diff --git a/website/docs/commitAndPullRequest.md b/website/docs/commitAndPullRequest.md new file mode 100644 index 0000000000..a30e4e5198 --- /dev/null +++ b/website/docs/commitAndPullRequest.md @@ -0,0 +1,17 @@ +--- +title: Commit and Pull-request +--- + +# Commit and Pull-request + +## Commit + +If you accidentally include generated files in your commit, the `pre-commit` hook will automatically unstage them. + +We create commits on the CI as well, and in that case, we skip this unstaging behavior with the environment variable `CI=true` given. + +If you want to change the patterns of generated file paths, see [config/generation.config.js](https://github.com/algolia/api-clients-automation/blob/main/config/generation.config.js). + +## Pull-request + +Semantic title is required. It's validated by [GitHub Action](https://github.com/deepakputhraya/action-pr-title). See [pr-title.yml](https://github.com/algolia/api-clients-automation/blob/main/.github/workflows/pr-title.yml) for the complete regular expressions. diff --git a/website/docs/introduction.md b/website/docs/introduction.md index a260fa4b47..2f94b3cc2c 100644 --- a/website/docs/introduction.md +++ b/website/docs/introduction.md @@ -13,7 +13,7 @@ To contribute to the repository, make sure to take a look at our guidelines and - [Setup the repository tooling](/docs/setupRepository): to install our tooling. - [Add a new client](/docs/addNewClient): to add a new client spec to generate. - [Support a new language](/docs/addNewLanguage): to add a new supported language to the API clients. -- [Pull-request](/docs/pullRequest): to see how to send pull-requests. +- [Commit and Pull-request](/docs/commitAndPullRequest): to see how to commit and send pull-requests. - [Release process](/docs/releaseProcess): to see how to release API clients. CLI commands can be found at [CLI > specs commands](/docs/specsCommands) and [CLI > generation commands](/docs/generationCommands) diff --git a/website/docs/pullRequest.md b/website/docs/pullRequest.md deleted file mode 100644 index efc315396a..0000000000 --- a/website/docs/pullRequest.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Pull-request ---- - -# Pull-request - -Semantic title is required. It's validated by [GitHub Action](https://github.com/deepakputhraya/action-pr-title). See [pr-title.yml](https://github.com/algolia/api-clients-automation/blob/main/.github/workflows/pr-title.yml) for the complete regular expressions. diff --git a/website/sidebars.js b/website/sidebars.js index 8f3e3ed422..26e86508d4 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -19,7 +19,7 @@ const sidebars = { }, 'addNewClient', 'addNewLanguage', - 'pullRequest', + 'commitAndPullRequest', 'releaseProcess', ], }, From 32dd38e8992ba810e099e0389c7b4dd6d6bea304 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 22 Apr 2022 15:30:47 +0200 Subject: [PATCH 18/18] chore: update cache version --- .github/.cache_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.cache_version b/.github/.cache_version index 1e7c7a7364..7262faa78c 100644 --- a/.github/.cache_version +++ b/.github/.cache_version @@ -1 +1 @@ -8.0.5.1 +8.0.5.2