@wordpress/env 11.4.0 → 11.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* External dependencies
|
|
4
4
|
*/
|
|
5
5
|
const path = require( 'path' );
|
|
6
|
-
const
|
|
6
|
+
const { existsSync, promises: fsPromises } = require( 'fs' );
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Internal dependencies
|
|
@@ -60,7 +60,7 @@ module.exports = async function loadConfig(
|
|
|
60
60
|
// If a custom config path was provided, verify the file exists.
|
|
61
61
|
if ( customConfigPath ) {
|
|
62
62
|
try {
|
|
63
|
-
await
|
|
63
|
+
await fsPromises.stat( configFilePath );
|
|
64
64
|
} catch {
|
|
65
65
|
throw new ValidationError(
|
|
66
66
|
`Config file not found: ${ configFilePath }`
|
|
@@ -68,11 +68,23 @@ module.exports = async function loadConfig(
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
const
|
|
72
|
-
|
|
71
|
+
const cacheDirectory = await getCacheDirectory();
|
|
72
|
+
|
|
73
|
+
// If a cache already exists at the "legacy" path (which consists of a
|
|
74
|
+
// simple but opaque md5 hash), honor it.
|
|
75
|
+
let cacheDirectoryPath = path.resolve(
|
|
76
|
+
cacheDirectory,
|
|
73
77
|
md5( configFilePath )
|
|
74
78
|
);
|
|
75
79
|
|
|
80
|
+
// Otherwise, prefer a more descriptive path.
|
|
81
|
+
if ( ! existsSync( cacheDirectoryPath ) ) {
|
|
82
|
+
cacheDirectoryPath = path.resolve(
|
|
83
|
+
cacheDirectory,
|
|
84
|
+
buildDescriptiveCacheDirectoryName( configFilePath )
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
76
88
|
// Parse any configuration we found in the given directory.
|
|
77
89
|
// This comes merged and prepared for internal consumption.
|
|
78
90
|
let config = await parseConfig(
|
|
@@ -124,6 +136,53 @@ module.exports = async function loadConfig(
|
|
|
124
136
|
};
|
|
125
137
|
};
|
|
126
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Derives the descriptive cache directory name for a given config file path.
|
|
141
|
+
*
|
|
142
|
+
* Format: `wp-env-<project-dir>[-<variant>]-<short-hash>`.
|
|
143
|
+
*
|
|
144
|
+
* @param {string} configFilePath Absolute path to the resolved config file.
|
|
145
|
+
*
|
|
146
|
+
* @return {string} The directory name to use as the cache directory.
|
|
147
|
+
*/
|
|
148
|
+
function buildDescriptiveCacheDirectoryName( configFilePath ) {
|
|
149
|
+
const projectDirectory = path.basename( path.dirname( configFilePath ) );
|
|
150
|
+
const variant = getConfigVariant( configFilePath );
|
|
151
|
+
const shortHash = md5( configFilePath ).slice( 0, 8 );
|
|
152
|
+
|
|
153
|
+
const segments = [ 'wp-env', projectDirectory ];
|
|
154
|
+
if ( variant ) {
|
|
155
|
+
segments.push( variant );
|
|
156
|
+
}
|
|
157
|
+
segments.push( shortHash );
|
|
158
|
+
|
|
159
|
+
return segments.join( '-' );
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Extracts a variant label from a config file name.
|
|
164
|
+
*
|
|
165
|
+
* Example: `.wp-env.test.json` -> 'test'
|
|
166
|
+
*
|
|
167
|
+
* @param {string} configFilePath Absolute path to the resolved config file.
|
|
168
|
+
*
|
|
169
|
+
* @return {string} The sanitized variant, or '' if none could be derived.
|
|
170
|
+
*/
|
|
171
|
+
function getConfigVariant( configFilePath ) {
|
|
172
|
+
const basename = path.basename( configFilePath, '.json' );
|
|
173
|
+
|
|
174
|
+
let variant;
|
|
175
|
+
if ( basename === '.wp-env' ) {
|
|
176
|
+
variant = '';
|
|
177
|
+
} else if ( basename.startsWith( '.wp-env.' ) ) {
|
|
178
|
+
variant = basename.slice( '.wp-env.'.length );
|
|
179
|
+
} else {
|
|
180
|
+
variant = basename;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return variant.replace( /[^a-zA-Z0-9._]+/g, '-' ).replace( /^-+|-+$/g, '' );
|
|
184
|
+
}
|
|
185
|
+
|
|
127
186
|
/**
|
|
128
187
|
* Checks to see whether or not there is any configuration present in the directory.
|
|
129
188
|
*
|
|
@@ -134,7 +193,7 @@ module.exports = async function loadConfig(
|
|
|
134
193
|
async function hasLocalConfig( configFilePaths ) {
|
|
135
194
|
for ( const filePath of configFilePaths ) {
|
|
136
195
|
try {
|
|
137
|
-
await
|
|
196
|
+
await fsPromises.stat( filePath );
|
|
138
197
|
return true;
|
|
139
198
|
} catch {}
|
|
140
199
|
}
|
|
@@ -5,7 +5,7 @@ exports[`Config Integration should load local and override configuration files 1
|
|
|
5
5
|
"configDirectoryPath": "/test/gutenberg",
|
|
6
6
|
"customConfigPath": null,
|
|
7
7
|
"detectedLocalConfig": true,
|
|
8
|
-
"dockerComposeConfigPath": "/cache/
|
|
8
|
+
"dockerComposeConfigPath": "/cache/wp-env-gutenberg-5fea4c56/docker-compose.yml",
|
|
9
9
|
"env": {
|
|
10
10
|
"development": {
|
|
11
11
|
"config": {
|
|
@@ -22,10 +22,10 @@ exports[`Config Integration should load local and override configuration files 1
|
|
|
22
22
|
},
|
|
23
23
|
"coreSource": {
|
|
24
24
|
"basename": "WordPress",
|
|
25
|
-
"clonePath": "/cache/
|
|
26
|
-
"path": "/cache/
|
|
25
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
26
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
27
27
|
"ref": "trunk",
|
|
28
|
-
"testsPath": "/cache/
|
|
28
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
29
29
|
"type": "git",
|
|
30
30
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
31
31
|
},
|
|
@@ -54,10 +54,10 @@ exports[`Config Integration should load local and override configuration files 1
|
|
|
54
54
|
},
|
|
55
55
|
"coreSource": {
|
|
56
56
|
"basename": "WordPress",
|
|
57
|
-
"clonePath": "/cache/
|
|
58
|
-
"path": "/cache/
|
|
57
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
58
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
59
59
|
"ref": "trunk",
|
|
60
|
-
"testsPath": "/cache/
|
|
60
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
61
61
|
"type": "git",
|
|
62
62
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
63
63
|
},
|
|
@@ -81,7 +81,7 @@ exports[`Config Integration should load local and override configuration files 1
|
|
|
81
81
|
},
|
|
82
82
|
"name": "gutenberg",
|
|
83
83
|
"testsEnvironment": true,
|
|
84
|
-
"workDirectoryPath": "/cache/
|
|
84
|
+
"workDirectoryPath": "/cache/wp-env-gutenberg-5fea4c56",
|
|
85
85
|
}
|
|
86
86
|
`;
|
|
87
87
|
|
|
@@ -90,7 +90,7 @@ exports[`Config Integration should load local configuration file 1`] = `
|
|
|
90
90
|
"configDirectoryPath": "/test/gutenberg",
|
|
91
91
|
"customConfigPath": null,
|
|
92
92
|
"detectedLocalConfig": true,
|
|
93
|
-
"dockerComposeConfigPath": "/cache/
|
|
93
|
+
"dockerComposeConfigPath": "/cache/wp-env-gutenberg-5fea4c56/docker-compose.yml",
|
|
94
94
|
"env": {
|
|
95
95
|
"development": {
|
|
96
96
|
"config": {
|
|
@@ -107,10 +107,10 @@ exports[`Config Integration should load local configuration file 1`] = `
|
|
|
107
107
|
},
|
|
108
108
|
"coreSource": {
|
|
109
109
|
"basename": "WordPress",
|
|
110
|
-
"clonePath": "/cache/
|
|
111
|
-
"path": "/cache/
|
|
110
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
111
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
112
112
|
"ref": "trunk",
|
|
113
|
-
"testsPath": "/cache/
|
|
113
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
114
114
|
"type": "git",
|
|
115
115
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
116
116
|
},
|
|
@@ -139,10 +139,10 @@ exports[`Config Integration should load local configuration file 1`] = `
|
|
|
139
139
|
},
|
|
140
140
|
"coreSource": {
|
|
141
141
|
"basename": "WordPress",
|
|
142
|
-
"clonePath": "/cache/
|
|
143
|
-
"path": "/cache/
|
|
142
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
143
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
144
144
|
"ref": "trunk",
|
|
145
|
-
"testsPath": "/cache/
|
|
145
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
146
146
|
"type": "git",
|
|
147
147
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
148
148
|
},
|
|
@@ -166,7 +166,7 @@ exports[`Config Integration should load local configuration file 1`] = `
|
|
|
166
166
|
},
|
|
167
167
|
"name": "gutenberg",
|
|
168
168
|
"testsEnvironment": true,
|
|
169
|
-
"workDirectoryPath": "/cache/
|
|
169
|
+
"workDirectoryPath": "/cache/wp-env-gutenberg-5fea4c56",
|
|
170
170
|
}
|
|
171
171
|
`;
|
|
172
172
|
|
|
@@ -175,7 +175,7 @@ exports[`Config Integration should use default configuration 1`] = `
|
|
|
175
175
|
"configDirectoryPath": "/test/gutenberg",
|
|
176
176
|
"customConfigPath": null,
|
|
177
177
|
"detectedLocalConfig": true,
|
|
178
|
-
"dockerComposeConfigPath": "/cache/
|
|
178
|
+
"dockerComposeConfigPath": "/cache/wp-env-gutenberg-5fea4c56/docker-compose.yml",
|
|
179
179
|
"env": {
|
|
180
180
|
"development": {
|
|
181
181
|
"config": {
|
|
@@ -192,10 +192,10 @@ exports[`Config Integration should use default configuration 1`] = `
|
|
|
192
192
|
},
|
|
193
193
|
"coreSource": {
|
|
194
194
|
"basename": "WordPress",
|
|
195
|
-
"clonePath": "/cache/
|
|
196
|
-
"path": "/cache/
|
|
195
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
196
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
197
197
|
"ref": "100.0.0",
|
|
198
|
-
"testsPath": "/cache/
|
|
198
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
199
199
|
"type": "git",
|
|
200
200
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
201
201
|
},
|
|
@@ -224,10 +224,10 @@ exports[`Config Integration should use default configuration 1`] = `
|
|
|
224
224
|
},
|
|
225
225
|
"coreSource": {
|
|
226
226
|
"basename": "WordPress",
|
|
227
|
-
"clonePath": "/cache/
|
|
228
|
-
"path": "/cache/
|
|
227
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
228
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
229
229
|
"ref": "100.0.0",
|
|
230
|
-
"testsPath": "/cache/
|
|
230
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
231
231
|
"type": "git",
|
|
232
232
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
233
233
|
},
|
|
@@ -251,7 +251,7 @@ exports[`Config Integration should use default configuration 1`] = `
|
|
|
251
251
|
},
|
|
252
252
|
"name": "gutenberg",
|
|
253
253
|
"testsEnvironment": true,
|
|
254
|
-
"workDirectoryPath": "/cache/
|
|
254
|
+
"workDirectoryPath": "/cache/wp-env-gutenberg-5fea4c56",
|
|
255
255
|
}
|
|
256
256
|
`;
|
|
257
257
|
|
|
@@ -260,7 +260,7 @@ exports[`Config Integration should use environment variables over local and over
|
|
|
260
260
|
"configDirectoryPath": "/test/gutenberg",
|
|
261
261
|
"customConfigPath": null,
|
|
262
262
|
"detectedLocalConfig": true,
|
|
263
|
-
"dockerComposeConfigPath": "/cache/
|
|
263
|
+
"dockerComposeConfigPath": "/cache/wp-env-gutenberg-5fea4c56/docker-compose.yml",
|
|
264
264
|
"env": {
|
|
265
265
|
"development": {
|
|
266
266
|
"config": {
|
|
@@ -277,10 +277,10 @@ exports[`Config Integration should use environment variables over local and over
|
|
|
277
277
|
},
|
|
278
278
|
"coreSource": {
|
|
279
279
|
"basename": "WordPress",
|
|
280
|
-
"clonePath": "/cache/
|
|
281
|
-
"path": "/cache/
|
|
280
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
281
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
282
282
|
"ref": "trunk",
|
|
283
|
-
"testsPath": "/cache/
|
|
283
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
284
284
|
"type": "git",
|
|
285
285
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
286
286
|
},
|
|
@@ -310,10 +310,10 @@ exports[`Config Integration should use environment variables over local and over
|
|
|
310
310
|
},
|
|
311
311
|
"coreSource": {
|
|
312
312
|
"basename": "WordPress",
|
|
313
|
-
"clonePath": "/cache/
|
|
314
|
-
"path": "/cache/
|
|
313
|
+
"clonePath": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
314
|
+
"path": "/cache/wp-env-gutenberg-5fea4c56/WordPress",
|
|
315
315
|
"ref": "trunk",
|
|
316
|
-
"testsPath": "/cache/
|
|
316
|
+
"testsPath": "/cache/wp-env-gutenberg-5fea4c56/tests-WordPress",
|
|
317
317
|
"type": "git",
|
|
318
318
|
"url": "https://github.com/WordPress/WordPress.git",
|
|
319
319
|
},
|
|
@@ -338,6 +338,6 @@ exports[`Config Integration should use environment variables over local and over
|
|
|
338
338
|
},
|
|
339
339
|
"name": "gutenberg",
|
|
340
340
|
"testsEnvironment": true,
|
|
341
|
-
"workDirectoryPath": "/cache/
|
|
341
|
+
"workDirectoryPath": "/cache/wp-env-gutenberg-5fea4c56",
|
|
342
342
|
}
|
|
343
343
|
`;
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
6
|
const { readFile } = require( 'fs' ).promises;
|
|
7
|
+
const { existsSync } = require( 'fs' );
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Internal dependencies
|
|
10
11
|
*/
|
|
11
12
|
const loadConfig = require( '../load-config' );
|
|
12
13
|
const detectDirectoryType = require( '../detect-directory-type' );
|
|
14
|
+
const md5 = require( '../../md5' );
|
|
13
15
|
|
|
14
16
|
jest.mock( 'fs', () => ( {
|
|
15
17
|
promises: {
|
|
@@ -18,6 +20,7 @@ jest.mock( 'fs', () => ( {
|
|
|
18
20
|
mkdir: jest.fn(),
|
|
19
21
|
writeFile: jest.fn(),
|
|
20
22
|
},
|
|
23
|
+
existsSync: jest.fn().mockReturnValue( false ),
|
|
21
24
|
} ) );
|
|
22
25
|
|
|
23
26
|
// This mocks a small response with a format matching the stable-check API.
|
|
@@ -200,4 +203,86 @@ describe( 'Config Integration', () => {
|
|
|
200
203
|
);
|
|
201
204
|
expect( config ).toMatchSnapshot();
|
|
202
205
|
} );
|
|
206
|
+
|
|
207
|
+
describe( 'cache directory naming', () => {
|
|
208
|
+
beforeEach( () => {
|
|
209
|
+
readFile.mockImplementation( async () => {
|
|
210
|
+
throw { code: 'ENOENT' };
|
|
211
|
+
} );
|
|
212
|
+
existsSync.mockReturnValue( false );
|
|
213
|
+
} );
|
|
214
|
+
|
|
215
|
+
it( 'uses the descriptive `wp-env-<dir>-<8charHash>` format by default', async () => {
|
|
216
|
+
const config = await loadConfig( '/test/gutenberg' );
|
|
217
|
+
|
|
218
|
+
const expectedHash = md5( '/test/gutenberg/.wp-env.json' ).slice(
|
|
219
|
+
0,
|
|
220
|
+
8
|
|
221
|
+
);
|
|
222
|
+
expect( config.workDirectoryPath ).toEqual(
|
|
223
|
+
`/cache/wp-env-gutenberg-${ expectedHash }`
|
|
224
|
+
);
|
|
225
|
+
// The short hash is exactly 8 hex chars.
|
|
226
|
+
expect( expectedHash ).toMatch( /^[0-9a-f]{8}$/ );
|
|
227
|
+
} );
|
|
228
|
+
|
|
229
|
+
it( 'produces distinct cache dirs for the same config filename in different directories', async () => {
|
|
230
|
+
const configA = await loadConfig( '/work/alice/myproject' );
|
|
231
|
+
const configB = await loadConfig( '/work/bob/myproject' );
|
|
232
|
+
|
|
233
|
+
expect( configA.workDirectoryPath ).toMatch(
|
|
234
|
+
/^\/cache\/wp-env-myproject-[0-9a-f]{8}$/
|
|
235
|
+
);
|
|
236
|
+
expect( configB.workDirectoryPath ).toMatch(
|
|
237
|
+
/^\/cache\/wp-env-myproject-[0-9a-f]{8}$/
|
|
238
|
+
);
|
|
239
|
+
expect( configA.workDirectoryPath ).not.toEqual(
|
|
240
|
+
configB.workDirectoryPath
|
|
241
|
+
);
|
|
242
|
+
} );
|
|
243
|
+
|
|
244
|
+
it( 'extracts a variant from `.wp-env.<variant>.json` custom config', async () => {
|
|
245
|
+
const config = await loadConfig(
|
|
246
|
+
'/test/gutenberg',
|
|
247
|
+
'/test/gutenberg/.wp-env.test.json'
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const expectedHash = md5(
|
|
251
|
+
'/test/gutenberg/.wp-env.test.json'
|
|
252
|
+
).slice( 0, 8 );
|
|
253
|
+
expect( config.workDirectoryPath ).toEqual(
|
|
254
|
+
`/cache/wp-env-gutenberg-test-${ expectedHash }`
|
|
255
|
+
);
|
|
256
|
+
} );
|
|
257
|
+
|
|
258
|
+
it( 'derives a variant from an arbitrarily-named custom config file', async () => {
|
|
259
|
+
const config = await loadConfig(
|
|
260
|
+
'/test/gutenberg',
|
|
261
|
+
'/some/configs/staging.json'
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const expectedHash = md5( '/some/configs/staging.json' ).slice(
|
|
265
|
+
0,
|
|
266
|
+
8
|
|
267
|
+
);
|
|
268
|
+
// The project-dir segment comes from the config file's parent directory
|
|
269
|
+
expect( config.workDirectoryPath ).toEqual(
|
|
270
|
+
`/cache/wp-env-configs-staging-${ expectedHash }`
|
|
271
|
+
);
|
|
272
|
+
} );
|
|
273
|
+
|
|
274
|
+
it( 'keeps using the legacy pure-md5 cache directory when it already exists', async () => {
|
|
275
|
+
const configFilePath = '/test/gutenberg/.wp-env.json';
|
|
276
|
+
const legacyPath = `/cache/${ md5( configFilePath ) }`;
|
|
277
|
+
|
|
278
|
+
// the legacy md5 directory is present on disk.
|
|
279
|
+
existsSync.mockImplementation(
|
|
280
|
+
( candidate ) => candidate === legacyPath
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
const config = await loadConfig( '/test/gutenberg' );
|
|
284
|
+
|
|
285
|
+
expect( config.workDirectoryPath ).toEqual( legacyPath );
|
|
286
|
+
} );
|
|
287
|
+
} );
|
|
203
288
|
} );
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/env",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.5.0",
|
|
4
4
|
"description": "A zero-config, self contained local WordPress environment for development and testing.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"scripts": {
|
|
64
64
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "8c229eaed0e88c9827e2da3d73a78f9ddd77714b"
|
|
67
67
|
}
|