From 6436a8faff8cba9e1f72147c7241585d7dd7802b Mon Sep 17 00:00:00 2001 From: Kyle Brennan Date: Sun, 7 Nov 2021 16:30:18 +0000 Subject: [PATCH] Fixes #852 optionally add last newline Tested with Linux and Windows, by appending many new functions to a single stack.yml file. Signed-off-by: Kyle Brennan --- commands/new_function.go | 30 +++++++++++++++ commands/new_function_test.go | 70 +++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/commands/new_function.go b/commands/new_function.go index 61cfcd1c5..aa6f64941 100644 --- a/commands/new_function.go +++ b/commands/new_function.go @@ -152,6 +152,11 @@ Download templates: } fileName = appendFile + + if err := addEofNewlines("./" + fileName); err != nil { + return err + } + outputMsg = fmt.Sprintf("Stack file updated: %s\n", fileName) } else { @@ -346,3 +351,28 @@ Cannot have duplicate function names in same yaml file`, functionName, appendFil return nil } + +func addEofNewlines(fileName string) error { + bytes, err := os.ReadFile(fileName) + if err != nil { + return fmt.Errorf("could not open '%s' to check for new lines %s", fileName, err) + } + + content := string(bytes) + hasLastNewline := strings.HasSuffix(content, "\n") + if hasLastNewline { + return nil + } + + file, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + return fmt.Errorf("could not open '%s' to append new lines %s", fileName, err) + } + defer file.Close() + + if _, err = file.WriteString("\n\n"); err != nil { + return fmt.Errorf("could not write to '%s' to append new lines %s", fileName, err) + } + + return nil +} diff --git a/commands/new_function_test.go b/commands/new_function_test.go index 670217291..2d6bfa6c1 100644 --- a/commands/new_function_test.go +++ b/commands/new_function_test.go @@ -372,6 +372,11 @@ func tearDownNewFunction(t *testing.T, functionName string) { t.Log(err) } } + if _, err := os.Stat("stack.yml"); err == nil { + if err := os.Remove("stack.yml"); err != nil { + t.Log(err) + } + } hDir := handlerDir if len(hDir) == 0 { hDir = functionName @@ -423,3 +428,68 @@ func Test_getPrefixValue_Flag(t *testing.T) { t.Errorf("want %s, got %s", want, val) } } + +func Test_addEofNewlines_works(t *testing.T) { + table := []struct { + funcName string + }{ + // TODO: after #906 is fixed + // -f or --yaml will work + // and we can change stack to func1 + {"stack"}, + {"func2"}, + {"func3"}, + } + resetForTest() + templatePullLocalTemplateRepo(t) + + defer tearDownFetchTemplates(t) + const stackFile = "stack.yml" + + for i, row := range table { + const functionLang = "ruby" + + parameters := []string{ + "new", + row.funcName, + "--lang=" + functionLang, + } + + if i == 0 { + // there's a bug where this doesn't get honored + // as a workaround, func1 is "stack" in the test table + // this way we predictability create stack.yml + parameters = append(parameters, "--yaml="+stackFile) + } else { + parameters = append(parameters, "--append="+stackFile) + } + + faasCmd.SetArgs(nil) + faasCmd.SetArgs(parameters) + faasCmd.Execute() + + // drop last two bytes (\n\n) for the first function + if i == 0 { + func(fileName string) { + file, _ := os.OpenFile(fileName, os.O_RDWR, 0600) + defer file.Close() + fileStats, _ := file.Stat() + file.Truncate(fileStats.Size() - 2) + }(stackFile) + } else { + func(fileName string) { + bytes, _ := os.ReadFile(fileName) + want := "\n\n" + got := string(bytes) + matches := strings.HasSuffix(got, want) + if !matches { + t.Fatalf("%q must end with: %q\n", fileName, want) + } + }(stackFile) + } + } + + for _, row := range table { + defer tearDownNewFunction(t, row.funcName) + } +}