-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add env var to bypass hooks execution #96
Changes from 9 commits
79136a8
3d0ff4c
c437eb7
10f1ded
6ad9fe4
062a539
d0b35e1
b506dbd
095089d
47dec20
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,7 @@ | |
"clean-publish": "^4.2.0", | ||
"eslint": "^7.19.0", | ||
"jest": "^26.6.3", | ||
"lint-staged": "^10.5.4" | ||
"lint-staged": "^10.5.4", | ||
"lodash.isequal": "^4.5.0" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this? I saw no usage? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
const fs = require('fs') | ||
const spc = require("./simple-git-hooks"); | ||
const path = require("path") | ||
const { execSync } = require('child_process'); | ||
const isEqual = require('lodash.isequal'); | ||
|
||
const { version: packageVersion } = require('./package.json'); | ||
|
||
|
@@ -88,6 +90,8 @@ const projectWithCustomConfigurationFilePath = path.normalize(path.join(testsFol | |
const projectWithIncorrectConfigurationInPackageJson = path.normalize(path.join(testsFolder, 'project_with_incorrect_configuration_in_package_json')) | ||
const projectWithoutConfiguration = path.normalize(path.join(testsFolder, 'project_without_configuration')) | ||
|
||
const TEST_SCRIPT = `${spc.PREPEND_SCRIPT}exit 1`; | ||
|
||
/** | ||
* Creates .git/hooks dir from root | ||
* @param {string} root | ||
|
@@ -126,108 +130,122 @@ function getInstalledGitHooks(hooksDir) { | |
return result | ||
} | ||
|
||
afterEach(() => { | ||
[ | ||
projectWithConfigurationInAlternativeSeparateJsPath, | ||
projectWithConfigurationInAlternativeSeparateCjsPath, | ||
projectWithConfigurationInSeparateCjsPath, | ||
projectWithConfigurationInSeparateJsPath, | ||
projectWithConfigurationInAlternativeSeparateJsonPath, | ||
projectWithConfigurationInSeparateJsonPath, | ||
projectWithConfigurationInPackageJsonPath, | ||
projectWithIncorrectConfigurationInPackageJson, | ||
projectWithoutConfiguration, | ||
projectWithConfigurationInPackageJsonPath, | ||
projectWithUnusedConfigurationInPackageJsonPath, | ||
projectWithCustomConfigurationFilePath, | ||
].forEach((testCase) => { | ||
removeGitHooksFolder(testCase); | ||
}); | ||
}); | ||
|
||
|
||
test('creates git hooks if configuration is correct from .simple-git-hooks.js', () => { | ||
createGitHooksFolder(projectWithConfigurationInAlternativeSeparateJsPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInAlternativeSeparateJsPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInAlternativeSeparateJsPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithConfigurationInAlternativeSeparateJsPath) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
}) | ||
|
||
|
||
test('creates git hooks if configuration is correct from .simple-git-hooks.cjs', () => { | ||
createGitHooksFolder(projectWithConfigurationInAlternativeSeparateCjsPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInAlternativeSeparateCjsPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInAlternativeSeparateCjsPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithConfigurationInAlternativeSeparateCjsPath) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
}) | ||
|
||
|
||
test('creates git hooks if configuration is correct from simple-git-hooks.cjs', () => { | ||
createGitHooksFolder(projectWithConfigurationInSeparateCjsPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInSeparateCjsPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInSeparateCjsPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithConfigurationInSeparateCjsPath) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can extract There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, extracted into COMMON_GIT_HOOKS variable |
||
}) | ||
|
||
|
||
test('creates git hooks if configuration is correct from simple-git-hooks.js', () => { | ||
createGitHooksFolder(projectWithConfigurationInSeparateJsPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInSeparateJsPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInSeparateJsPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithConfigurationInSeparateJsPath) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
}) | ||
|
||
|
||
test('creates git hooks if configuration is correct from .simple-git-hooks.json', () => { | ||
createGitHooksFolder(projectWithConfigurationInAlternativeSeparateJsonPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInAlternativeSeparateJsonPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInAlternativeSeparateJsonPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithConfigurationInAlternativeSeparateJsonPath) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
}) | ||
|
||
|
||
test('creates git hooks if configuration is correct from simple-git-hooks.json', () => { | ||
createGitHooksFolder(projectWithConfigurationInSeparateJsonPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInSeparateJsonPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInSeparateJsonPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithConfigurationInSeparateJsonPath) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
}) | ||
|
||
|
||
test('creates git hooks if configuration is correct from package.json', () => { | ||
createGitHooksFolder(projectWithConfigurationInPackageJsonPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInPackageJsonPath) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInPackageJsonPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`})) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT })).toBe(true); | ||
|
||
removeGitHooksFolder(projectWithConfigurationInPackageJsonPath) | ||
}) | ||
|
||
|
||
test('fails to create git hooks if configuration contains bad git hooks', () => { | ||
createGitHooksFolder(projectWithIncorrectConfigurationInPackageJson) | ||
|
||
expect(() => spc.setHooksFromConfig(projectWithIncorrectConfigurationInPackageJson)).toThrow('[ERROR] Config was not in correct format. Please check git hooks or options name') | ||
|
||
removeGitHooksFolder(projectWithIncorrectConfigurationInPackageJson) | ||
}) | ||
|
||
|
||
test('fails to create git hooks if not configured', () => { | ||
createGitHooksFolder(projectWithoutConfiguration) | ||
|
||
expect(() => spc.setHooksFromConfig(projectWithoutConfiguration)).toThrow('[ERROR] Config was not found! Please add `.simple-git-hooks.js` or `simple-git-hooks.js` or `.simple-git-hooks.json` or `simple-git-hooks.json` or `simple-git-hooks` entry in package.json.') | ||
|
||
removeGitHooksFolder(projectWithoutConfiguration) | ||
}) | ||
|
||
|
||
test('removes git hooks', () => { | ||
createGitHooksFolder(projectWithConfigurationInPackageJsonPath) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInPackageJsonPath) | ||
|
||
let installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInPackageJsonPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`})) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT })).toBe(true) | ||
|
||
spc.removeHooks(projectWithConfigurationInPackageJsonPath) | ||
|
||
installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithConfigurationInPackageJsonPath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({})) | ||
expect(isEqual(installedHooks, {})).toBe(true); | ||
|
||
removeGitHooksFolder(projectWithConfigurationInPackageJsonPath) | ||
}) | ||
|
||
|
||
test('creates git hooks and removes unused git hooks', () => { | ||
createGitHooksFolder(projectWithConfigurationInPackageJsonPath) | ||
|
||
|
@@ -236,14 +254,13 @@ test('creates git hooks and removes unused git hooks', () => { | |
fs.writeFileSync(path.resolve(installedHooksDir, 'pre-push'), "# do nothing") | ||
|
||
let installedHooks = getInstalledGitHooks(installedHooksDir); | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-push':'# do nothing'})) | ||
expect(isEqual(installedHooks, { 'pre-push': '# do nothing' })).toBe(true) | ||
|
||
spc.setHooksFromConfig(projectWithConfigurationInPackageJsonPath) | ||
|
||
installedHooks = getInstalledGitHooks(installedHooksDir); | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`})) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT })).toBe(true); | ||
|
||
removeGitHooksFolder(projectWithConfigurationInPackageJsonPath) | ||
}) | ||
|
||
|
||
|
@@ -256,16 +273,16 @@ test('creates git hooks and removes unused but preserves specific git hooks', () | |
fs.writeFileSync(path.resolve(installedHooksDir, 'pre-push'), "# do nothing") | ||
|
||
let installedHooks = getInstalledGitHooks(installedHooksDir); | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'commit-msg': '# do nothing', 'pre-push':'# do nothing'})) | ||
expect(isEqual(installedHooks, { 'commit-msg': '# do nothing', 'pre-push': '# do nothing' })).toBe(true); | ||
|
||
spc.setHooksFromConfig(projectWithUnusedConfigurationInPackageJsonPath) | ||
|
||
installedHooks = getInstalledGitHooks(installedHooksDir); | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'commit-msg': '# do nothing', 'pre-commit':`#!/bin/sh\nexit 1`})) | ||
expect(isEqual(installedHooks, { 'commit-msg': '# do nothing', 'pre-commit': TEST_SCRIPT })).toBe(true); | ||
|
||
removeGitHooksFolder(projectWithUnusedConfigurationInPackageJsonPath) | ||
}) | ||
|
||
|
||
test.each([ | ||
['npx', 'simple-git-hooks', './git-hooks.js'], | ||
['node', require.resolve(`./cli`), './git-hooks.js'], | ||
|
@@ -275,7 +292,77 @@ test.each([ | |
|
||
spc.setHooksFromConfig(projectWithCustomConfigurationFilePath, args) | ||
const installedHooks = getInstalledGitHooks(path.normalize(path.join(projectWithCustomConfigurationFilePath, '.git', 'hooks'))) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({'pre-commit':`#!/bin/sh\nexit 1`, 'pre-push':`#!/bin/sh\nexit 1`})) | ||
|
||
removeGitHooksFolder(projectWithCustomConfigurationFilePath) | ||
expect(JSON.stringify(installedHooks)).toBe(JSON.stringify({ 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })) | ||
expect(isEqual(installedHooks, { 'pre-commit': TEST_SCRIPT, 'pre-push': TEST_SCRIPT })).toBe(true); | ||
}) | ||
|
||
describe('Tests for skipping git hooks using SKIP_SIMPLE_GIT_HOOKS env var', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's nice to see you taking a look to jest But it makes no sense if it is used only in your tests. Let me try to be more clear on what I meant in the previous review: So, we have our test code setup like this:
We can use describe to make it look like this:
This way tests can be grouped, which allows us to see pretty output: here is an example if we do the manipulations above -- I propose two solutions:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have used describe, it syntax, let me if it needs further work |
||
|
||
const GIT_USER_NAME = "github-actions"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can do this in GitHub actions itself, do not see why we need some GH actions specific code in repo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the tests, I'm performing commit git operation which requires to set username and email, so I have used random values, let me know if it can be done in a better way |
||
const GIT_USER_EMAIL = "[email protected]"; | ||
|
||
const initializeGitRepository = (path) => { | ||
execSync( | ||
`git init \ | ||
&& git config user.name ${GIT_USER_NAME} \ | ||
&& git config user.email ${GIT_USER_EMAIL}`, | ||
{ cwd: path } | ||
); | ||
}; | ||
|
||
const performTestCommit = (path, env = process.env) => { | ||
try { | ||
execSync( | ||
'git add . && git commit --allow-empty -m "Test commit" && git commit --allow-empty -am "Change commit msg"', | ||
{ | ||
cwd: path, | ||
env: env, | ||
} | ||
); | ||
return false; | ||
} catch (e) { | ||
return true; | ||
} | ||
}; | ||
|
||
beforeEach(() => { | ||
initializeGitRepository(projectWithConfigurationInPackageJsonPath); | ||
createGitHooksFolder(projectWithConfigurationInPackageJsonPath); | ||
spc.setHooksFromConfig(projectWithConfigurationInPackageJsonPath); | ||
}); | ||
|
||
afterEach(() => { | ||
delete process.env.SKIP_SIMPLE_GIT_HOOKS; | ||
}); | ||
|
||
const expectCommitToSucceed = (path) => { | ||
const errorOccurred = performTestCommit(path); | ||
expect(errorOccurred).toBe(false); | ||
}; | ||
|
||
const expectCommitToFail = (path) => { | ||
const errorOccurred = performTestCommit(path); | ||
expect(errorOccurred).toBe(true); | ||
}; | ||
|
||
test('commits successfully when SKIP_SIMPLE_GIT_HOOKS is set to "1"', () => { | ||
process.env.SKIP_SIMPLE_GIT_HOOKS = "1"; | ||
expectCommitToSucceed(projectWithConfigurationInPackageJsonPath); | ||
}); | ||
|
||
test("commit fails when SKIP_SIMPLE_GIT_HOOKS is not set", () => { | ||
expectCommitToFail(projectWithConfigurationInPackageJsonPath); | ||
}); | ||
|
||
test('commit fails when SKIP_SIMPLE_GIT_HOOKS is set to "0"', () => { | ||
process.env.SKIP_SIMPLE_GIT_HOOKS = "0"; | ||
expectCommitToFail(projectWithConfigurationInPackageJsonPath); | ||
}); | ||
|
||
test("commit fails when SKIP_SIMPLE_GIT_HOOKS is set to a random string", () => { | ||
process.env.SKIP_SIMPLE_GIT_HOOKS = "simple-git-hooks"; | ||
expectCommitToFail(projectWithConfigurationInPackageJsonPath); | ||
}); | ||
|
||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's best to also include use cases. I've seen people struggle with skipping git hooks when using 3rd party git clients
Normally (from the terminal) you can bypass hooks by using
--skip-hooks
option if im not mistaken :-)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like so:
Using with 3rd party clients:
...