@@ -22,27 +22,64 @@ if (!global.setImmediate || !require('timers').setImmediate) {
22
22
}
23
23
24
24
var spawn = require ( 'child_process' ) . spawn
25
+ const spawnSync = require ( 'child_process' ) . spawnSync
25
26
var path = require ( 'path' )
26
27
28
+ // space these out to help prevent collisions
29
+ const testId = 3 * ( + process . env . TAP_CHILD_ID || 0 )
30
+
27
31
// provide a working dir unique to each test
28
32
const main = require . main . filename
29
- exports . pkg = path . resolve ( path . dirname ( main ) , path . basename ( main , '.js' ) )
33
+ const testName = path . basename ( main , '.js' )
34
+ exports . pkg = path . resolve ( path . dirname ( main ) , testName )
35
+ var commonCache = path . resolve ( __dirname , 'npm_cache_' + testName )
36
+ exports . cache = commonCache
37
+
30
38
const mkdirp = require ( 'mkdirp' )
31
39
const rimraf = require ( 'rimraf' )
40
+ rimraf . sync ( exports . pkg )
41
+ rimraf . sync ( commonCache )
32
42
mkdirp . sync ( exports . pkg )
43
+ mkdirp . sync ( commonCache )
44
+ // if we're in sudo mode, make sure that the cache is not root-owned
45
+ const isRoot = process . getuid && process . getuid ( ) === 0
46
+ const isSudo = isRoot && process . env . SUDO_UID && process . env . SUDO_GID
47
+ if ( isSudo ) {
48
+ const sudoUid = + process . env . SUDO_UID
49
+ const sudoGid = + process . env . SUDO_GID
50
+ fs . chownSync ( commonCache , sudoUid , sudoGid )
51
+ }
52
+
53
+ const returnCwd = path . dirname ( __dirname )
54
+ const find = require ( 'which' ) . sync ( 'find' )
33
55
require ( 'tap' ) . teardown ( ( ) => {
56
+ // work around windows folder locking
57
+ process . chdir ( returnCwd )
34
58
try {
35
- rimraf . sync ( exports . pkg )
59
+ if ( isSudo ) {
60
+ // running tests as sudo. ensure we didn't leave any root-owned
61
+ // files in the cache by mistake.
62
+ const args = [ commonCache , '-uid' , '0' ]
63
+ const found = spawnSync ( find , args )
64
+ const output = found && found . stdout && found . stdout . toString ( )
65
+ if ( output . length ) {
66
+ const er = new Error ( 'Root-owned files left in cache!' )
67
+ er . testName = main
68
+ er . files = output . trim ( ) . split ( '\n' )
69
+ throw er
70
+ }
71
+ }
72
+ if ( ! process . env . NO_TEST_CLEANUP ) {
73
+ rimraf . sync ( exports . pkg )
74
+ rimraf . sync ( commonCache )
75
+ }
36
76
} catch ( e ) {
37
77
if ( process . platform !== 'win32' ) {
38
78
throw e
39
79
}
40
80
}
41
81
} )
42
82
43
- // space these out to help prevent collisions
44
- const testId = 3 * ( + process . env . TAP_CHILD_ID || 0 )
45
-
46
83
var port = exports . port = 15443 + testId
47
84
exports . registry = 'http://localhost:' + port
48
85
@@ -59,8 +96,8 @@ ourenv.npm_config_progress = 'false'
59
96
ourenv . npm_config_metrics = 'false'
60
97
ourenv . npm_config_audit = 'false'
61
98
62
- var npm_config_cache = path . resolve ( __dirname , 'npm_cache_' + testId )
63
- ourenv . npm_config_cache = exports . npm_config_cache = npm_config_cache
99
+ ourenv . npm_config_unsafe_perm = 'true'
100
+ ourenv . npm_config_cache = commonCache
64
101
ourenv . npm_config_userconfig = exports . npm_config_userconfig = configCommon . userconfig
65
102
ourenv . npm_config_globalconfig = exports . npm_config_globalconfig = configCommon . globalconfig
66
103
ourenv . npm_config_global_style = 'false'
@@ -94,7 +131,10 @@ exports.npm = function (cmd, opts, cb) {
94
131
opts . env = opts . env || process . env
95
132
if ( opts . env . _storage ) opts . env = Object . assign ( { } , opts . env . _storage )
96
133
if ( ! opts . env . npm_config_cache ) {
97
- opts . env . npm_config_cache = npm_config_cache
134
+ opts . env . npm_config_cache = commonCache
135
+ }
136
+ if ( ! opts . env . npm_config_unsafe_perm ) {
137
+ opts . env . npm_config_unsafe_perm = 'true'
98
138
}
99
139
if ( ! opts . env . npm_config_send_metrics ) {
100
140
opts . env . npm_config_send_metrics = 'false'
0 commit comments