@@ -2,7 +2,7 @@ import { assert } from 'chai';
2
2
import * as path from 'path' ;
3
3
import { DevContainerConfig , DevContainerFeature } from '../../spec-configuration/configuration' ;
4
4
import { OCIRef } from '../../spec-configuration/containerCollectionsOCI' ;
5
- import { Feature , FeatureSet , getBackwardCompatibleFeatureId , getFeatureInstallWrapperScript , processFeatureIdentifier , updateDeprecatedFeaturesIntoOptions } from '../../spec-configuration/containerFeaturesConfiguration' ;
5
+ import { Feature , FeatureSet , getBackwardCompatibleFeatureId , getFeatureInstallWrapperScript , normalizeUserFeatureIdentifier , processFeatureIdentifier , updateDeprecatedFeaturesIntoOptions } from '../../spec-configuration/containerFeaturesConfiguration' ;
6
6
import { getSafeId , findContainerUsers } from '../../spec-node/containerFeatures' ;
7
7
import { ImageMetadataEntry } from '../../spec-node/imageMetadata' ;
8
8
import { SubstitutedConfig } from '../../spec-node/utils' ;
@@ -62,6 +62,7 @@ describe('validate processFeatureIdentifier', async function () {
62
62
// Parsed out of a user's devcontainer.json
63
63
let userFeature : DevContainerFeature = {
64
64
rawUserFeatureId : 'docker-in-docker' ,
65
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'docker-in-docker' ) ,
65
66
options : { }
66
67
} ;
67
68
const featureSet = await processFeatureIdentifier ( params , defaultConfigPath , workspaceRoot , userFeature ) ;
@@ -83,6 +84,7 @@ describe('validate processFeatureIdentifier', async function () {
83
84
it ( 'should process github-repo (without version)' , async function ( ) {
84
85
const userFeature : DevContainerFeature = {
85
86
rawUserFeatureId : 'octocat/myfeatures/helloworld' ,
87
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures/helloworld' ) ,
86
88
options : { } ,
87
89
} ;
88
90
const featureSet = await processFeatureIdentifier ( params , defaultConfigPath , workspaceRoot , userFeature ) ;
@@ -111,6 +113,7 @@ describe('validate processFeatureIdentifier', async function () {
111
113
it ( 'should process github-repo (with version)' , async function ( ) {
112
114
const userFeature : DevContainerFeature = {
113
115
rawUserFeatureId :
'octocat/myfeatures/[email protected] ' ,
116
+ normalizedUserFeatureId :
normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures/[email protected] ' ) ,
114
117
options : { } ,
115
118
} ;
116
119
const featureSet = await processFeatureIdentifier ( params , defaultConfigPath , workspaceRoot , userFeature ) ;
@@ -140,6 +143,7 @@ describe('validate processFeatureIdentifier', async function () {
140
143
it ( 'should process direct-tarball (v2 with direct tar download)' , async function ( ) {
141
144
const userFeature : DevContainerFeature = {
142
145
rawUserFeatureId : 'https://example.com/some/long/path/devcontainer-feature-ruby.tgz' ,
146
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'https://example.com/some/long/path/devcontainer-feature-ruby.tgz' ) ,
143
147
options : { } ,
144
148
} ;
145
149
@@ -158,6 +162,7 @@ describe('validate processFeatureIdentifier', async function () {
158
162
it ( 'local-path should parse when provided a relative path with Config file in $WORKSPACE_ROOT/.devcontainer' , async function ( ) {
159
163
const userFeature : DevContainerFeature = {
160
164
rawUserFeatureId : './featureA' ,
165
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , './featureA' ) ,
161
166
options : { } ,
162
167
} ;
163
168
@@ -173,6 +178,7 @@ describe('validate processFeatureIdentifier', async function () {
173
178
it ( 'local-path should parse when provided relative path with config file in $WORKSPACE_ROOT' , async function ( ) {
174
179
const userFeature : DevContainerFeature = {
175
180
rawUserFeatureId : './.devcontainer/featureB' ,
181
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , './.devcontainer/featureB' ) ,
176
182
options : { } ,
177
183
} ;
178
184
@@ -188,6 +194,7 @@ describe('validate processFeatureIdentifier', async function () {
188
194
it ( 'should process oci registry (without tag)' , async function ( ) {
189
195
const userFeature : DevContainerFeature = {
190
196
rawUserFeatureId : 'ghcr.io/codspace/features/ruby' ,
197
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'ghcr.io/codspace/features/ruby' ) ,
191
198
options : { } ,
192
199
} ;
193
200
@@ -224,6 +231,7 @@ describe('validate processFeatureIdentifier', async function () {
224
231
it ( 'should process oci registry (with a digest)' , async function ( ) {
225
232
const userFeature : DevContainerFeature = {
226
233
rawUserFeatureId : 'ghcr.io/devcontainers/features/ruby@sha256:4ef08c9c3b708f3c2faecc5a898b39736423dd639f09f2a9f8bf9b0b9252ef0a' ,
234
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'ghcr.io/devcontainers/features/ruby@sha256:4ef08c9c3b708f3c2faecc5a898b39736423dd639f09f2a9f8bf9b0b9252ef0a' ) ,
227
235
options : { } ,
228
236
} ;
229
237
@@ -260,6 +268,7 @@ describe('validate processFeatureIdentifier', async function () {
260
268
it ( 'should process oci registry (with a tag)' , async function ( ) {
261
269
const userFeature : DevContainerFeature = {
262
270
rawUserFeatureId : 'ghcr.io/codspace/features/ruby:1.0.13' ,
271
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'ghcr.io/codspace/features/ruby:1.0.13' ) ,
263
272
options : { } ,
264
273
} ;
265
274
@@ -298,6 +307,7 @@ describe('validate processFeatureIdentifier', async function () {
298
307
it ( 'local-path should fail to parse when provided absolute path and defaultConfigPath with a .devcontainer' , async function ( ) {
299
308
const userFeature : DevContainerFeature = {
300
309
rawUserFeatureId : '/some/long/path/to/helloworld' ,
310
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , '/some/long/path/to/helloworld' ) ,
301
311
options : { } ,
302
312
} ;
303
313
@@ -310,6 +320,7 @@ describe('validate processFeatureIdentifier', async function () {
310
320
it ( 'local-path should fail to parse when provided an absolute path and defaultConfigPath without a .devcontainer' , async function ( ) {
311
321
const userFeature : DevContainerFeature = {
312
322
rawUserFeatureId : '/some/long/path/to/helloworld' ,
323
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , '/some/long/path/to/helloworld' ) ,
313
324
options : { } ,
314
325
} ;
315
326
@@ -322,6 +333,7 @@ describe('validate processFeatureIdentifier', async function () {
322
333
it ( 'local-path should fail to parse when provided an a relative path breaking out of the .devcontainer folder' , async function ( ) {
323
334
const userFeature : DevContainerFeature = {
324
335
rawUserFeatureId : '../featureC' ,
336
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , '../featureC' ) ,
325
337
options : { } ,
326
338
} ;
327
339
@@ -334,6 +346,7 @@ describe('validate processFeatureIdentifier', async function () {
334
346
it ( 'should fail parsing a generic tar with no feature and trailing slash' , async function ( ) {
335
347
const userFeature : DevContainerFeature = {
336
348
rawUserFeatureId : 'https://example.com/some/long/path/devcontainer-features.tgz/' ,
349
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'https://example.com/some/long/path/devcontainer-features.tgz/' ) ,
337
350
options : { } ,
338
351
} ;
339
352
@@ -344,6 +357,7 @@ describe('validate processFeatureIdentifier', async function () {
344
357
it ( 'should not parse gitHub without triple slash' , async function ( ) {
345
358
const userFeature : DevContainerFeature = {
346
359
rawUserFeatureId : 'octocat/myfeatures#helloworld' ,
360
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures#helloworld' ) ,
347
361
options : { } ,
348
362
} ;
349
363
@@ -354,6 +368,7 @@ describe('validate processFeatureIdentifier', async function () {
354
368
it ( 'should fail parsing a generic tar with no feature and no trailing slash' , async function ( ) {
355
369
const userFeature : DevContainerFeature = {
356
370
rawUserFeatureId : 'https://example.com/some/long/path/devcontainer-features.tgz' ,
371
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'https://example.com/some/long/path/devcontainer-features.tgz' ) ,
357
372
options : { } ,
358
373
} ;
359
374
@@ -364,6 +379,7 @@ describe('validate processFeatureIdentifier', async function () {
364
379
it ( 'should fail parsing a generic tar with a hash but no feature' , async function ( ) {
365
380
const userFeature : DevContainerFeature = {
366
381
rawUserFeatureId : 'https://example.com/some/long/path/devcontainer-features.tgz#' ,
382
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'https://example.com/some/long/path/devcontainer-features.tgz#' ) ,
367
383
options : { } ,
368
384
} ;
369
385
@@ -374,6 +390,7 @@ describe('validate processFeatureIdentifier', async function () {
374
390
it ( 'should fail parsing a marketplace shorthand with only two segments and a hash with no feature' , async function ( ) {
375
391
const userFeature : DevContainerFeature = {
376
392
rawUserFeatureId : 'octocat/myfeatures#' ,
393
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures#' ) ,
377
394
options : { } ,
378
395
} ;
379
396
@@ -384,6 +401,7 @@ describe('validate processFeatureIdentifier', async function () {
384
401
it ( 'should fail parsing a marketplace shorthand with only two segments (no feature)' , async function ( ) {
385
402
const userFeature : DevContainerFeature = {
386
403
rawUserFeatureId : 'octocat/myfeatures' ,
404
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures' ) ,
387
405
options : { } ,
388
406
} ;
389
407
@@ -394,6 +412,7 @@ describe('validate processFeatureIdentifier', async function () {
394
412
it ( 'should fail parsing a marketplace shorthand with an invalid feature name (1)' , async function ( ) {
395
413
const userFeature : DevContainerFeature = {
396
414
rawUserFeatureId : 'octocat/myfeatures/@mycoolfeature' ,
415
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures/@mycoolfeature' ) ,
397
416
options : { } ,
398
417
} ;
399
418
@@ -404,6 +423,7 @@ describe('validate processFeatureIdentifier', async function () {
404
423
it ( 'should fail parsing a marketplace shorthand with an invalid feature name (2)' , async function ( ) {
405
424
const userFeature : DevContainerFeature = {
406
425
rawUserFeatureId : 'octocat/myfeatures/MY_$UPER_COOL_FEATURE' ,
426
+ normalizedUserFeatureId : normalizeUserFeatureIdentifier ( output , 'octocat/myfeatures/MY_$UPER_COOL_FEATURE' ) ,
407
427
options : { } ,
408
428
} ;
409
429
@@ -414,6 +434,7 @@ describe('validate processFeatureIdentifier', async function () {
414
434
it ( 'should fail parsing a marketplace shorthand with only two segments, no hash, and with a version' , async function ( ) {
415
435
const userFeature : DevContainerFeature = {
416
436
rawUserFeatureId :
'octocat/[email protected] ' ,
437
+ normalizedUserFeatureId :
normalizeUserFeatureIdentifier ( output , 'octocat/[email protected] ' ) ,
417
438
options : { } ,
418
439
} ;
419
440
0 commit comments