@@ -193,6 +193,7 @@ Download templates:
193
193
return fmt .Errorf ("folder: %s already exists" , handlerDir )
194
194
}
195
195
196
+ // In non-append mode, we error if the file exists.
196
197
if _ , err := os .Stat (fileName ); err == nil && ! appendMode {
197
198
return fmt .Errorf ("file: %s already exists. Try \" faas-cli new --append %s\" instead" , fileName , fileName )
198
199
}
@@ -258,17 +259,37 @@ Download templates:
258
259
}
259
260
}
260
261
262
+ // Build the YAML content. In append mode this is just the function block.
261
263
yamlContent := prepareYAMLContent (appendMode , gateway , & function )
262
264
263
- f , err := os .OpenFile ("./" + fileName , os .O_APPEND | os .O_WRONLY | os .O_CREATE , 0600 )
264
- if err != nil {
265
- return fmt .Errorf ("could not open file '%s' %s" , fileName , err )
266
- }
265
+ // === Begin Updated Code for Inserting into functions: block ===
266
+ if appendMode {
267
+ // Read the existing file content.
268
+ existingBytes , err := os .ReadFile (fileName )
269
+ if err != nil {
270
+ return fmt .Errorf ("unable to read file: %s" , fileName )
271
+ }
272
+ existingContent := string (existingBytes )
273
+
274
+ // Insert the new function block into the functions: section.
275
+ updatedContent , err := insertFunctionIntoFunctionsBlock (existingContent , yamlContent )
276
+ if err != nil {
277
+ return fmt .Errorf ("error updating functions block: %s" , err )
278
+ }
267
279
268
- _ , stackWriteErr := f .Write ([]byte (yamlContent ))
269
- if stackWriteErr != nil {
270
- return fmt .Errorf ("error writing stack file %s" , stackWriteErr )
280
+ // Write the updated content back to file.
281
+ err = os .WriteFile (fileName , []byte (updatedContent ), 0644 )
282
+ if err != nil {
283
+ return fmt .Errorf ("error writing updated stack file: %s" , err )
284
+ }
285
+ } else {
286
+ // In non-append mode, write out the entire YAML file.
287
+ err = os .WriteFile (fileName , []byte (yamlContent ), 0644 )
288
+ if err != nil {
289
+ return fmt .Errorf ("error writing stack file: %s" , err )
290
+ }
271
291
}
292
+ // === End Updated Code ===
272
293
273
294
fmt .Print (outputMsg )
274
295
@@ -371,3 +392,67 @@ Cannot have duplicate function names in same yaml file`, functionName, appendFil
371
392
372
393
return nil
373
394
}
395
+
396
+ // insertFunctionIntoFunctionsBlock locates the existing "functions:" block
397
+ // in the YAML file content and inserts newFuncBlock (which should be indented)
398
+ // at the end of the functions: block (i.e. before the next section begins).
399
+ func insertFunctionIntoFunctionsBlock (existingContent string , newFuncBlock string ) (string , error ) {
400
+ // If existing content is empty (or only whitespace), return a newline plus the new block.
401
+ if strings .TrimSpace (existingContent ) == "" {
402
+ return "\n " + newFuncBlock , nil
403
+ }
404
+
405
+ // Split the file into lines.
406
+ lines := strings .Split (existingContent , "\n " )
407
+ // Remove any trailing empty lines.
408
+ for len (lines ) > 0 && lines [len (lines )- 1 ] == "" {
409
+ lines = lines [:len (lines )- 1 ]
410
+ }
411
+
412
+ functionsHeaderRegex := regexp .MustCompile (`^\s*functions:\s*$` )
413
+ var functionsIndex int = - 1
414
+
415
+ // Find the "functions:" header.
416
+ for i , line := range lines {
417
+ if functionsHeaderRegex .MatchString (line ) {
418
+ functionsIndex = i
419
+ break
420
+ }
421
+ }
422
+
423
+ // If no functions header is found, simply append the new block at the end.
424
+ if functionsIndex == - 1 {
425
+ return strings .Join (lines , "\n " ) + "\n " + newFuncBlock , nil
426
+ }
427
+
428
+ // Determine where the functions: block ends.
429
+ // We assume that function entries are indented (e.g. at least 2 spaces).
430
+ insertIndex := len (lines )
431
+ for i := functionsIndex + 1 ; i < len (lines ); i ++ {
432
+ line := lines [i ]
433
+ if strings .TrimSpace (line ) == "" {
434
+ continue // Skip blank lines.
435
+ }
436
+ // Calculate the indent level.
437
+ indentLen := len (line ) - len (strings .TrimLeft (line , " " ))
438
+ if indentLen < 2 {
439
+ // Found a new section (or unindented line); mark the end of the functions block.
440
+ insertIndex = i
441
+ break
442
+ }
443
+ }
444
+
445
+ // Remove any trailing newline from the new function block.
446
+ newFuncBlock = strings .TrimRight (newFuncBlock , "\n " )
447
+ newFuncLines := strings .Split (newFuncBlock , "\n " )
448
+
449
+ // Insert the new function block just before insertIndex.
450
+ newLines := append ([]string {}, lines [:insertIndex ]... )
451
+ newLines = append (newLines , newFuncLines ... )
452
+ // Append the remainder of the file.
453
+ if insertIndex < len (lines ) {
454
+ newLines = append (newLines , lines [insertIndex :]... )
455
+ }
456
+ updatedContent := strings .Join (newLines , "\n " )
457
+ return updatedContent , nil
458
+ }
0 commit comments