'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) }