@@ -427,9 +427,11 @@ func Run(ctx context.Context, options Options) error {
427
427
if options .DockerfilePath == "" {
428
428
// Only look for a devcontainer if a Dockerfile wasn't specified.
429
429
// devcontainer is a standard, so it's reasonable to be the default.
430
- devcontainerPath , devcontainerDir := findDevcontainerJSON (options )
431
- _ , err := options .Filesystem .Stat (devcontainerPath )
432
- if err == nil {
430
+ devcontainerPath , devcontainerDir , err := findDevcontainerJSON (options )
431
+ if err != nil {
432
+ logf (codersdk .LogLevelError , "Failed to locate devcontainer.json: %s" , err .Error ())
433
+ logf (codersdk .LogLevelError , "Falling back to the default image..." )
434
+ } else {
433
435
// We know a devcontainer exists.
434
436
// Let's parse it and use it!
435
437
file , err := options .Filesystem .Open (devcontainerPath )
@@ -1194,7 +1196,7 @@ func (fs *osfsWithChmod) Chmod(name string, mode os.FileMode) error {
1194
1196
return os .Chmod (name , mode )
1195
1197
}
1196
1198
1197
- func findDevcontainerJSON (options Options ) (string , string ) {
1199
+ func findDevcontainerJSON (options Options ) (string , string , error ) {
1198
1200
// 0. Check provided options.
1199
1201
if options .DevcontainerDir != "" || options .DevcontainerJSONPath != "" {
1200
1202
// Locate .devcontainer directory.
@@ -1212,7 +1214,7 @@ func findDevcontainerJSON(options Options) (string, string) {
1212
1214
1213
1215
// An absolute location always takes a precedence.
1214
1216
if filepath .IsAbs (devcontainerPath ) {
1215
- return options .DevcontainerJSONPath , devcontainerDir
1217
+ return options .DevcontainerJSONPath , devcontainerDir , nil
1216
1218
}
1217
1219
1218
1220
// If an override is not provided, assume it is just `devcontainer.json`.
@@ -1223,24 +1225,47 @@ func findDevcontainerJSON(options Options) (string, string) {
1223
1225
if ! filepath .IsAbs (devcontainerPath ) {
1224
1226
devcontainerPath = filepath .Join (devcontainerDir , devcontainerPath )
1225
1227
}
1226
- return devcontainerPath , devcontainerDir
1228
+ return devcontainerPath , devcontainerDir , nil
1227
1229
}
1228
1230
1229
1231
// 1. Check `options.WorkspaceFolder`/.devcontainer/devcontainer.json.
1230
1232
location := filepath .Join (options .WorkspaceFolder , ".devcontainer" , "devcontainer.json" )
1231
1233
_ , err := options .Filesystem .Stat (location )
1232
1234
if err == nil {
1233
- return location , filepath .Dir (location )
1235
+ return location , filepath .Dir (location ), nil
1234
1236
}
1235
1237
1236
1238
// 2. Check `options.WorkspaceFolder`/devcontainer.json.
1237
1239
location = filepath .Join (options .WorkspaceFolder , "devcontainer.json" )
1238
1240
_ , err = options .Filesystem .Stat (location )
1239
1241
if err == nil {
1240
- return location , filepath .Dir (location )
1242
+ return location , filepath .Dir (location ), nil
1241
1243
}
1242
1244
1243
- // 3. Check every folder: `options.WorkspaceFolder`/<folder>/devcontainer.json.
1245
+ // 3. Check every folder: `options.WorkspaceFolder`/.devcontainer/<folder>/devcontainer.json.
1246
+ devcontainerDir := filepath .Join (options .WorkspaceFolder , ".devcontainer" )
1247
+
1248
+ fileInfos , err := options .Filesystem .ReadDir (devcontainerDir )
1249
+ if err != nil {
1250
+ return "" , "" , err
1251
+ }
1252
+
1253
+ logf := options .Logger
1254
+ for _ , fileInfo := range fileInfos {
1255
+ if ! fileInfo .IsDir () {
1256
+ logf (codersdk .LogLevelDebug , `%s is a file` , fileInfo .Name ())
1257
+ continue
1258
+ }
1259
+
1260
+ location := filepath .Join (devcontainerDir , fileInfo .Name (), "devcontainer.json" )
1261
+ _ , err := options .Filesystem .Stat (location )
1262
+ if err != nil {
1263
+ logf (codersdk .LogLevelDebug , `stat %s failed: %s` , location , err .Error ())
1264
+ continue
1265
+ }
1266
+
1267
+ return location , filepath .Dir (location ), nil
1268
+ }
1244
1269
1245
- panic ( "not implemented yet " )
1270
+ return "" , "" , errors . New ( "can't find devcontainer.json, is it a correct spec? " )
1246
1271
}
0 commit comments