6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import * as fs from 'fs' ;
10
- import * as path from 'path' ;
11
- import * as tmp from 'tmp' ;
12
- import * as os from 'os' ;
9
+ import fs from 'node:fs/promises' ;
10
+ import path from 'node:path' ;
11
+ import os from 'node:os' ;
13
12
14
13
import {
15
14
BazelExpandedValue ,
16
15
BazelFileInfo ,
17
16
resolveBazelFile ,
18
17
resolveBinaryWithRunfilesGracefully ,
19
- } from './bazel' ;
18
+ } from './bazel.mjs ' ;
20
19
import {
21
20
PackageMappings ,
22
21
readPackageJsonContents ,
23
22
updateMappingsForPackageJson ,
24
- } from './package_json' ;
25
- import { addWritePermissionFlag , writeExecutableFile } from './file_system_utils' ;
23
+ } from './package_json.mjs ' ;
24
+ import { addWritePermissionFlag , writeExecutableFile } from './file_system_utils.mjs ' ;
26
25
import {
27
26
expandEnvironmentVariableSubstitutions ,
28
27
getBinaryPassThroughScript ,
29
28
prependToPathVariable ,
30
29
runCommandInChildProcess ,
31
- } from './process_utils' ;
32
-
33
- import { ENVIRONMENT_TMP_PLACEHOLDER } from './constants' ;
34
- import { debug } from './debug' ;
30
+ } from './process_utils.mjs' ;
31
+ import { ENVIRONMENT_TMP_PLACEHOLDER } from './constants.mjs' ;
32
+ import { debug } from './debug.mjs' ;
35
33
36
34
/** Error class that is used when an integration command fails. */
37
35
class IntegrationTestCommandError extends Error { }
@@ -55,7 +53,7 @@ export class TestRunner {
55
53
private readonly testFiles : BazelFileInfo [ ] ,
56
54
private readonly testPackage : string ,
57
55
private readonly testPackageRelativeWorkingDir : string ,
58
- private readonly toolMappings : Record < string , BazelFileInfo > ,
56
+ private readonly toolMappings : Record < string , Pick < BazelFileInfo , 'shortPath' > > ,
59
57
private readonly npmPackageMappings : Record < string , BazelFileInfo > ,
60
58
private readonly commands : [ [ binary : BazelExpandedValue , ...args : string [ ] ] ] ,
61
59
environment : EnvironmentConfig ,
@@ -70,13 +68,13 @@ export class TestRunner {
70
68
71
69
// Create the test sandbox directory. The working directory does not need to
72
70
// be explicitly created here as the test file copying should create the folder.
73
- await fs . promises . mkdir ( testSandboxDir ) ;
71
+ await fs . mkdir ( testSandboxDir ) ;
74
72
75
73
const toolMappings = await this . _setupToolMappingsForTest ( testTmpDir ) ;
76
74
const testEnv = await this . _buildTestProcessEnvironment ( testTmpDir , toolMappings . binDir ) ;
77
75
78
76
debug ( `Temporary directory for integration test: ${ path . normalize ( testTmpDir ) } ` ) ;
79
- debug ( `Test files are copied into: ${ path . normalize ( testSandboxDir ) } ` ) ;
77
+ debug ( `Test files are copied into: ${ path . normalize ( testWorkingDir ) } ` ) ;
80
78
console . info ( `Running test in directory: ${ path . normalize ( testWorkingDir ) } ` ) ;
81
79
82
80
await this . _copyTestFilesToDirectory ( testSandboxDir ) ;
@@ -90,7 +88,7 @@ export class TestRunner {
90
88
// We keep the temporary directory on disk if the users wants to debug the test.
91
89
if ( ! this . isTestDebugMode ) {
92
90
debug ( 'Deleting the integration test temporary directory..' ) ;
93
- await fs . promises . rm ( testTmpDir , { force : true , recursive : true , maxRetries : 3 } ) ;
91
+ await fs . rm ( testTmpDir , { force : true , recursive : true , maxRetries : 3 } ) ;
94
92
}
95
93
}
96
94
}
@@ -111,17 +109,7 @@ export class TestRunner {
111
109
// system directories are always writable. See:
112
110
// Linux: https://github.com/bazelbuild/bazel/blob/d35f923b098e4dc9c90b1ab66b413c216bdee638/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java#L280.
113
111
// Darwin: https://github.com/bazelbuild/bazel/blob/d35f923b098e4dc9c90b1ab66b413c216bdee638/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java#L170.
114
- return new Promise ( ( resolve , reject ) => {
115
- tmp . dir (
116
- {
117
- template : 'ng-integration-test-XXXXXX' ,
118
- // Always keep the directory for debugging. We will handle the deletion
119
- // manually and need full control over the directory persistence.
120
- keep : true ,
121
- } ,
122
- ( err , tmpPath ) => ( err ? reject ( err ) : resolve ( path . resolve ( tmpPath ) ) ) ,
123
- ) ;
124
- } ) ;
112
+ return fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'ng-integration-test' ) ) ;
125
113
}
126
114
127
115
/**
@@ -149,8 +137,8 @@ export class TestRunner {
149
137
const outAbsolutePath = path . join ( tmpDir , outRelativePath ) ;
150
138
const resolvedFilePath = resolveBazelFile ( file ) ;
151
139
152
- await fs . promises . mkdir ( path . dirname ( outAbsolutePath ) , { recursive : true } ) ;
153
- await fs . promises . copyFile ( resolvedFilePath , outAbsolutePath ) ;
140
+ await fs . mkdir ( path . dirname ( outAbsolutePath ) , { recursive : true } ) ;
141
+ await fs . copyFile ( resolvedFilePath , outAbsolutePath ) ;
154
142
155
143
// Bazel removes the write permission from all generated files. Since we copied
156
144
// the test files over to a directory, we want to re-add the write permission in
@@ -164,17 +152,16 @@ export class TestRunner {
164
152
* directory can be added to the `$PATH` later when commands are executed.
165
153
*/
166
154
private async _setupToolMappingsForTest ( testDir : string ) {
167
- const toolBinDir = path . join ( testDir , '. integration-bazel-tool-bin' ) ;
155
+ const toolBinDir = path . join ( testDir , 'integration-bazel-tool-bin' ) ;
168
156
169
157
// Create the bin directory for the tool mappings.
170
- await fs . promises . mkdir ( toolBinDir , { recursive : true } ) ;
158
+ await fs . mkdir ( toolBinDir , { recursive : true } ) ;
171
159
172
160
for ( const [ toolName , toolFile ] of Object . entries ( this . toolMappings ) ) {
173
161
const toolAbsolutePath = resolveBazelFile ( toolFile ) ;
174
162
const passThroughScripts = getBinaryPassThroughScript ( toolAbsolutePath ) ;
175
163
const toolDelegateBasePath = path . join ( toolBinDir , toolName ) ;
176
164
177
- await writeExecutableFile ( `${ toolDelegateBasePath } .cmd` , passThroughScripts . cmd ) ;
178
165
await writeExecutableFile ( `${ toolDelegateBasePath } .sh` , passThroughScripts . bash ) ;
179
166
await writeExecutableFile ( toolDelegateBasePath , passThroughScripts . bash ) ;
180
167
}
@@ -207,7 +194,7 @@ export class TestRunner {
207
194
208
195
// Write the new `package.json` file to the test directory, overwriting
209
196
// the `package.json` file initially copied as a test input/file.
210
- await fs . promises . writeFile ( pkgJsonPath , JSON . stringify ( newPkgJson , null , 2 ) ) ;
197
+ await fs . writeFile ( pkgJsonPath , JSON . stringify ( newPkgJson , null , 2 ) ) ;
211
198
}
212
199
213
200
/**
@@ -230,15 +217,21 @@ export class TestRunner {
230
217
if ( value . containsExpansion ) {
231
218
envValue = await resolveBinaryWithRunfilesGracefully ( envValue ) ;
232
219
} else if ( envValue === ENVIRONMENT_TMP_PLACEHOLDER ) {
233
- envValue = path . join ( testTmpDir , `. tmp-env-${ i ++ } ` ) ;
234
- await fs . promises . mkdir ( envValue ) ;
220
+ envValue = path . join ( testTmpDir , `tmp-env-${ i ++ } ` ) ;
221
+ await fs . mkdir ( envValue ) ;
235
222
}
236
223
237
224
testEnv [ variableName ] = envValue ;
238
225
}
239
226
240
227
const commandPath = prependToPathVariable ( toolsBinDir , testEnv . PATH ?? '' ) ;
241
- return { ...testEnv , PATH : commandPath } ;
228
+ return {
229
+ ...testEnv ,
230
+ PATH : commandPath ,
231
+ // `rules_js` binaries are never build actions, so can be set to `.`.
232
+ // See: https://github.com/aspect-build/rules_js/blob/674f689ff56b962c3cb0509a4b97e99af049a6eb/js/private/js_binary.sh.tpl#L200-L207
233
+ BAZEL_BINDIR : '.' ,
234
+ } ;
242
235
}
243
236
244
237
/**
@@ -301,16 +294,9 @@ export class TestRunner {
301
294
private _assignDefaultEnvironmentVariables ( baseEnv : EnvironmentConfig ) : EnvironmentConfig {
302
295
const defaults : EnvironmentConfig = {
303
296
'HOME' : { value : ENVIRONMENT_TMP_PLACEHOLDER , containsExpansion : false } ,
297
+ 'PROFILE' : { value : ENVIRONMENT_TMP_PLACEHOLDER , containsExpansion : false } ,
304
298
} ;
305
299
306
- // Support windows-specific system variables. We don't want to always assign these as
307
- // it would result in unnecessary directories being created all the time.
308
- if ( os . platform ( ) === 'win32' ) {
309
- defaults . USERPROFILE = { value : ENVIRONMENT_TMP_PLACEHOLDER , containsExpansion : false } ;
310
- defaults . APPDATA = { value : ENVIRONMENT_TMP_PLACEHOLDER , containsExpansion : false } ;
311
- defaults . LOCALAPPDATA = { value : ENVIRONMENT_TMP_PLACEHOLDER , containsExpansion : false } ;
312
- }
313
-
314
300
return { ...defaults , ...baseEnv } ;
315
301
}
316
302
}
0 commit comments