Skip to content
This repository has been archived by the owner on Aug 17, 2019. It is now read-only.

Commit

Permalink
fix(lifecycle): detect binding.gyp for default install lifecycle (#46)
Browse files Browse the repository at this point in the history
Fixes: #45
  • Loading branch information
caleblloyd authored and zkat committed Apr 8, 2018
1 parent 7fe4703 commit 9149631
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
19 changes: 19 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ class Installer {
? pkg
: this.updateFromField(dep, pkg).then(() => pkg)
)
.then(pkg => (pkg.scripts && pkg.scripts.install)
? pkg
: this.updateInstallScript(dep, pkg).then(() => pkg)
)
.tap(pkg => { pkgJsons.set(dep, pkg) })
}, {concurrency: 100, Promise: BB})
.then(() => pkgJsons)
Expand Down Expand Up @@ -311,6 +315,21 @@ class Installer {
.then(pkg)
}

updateInstallScript (dep, pkg) {
const depPath = dep.path(this.prefix)
return statAsync(path.join(depPath, 'binding.gyp'))
.catch(err => { if (err.code !== 'ENOENT') { throw err } })
.then(stat => {
if (stat) {
if (!pkg.scripts) {
pkg.scripts = {}
}
pkg.scripts.install = 'node-gyp rebuild'
}
})
.then(pkg)
}

// A cute little mark-and-sweep collector!
garbageCollect (tree) {
if (!this.failedDeps.size) { return }
Expand Down
75 changes: 75 additions & 0 deletions test/specs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const pkgVersion = '1.0.0'
const writeEnvScript = process.platform === 'win32'
? 'echo %npm_lifecycle_event% > %npm_lifecycle_event%'
: 'echo $npm_lifecycle_event > $npm_lifecycle_event'
const binarySuffix = process.platform === 'win32'
? '.exe'
: ''

const prefix = require('../lib/test-dir')(__filename)

Expand Down Expand Up @@ -654,6 +657,78 @@ test('skips lifecycle scripts with ignoreScripts is set', t => {
})
})

test('adds install script when binding.gyp is present', t => {
const originalConsoleLog = console.log
console.log = () => {}

const fixture = new Tacks(Dir({
'package.json': File({
name: pkgName,
version: pkgVersion,
dependencies: {
a: '^1',
b: '^1'
}
}),
'package-lock.json': File({
dependencies: {
a: { version: '1.0.0' },
b: { version: '1.0.0' }
},
lockfileVersion: 1
})
}))
fixture.create(prefix)

extract = (name, child, childPath, opts) => {
const pkg = (child.name === 'a')
? {
name: 'a',
version: '1.0.0'
}
: {
name: 'b',
version: '1.0.0',
scripts: {
install: 'exit 0'
}
}
const files = new Tacks(Dir({
'package.json': File(pkg),
'binding.gyp': File({
'targets': [
{
'target_name': 'hello',
'type': 'executable',
'sources': [
'hello.cc'
]
}
]
}),
'hello.cc': File(
'#include <iostream>\n' +
'int main() {\n' +
'std::cout << "hello";\n' +
'return 0;\n' +
'}\n'
)
}))
files.create(childPath)
}

return run().then(details => {
t.equal(details.pkgCount, 2)
t.ok(fs.statSync(path.join(prefix, 'node_modules', 'a', 'build', 'Release', 'hello' + binarySuffix)), 'dep a binary is built')
t.throws(() => {
fs.statSync(path.join(prefix, 'node_modules', 'b', 'build', 'Release', 'hello' + binarySuffix))
}, 'dep b binary is not built')

fixtureHelper.teardown()
console.log = originalConsoleLog
})
})

test('handles JSON docs that contain a BOM', t => {
t.plan(2)
const Installer = requireInject('../../index.js', {/* just don't want to cache */})
Expand Down

0 comments on commit 9149631

Please sign in to comment.