1'use strict' 2 3const fs = require('fs') 4const path = require('path') 5 6const test = require('tap').test 7const mr = require('npm-registry-mock') 8 9const npm = require('../../lib/npm.js') 10const common = require('../common-tap.js') 11 12const testdir = common.pkg 13const repo = path.join(testdir, 'repo') 14const prefix = path.join(testdir, 'prefix') 15const cache = common.cache 16 17var Tacks = require('tacks') 18var Dir = Tacks.Dir 19var File = Tacks.File 20 21let daemon 22let daemonPID 23let git 24let mockRegistry 25 26process.env.npm_config_prefix = prefix 27 28const fixture = new Tacks(Dir({ 29 repo: Dir({}), 30 prefix: Dir({}), 31 deps: Dir({ 32 parent: Dir({ 33 'package.json': File({ 34 name: 'parent', 35 version: '1.2.3', 36 dependencies: { 37 'child': 'git://localhost:' + common.gitPort + '/child.git' 38 } 39 }) 40 }), 41 child: Dir({ 42 'package.json': File({ 43 name: 'child', 44 version: '1.0.3', 45 main: 'dobuild.js', 46 scripts: { 47 'prepublish': 'exit 123', 48 'prepare': 'writer build-artifact' 49 }, 50 devDependencies: { 51 writer: 'file:' + path.join(testdir, 'deps', 'writer') 52 } 53 }) 54 }), 55 writer: Dir({ 56 'package.json': File({ 57 name: 'writer', 58 version: '1.0.0', 59 bin: 'writer.js' 60 }), 61 'writer.js': File(`#!/usr/bin/env node\n 62 require('fs').writeFileSync(process.argv[2], 'hello, world!') 63 `) 64 }) 65 }) 66})) 67 68test('setup', function (t) { 69 fixture.create(testdir) 70 setup(function (er, r) { 71 t.ifError(er, 'git started up successfully') 72 73 if (!er) { 74 daemon = r[r.length - 2] 75 daemonPID = r[r.length - 1] 76 } 77 78 mr({ 79 port: common.port 80 }, function (er, server) { 81 t.ifError(er, 'started mock registry') 82 mockRegistry = server 83 84 t.end() 85 }) 86 }) 87}) 88 89test('install from git repo with prepare script', function (t) { 90 const parent = path.join(testdir, 'deps', 'parent') 91 92 common.npm([ 93 'install', 94 '--no-save', 95 '--registry', common.registry, 96 '--cache', cache, 97 '--loglevel', 'error' 98 ], { 99 cwd: parent 100 }, function (err, code, stdout, stderr) { 101 if (err) { throw err } 102 t.equal(code, 0, 'exited successfully') 103 t.equal(stderr, '', 'no actual output on stderr') 104 105 const target = path.join(parent, 'node_modules', 'child', 'build-artifact') 106 fs.readFile(target, 'utf8', (err, data) => { 107 if (err) { throw err } 108 t.equal(data, 'hello, world!', 'build artifact written for git dep') 109 t.end() 110 }) 111 }) 112}) 113 114test('clean', function (t) { 115 mockRegistry.close() 116 daemon.on('close', t.end) 117 process.kill(daemonPID) 118}) 119 120function setup (cb) { 121 npm.load({ 122 prefix: testdir, 123 loglevel: 'silent' 124 }, function () { 125 git = require('../../lib/utils/git.js') 126 127 function startDaemon (cb) { 128 // start git server 129 const d = git.spawn( 130 [ 131 'daemon', 132 '--verbose', 133 '--listen=localhost', 134 '--export-all', 135 '--base-path=.', 136 '--reuseaddr', 137 '--port=' + common.gitPort 138 ], 139 { 140 cwd: repo, 141 env: process.env 142 } 143 ) 144 d.stderr.on('data', childFinder) 145 146 function childFinder (c) { 147 const cpid = c.toString().match(/^\[(\d+)\]/) 148 if (cpid[1]) { 149 this.removeListener('data', childFinder) 150 cb(null, [d, cpid[1]]) 151 } 152 } 153 } 154 155 const childPath = path.join(testdir, 'deps', 'child') 156 common.makeGitRepo({ 157 path: childPath, 158 commands: [ 159 git.chainableExec([ 160 'clone', '--bare', childPath, 'child.git' 161 ], { cwd: repo, env: process.env }), 162 startDaemon 163 ] 164 }, cb) 165 }) 166} 167