Skip to content
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

fix: always run hooks as CommonJS #396

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions lib/hook.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const fs = require('fs')
const resolve = require('path').resolve
const join = require('path').join

exports.generatedMessage = 'Generated by ghooks. Do not edit this file.'
const generatedMessage = require('./message.template.js').generatedMessage

exports.content = fs
.readFileSync(resolve(`${__dirname}/hook.template.raw`), 'UTF-8')
.replace('{{generated_message}}', exports.generatedMessage)
.replace('{{generated_message}}', generatedMessage)
.replace('{{node_modules_path}}', join(process.cwd(), '..').replace(/\\/g, '\\\\'))
24 changes: 20 additions & 4 deletions lib/install.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const fs = require('fs')
const resolve = require('path').resolve
const findup = require('findup')
const template = require('./hook.template')
const generatedMessage = require('./message.template.js').generatedMessage
const packageTemplate = require('./package.template')
const hookTemplate = require('./hook.template')

const JSON_INDENTATION = 2

const hooks = [
'applypatch-msg',
Expand All @@ -27,12 +31,17 @@ function installHooks() {
const gitRoot = findGitRoot()
if (gitRoot) {
const hooksDir = resolve(gitRoot, 'hooks')
hooks.forEach(install.bind(null, hooksDir))
installHooksIntoDir(hooksDir)
} else {
warnAboutGit()
}
}

function installHooksIntoDir(dir) {
installPackageJSON(dir)
hooks.forEach(install.bind(null, dir))
}

function findGitRoot() {
try {
return getGitRoot()
Expand Down Expand Up @@ -74,6 +83,13 @@ function warnAboutGit() {
)
}

function installPackageJSON(dir) {
ensureDirExists(dir)
const file = resolve(dir, 'package.json')
needsBackup(file) && backup(file)
fs.writeFileSync(file, JSON.stringify(packageTemplate.content, null, JSON_INDENTATION))
}

function install(dir, hook) {
ensureDirExists(dir)
const file = resolve(dir, hook)
Expand All @@ -90,15 +106,15 @@ function needsBackup(file) {
}

function generatedByGHooks(file) {
return !!fs.readFileSync(file, 'UTF-8').match(template.generatedMessage)
return !!fs.readFileSync(file, 'UTF-8').match(generatedMessage)
}

function backup(file) {
fs.renameSync(file, `${file}.bkp`)
}

function createExecutableHook(file) {
fs.writeFileSync(file, template.content)
fs.writeFileSync(file, hookTemplate.content)
fs.chmodSync(file, '755')
}

Expand Down
1 change: 1 addition & 0 deletions lib/message.template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.generatedMessage = 'Generated by ghooks. Do not edit this file.'
8 changes: 8 additions & 0 deletions lib/package.template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const generatedMessage = require('./message.template.js').generatedMessage

exports.content = {
type: 'commonjs',
'//': [
generatedMessage
]
}
3 changes: 2 additions & 1 deletion test/hook.template.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
require('./setup')()

describe('hook.template', () => {
const generatedMessage = require('../lib/message.template').generatedMessage
const template = require('../lib/hook.template')

it('replaces the {{generated_message}} token', () => {
expect(template.content).to.match(new RegExp(template.generatedMessage))
expect(template.content).to.match(new RegExp(generatedMessage))
})

})
42 changes: 42 additions & 0 deletions test/install.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ describe('install', function describeInstall() {
expect(fs.existsSync('.git/hooks')).to.be.true
})

it('creates a package.json', () => {
fsStub({'.git/hooks': {}})
install()

const hooks = fs.readdirSync('.git/hooks')
const packageContent = require('../lib/package.template').content
expect(hooks).to.include('package.json')
expect(JSON.parse(fs.readFileSync('.git/hooks/package.json', 'UTF-8'))).to.deep.equal(packageContent)
})

it('creates hook files', () => {
fsStub({'.git/hooks': {}})
install()
Expand Down Expand Up @@ -49,6 +59,38 @@ describe('install', function describeInstall() {
expectHook('post-rewrite', '.git/hooks/post-rewrite', '755')
})

describe('backs up an existing package.json', () => {

const existingGHookPackage = '// Generated by ghooks. Do not edit this file.'
const existingUserPackage = '# existing content'

it('does not keep a copy of an existing GHook package.json', () => {
fsStub({'.git/hooks': {
'package.json': existingGHookPackage,
}})

install()
const files = fs.readdirSync('.git/hooks')

expect(files).to.not.include('package.json.bkp')
expect(files).to.include('package.json')
})

it('backs up an existing user package.json', () => {
fsStub({'.git/hooks': {
'package.json': existingUserPackage,
}})

install()
const files = fs.readdirSync('.git/hooks')

expect(files).to.include('package.json.bkp')
expect(files).to.include('package.json')
expect(fs.readFileSync('.git/hooks/package.json.bkp', 'UTF-8')).to.equal(existingUserPackage)
})

})

describe('backing up existing hooks', () => {

const existingGHook = '// Generated by ghooks. Do not edit this file.'
Expand Down
11 changes: 11 additions & 0 deletions test/package.template.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require('./setup')()

describe('package.template', () => {
const generatedMessage = require('../lib/message.template').generatedMessage
const template = require('../lib/package.template')

it('replaces the {{generated_message}} token', () => {
expect(template.content).to.match(new RegExp(generatedMessage))
})

})