Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/easy-sites-stick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"simple-git-hooks": minor
---

feat: silent success if nothing has changed
8 changes: 7 additions & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,11 @@ if(skipInstall()) {
}

setHooksFromConfig(process.cwd(), process.argv)
.then(() => console.log('[INFO] Successfully set all git hooks'))
.then(({ isHookChanged }) => {
if (!isHookChanged) {
// all configured hooks are set but with same contents, silent success
return
}
console.log('[INFO] Successfully set all git hooks')
})
.catch(e => console.log('[ERROR], Was not able to set git hooks. Error: ' + e))
34 changes: 31 additions & 3 deletions simple-git-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,22 @@ async function setHooksFromConfig(projectRootPath=process.cwd(), argv=process.ar

const preserveUnused = Array.isArray(config.preserveUnused) ? config.preserveUnused : config.preserveUnused ? VALID_GIT_HOOKS: []

let isHookChanged = false

for (let hook of VALID_GIT_HOOKS) {
if (Object.prototype.hasOwnProperty.call(config, hook)) {
_setHook(hook, config[hook], projectRootPath)
const isHookUpdated = _setHook(hook, config[hook], projectRootPath).hookChanged
isHookChanged = isHookChanged || isHookUpdated
} else if (!preserveUnused.includes(hook)) {
_removeHook(hook, projectRootPath)
const isHookDeleted = _removeHook(hook, projectRootPath)
isHookChanged = isHookChanged || isHookDeleted
}
}


return {
isHookChanged,
}
}

/**
Expand Down Expand Up @@ -226,7 +235,10 @@ function _setHook(hook, command, projectRoot=process.cwd()) {

if (!gitRoot) {
console.info('[INFO] No `.git` root folder found, skipping')
return
return {
hookChanged: false,
success: false
}
}

Comment thread
younggglcy marked this conversation as resolved.
const hookCommand = PREPEND_SCRIPT + command
Expand All @@ -238,10 +250,23 @@ function _setHook(hook, command, projectRoot=process.cwd()) {
fs.mkdirSync(normalizedHookDirectory, { recursive: true })
}

if (fs.existsSync(hookPath)) {
const existingHook = fs.readFileSync(hookPath, { encoding: 'utf-8' })
if (existingHook === hookCommand) {
return {
hookChanged: false,
success: true
}
}
}
fs.writeFileSync(hookPath, hookCommand)
fs.chmodSync(hookPath, 0o0755)

console.info(`[INFO] Successfully set the ${hook} with command: ${command}`)
return {
hookChanged: true,
success: true
}
}

/**
Expand All @@ -268,6 +293,7 @@ async function removeHooks(projectRoot = process.cwd()) {
* Removes the pre-commit hook
* @param {string} hook
* @param {string} projectRoot
* @returns {boolean} whether the hook was removed
* @private
*/
function _removeHook(hook, projectRoot=process.cwd()) {
Expand All @@ -276,7 +302,9 @@ function _removeHook(hook, projectRoot=process.cwd()) {

if (fs.existsSync(hookPath)) {
fs.unlinkSync(hookPath)
return true
}
return false
}

/** Reads package.json file, returns package.json content and path
Expand Down
13 changes: 13 additions & 0 deletions simple-git-hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,19 @@ describe("Simple Git Hooks tests", () => {
expect(installedHooks).toEqual({ "pre-commit": TEST_SCRIPT });
});
});

describe('should silently succeed if all hooks are already installed', () => {
it('silent success by default', async () => {
createGitHooksFolder(PROJECT_WITH_CONF_IN_SEPARATE_JSON);

const output1 = execSync(`node ${require.resolve("./cli")}`, { cwd: PROJECT_WITH_CONF_IN_SEPARATE_JSON, encoding: 'utf8' });
expect(output1).toMatch(/\[INFO\] Successfully set all git hooks/);
expect(output1).toMatch(/\[INFO\] Successfully set the pre-commit with command: exit 1/);

const output2 = execSync(`node ${require.resolve("./cli")}`, { cwd: PROJECT_WITH_CONF_IN_SEPARATE_JSON, encoding: 'utf8' }).trim();
expect(output2).toBe('');
})
});
});

describe("ENV vars features tests", () => {
Expand Down