You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
3.9 KiB

'use strict'
const fs = require('fs')
const path = require('path')
const osenv = require('osenv')
const rimraf = require('rimraf')
const test = require('tap').test
const mr = require('npm-registry-mock')
const npm = require('../../lib/npm.js')
const common = require('../common-tap.js')
const testdir = path.resolve(__dirname, path.basename(__filename, '.js'))
const repo = path.join(testdir, 'repo')
const prefix = path.join(testdir, 'prefix')
const cache = path.join(testdir, 'cache')
var Tacks = require('tacks')
var Dir = Tacks.Dir
var File = Tacks.File
let daemon
let daemonPID
let git
let mockRegistry
process.env.npm_config_prefix = prefix
const fixture = new Tacks(Dir({
repo: Dir({}),
prefix: Dir({}),
cache: Dir({}),
deps: Dir({
parent: Dir({
'package.json': File({
name: 'parent',
version: '1.2.3',
dependencies: {
'child': 'git://localhost:1234/child.git'
}
})
}),
child: Dir({
'package.json': File({
name: 'child',
version: '1.0.3',
main: 'dobuild.js',
scripts: {
'prepublish': 'exit 123',
'prepare': 'writer build-artifact'
},
devDependencies: {
writer: 'file:' + path.join(testdir, 'deps', 'writer')
}
})
}),
writer: Dir({
'package.json': File({
name: 'writer',
version: '1.0.0',
bin: 'writer.js'
}),
'writer.js': File(`#!/usr/bin/env node\n
require('fs').writeFileSync(process.argv[2], 'hello, world!')
`)
})
})
}))
test('setup', function (t) {
bootstrap()
setup(function (er, r) {
t.ifError(er, 'git started up successfully')
if (!er) {
daemon = r[r.length - 2]
daemonPID = r[r.length - 1]
}
mr({
port: common.port
}, function (er, server) {
t.ifError(er, 'started mock registry')
mockRegistry = server
t.end()
})
})
})
test('install from git repo with prepare script', function (t) {
const parent = path.join(testdir, 'deps', 'parent')
common.npm([
'install',
'--no-save',
'--registry', common.registry,
'--cache', cache,
'--loglevel', 'error'
], {
cwd: parent
}, function (err, code, stdout, stderr) {
if (err) { throw err }
t.equal(code, 0, 'exited successfully')
t.equal(stderr, '', 'no actual output on stderr')
const target = path.join(parent, 'node_modules', 'child', 'build-artifact')
fs.readFile(target, 'utf8', (err, data) => {
if (err) { throw err }
t.equal(data, 'hello, world!', 'build artifact written for git dep')
t.end()
})
})
})
test('clean', function (t) {
mockRegistry.close()
daemon.on('close', function () {
cleanup()
t.end()
})
process.kill(daemonPID)
})
function bootstrap () {
fixture.create(testdir)
}
function setup (cb) {
npm.load({
prefix: testdir,
loglevel: 'silent'
}, function () {
git = require('../../lib/utils/git.js')
function startDaemon (cb) {
// start git server
const d = git.spawn(
[
'daemon',
'--verbose',
'--listen=localhost',
'--export-all',
'--base-path=.',
'--reuseaddr',
'--port=1234'
],
{
cwd: repo,
env: process.env
}
)
d.stderr.on('data', childFinder)
function childFinder (c) {
const cpid = c.toString().match(/^\[(\d+)\]/)
if (cpid[1]) {
this.removeListener('data', childFinder)
cb(null, [d, cpid[1]])
}
}
}
const childPath = path.join(testdir, 'deps', 'child')
common.makeGitRepo({
path: childPath,
commands: [
git.chainableExec([
'clone', '--bare', childPath, 'child.git'
], { cwd: repo, env: process.env }),
startDaemon
]
}, cb)
})
}
function cleanup () {
process.chdir(osenv.tmpdir())
rimraf.sync(testdir)
}