diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index b9ea928be..2a7cc1328 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -109,13 +109,34 @@ func (c *OSCommand) Quote(message string) string { // AppendLineToFile adds a new line in file func (c *OSCommand) AppendLineToFile(filename, line string) error { c.LogCommand(fmt.Sprintf("Appending '%s' to file '%s'", line, filename), false) - f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600) + f, err := os.OpenFile(filename, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0o600) if err != nil { return utils.WrapError(err) } defer f.Close() - _, err = f.WriteString("\n" + line) + info, err := os.Stat(filename) + if err != nil { + return utils.WrapError(err) + } + + if info.Size() > 0 { + // read last char + buf := make([]byte, 1) + if _, err := f.ReadAt(buf, info.Size()-1); err != nil { + return utils.WrapError(err) + } + + // if the last byte of the file is not a newline, add it + if []byte("\n")[0] != buf[0] { + _, err = f.WriteString("\n") + } + } + + if err == nil { + _, err = f.WriteString(line + "\n") + } + if err != nil { return utils.WrapError(err) } diff --git a/pkg/commands/oscommands/os_test.go b/pkg/commands/oscommands/os_test.go index 0152fec58..969224405 100644 --- a/pkg/commands/oscommands/os_test.go +++ b/pkg/commands/oscommands/os_test.go @@ -1,7 +1,9 @@ package oscommands import ( + "io/ioutil" "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -135,3 +137,61 @@ func TestOSCommandFileType(t *testing.T) { _ = os.RemoveAll(s.path) } } + +func TestOSCommandAppendLineToFile(t *testing.T) { + type scenario struct { + path string + setup func(string) + test func(string) + } + + scenarios := []scenario{ + { + filepath.Join(os.TempDir(), "testFile"), + func(path string) { + if err := ioutil.WriteFile(path, []byte("hello"), 0o600); err != nil { + panic(err) + } + }, + func(output string) { + assert.EqualValues(t, "hello\nworld\n", output) + }, + }, + { + filepath.Join(os.TempDir(), "emptyTestFile"), + func(path string) { + if err := ioutil.WriteFile(path, []byte(""), 0o600); err != nil { + panic(err) + } + }, + func(output string) { + assert.EqualValues(t, "world\n", output) + }, + }, + { + filepath.Join(os.TempDir(), "testFileWithNewline"), + func(path string) { + if err := ioutil.WriteFile(path, []byte("hello\n"), 0o600); err != nil { + panic(err) + } + }, + func(output string) { + assert.EqualValues(t, "hello\nworld\n", output) + }, + }, + } + + for _, s := range scenarios { + s.setup(s.path) + osCommand := NewDummyOSCommand() + if err := osCommand.AppendLineToFile(s.path, "world"); err != nil { + panic(err) + } + f, err := ioutil.ReadFile(s.path) + if err != nil { + panic(err) + } + s.test(string(f)) + _ = os.RemoveAll(s.path) + } +} diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/config b/test/integration/gitignoreMenu/expected/repo/.git_keep/config index 8ae104545..596ebaeb3 100644 --- a/test/integration/gitignoreMenu/expected/repo/.git_keep/config +++ b/test/integration/gitignoreMenu/expected/repo/.git_keep/config @@ -3,8 +3,6 @@ filemode = true bare = false logallrefupdates = true - ignorecase = true - precomposeunicode = true [user] email = CI@example.com name = CI diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/info/exclude b/test/integration/gitignoreMenu/expected/repo/.git_keep/info/exclude index 8e9f2071f..a5196d1be 100644 --- a/test/integration/gitignoreMenu/expected/repo/.git_keep/info/exclude +++ b/test/integration/gitignoreMenu/expected/repo/.git_keep/info/exclude @@ -4,4 +4,3 @@ # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ -.DS_Store diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/HEAD b/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/HEAD index bef74759d..329f08e98 100644 --- a/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/HEAD +++ b/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/HEAD @@ -1 +1 @@ -0000000000000000000000000000000000000000 9dd04ee245b7d6f1f80aa2b428111cbac4a4e37d CI 1657012500 +1000 commit (initial): Initial commit +0000000000000000000000000000000000000000 04535177acab8a81c84b0b1b44ee3aea76b0e36e CI 1659528492 +0200 commit (initial): Initial commit diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/refs/heads/master b/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/refs/heads/master index bef74759d..329f08e98 100644 --- a/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/refs/heads/master +++ b/test/integration/gitignoreMenu/expected/repo/.git_keep/logs/refs/heads/master @@ -1 +1 @@ -0000000000000000000000000000000000000000 9dd04ee245b7d6f1f80aa2b428111cbac4a4e37d CI 1657012500 +1000 commit (initial): Initial commit +0000000000000000000000000000000000000000 04535177acab8a81c84b0b1b44ee3aea76b0e36e CI 1659528492 +0200 commit (initial): Initial commit diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/objects/04/535177acab8a81c84b0b1b44ee3aea76b0e36e b/test/integration/gitignoreMenu/expected/repo/.git_keep/objects/04/535177acab8a81c84b0b1b44ee3aea76b0e36e new file mode 100644 index 000000000..ff7e7bc39 Binary files /dev/null and b/test/integration/gitignoreMenu/expected/repo/.git_keep/objects/04/535177acab8a81c84b0b1b44ee3aea76b0e36e differ diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/objects/9d/d04ee245b7d6f1f80aa2b428111cbac4a4e37d b/test/integration/gitignoreMenu/expected/repo/.git_keep/objects/9d/d04ee245b7d6f1f80aa2b428111cbac4a4e37d deleted file mode 100644 index eb76d5d88..000000000 Binary files a/test/integration/gitignoreMenu/expected/repo/.git_keep/objects/9d/d04ee245b7d6f1f80aa2b428111cbac4a4e37d and /dev/null differ diff --git a/test/integration/gitignoreMenu/expected/repo/.git_keep/refs/heads/master b/test/integration/gitignoreMenu/expected/repo/.git_keep/refs/heads/master index 998d07e0e..4725f5182 100644 --- a/test/integration/gitignoreMenu/expected/repo/.git_keep/refs/heads/master +++ b/test/integration/gitignoreMenu/expected/repo/.git_keep/refs/heads/master @@ -1 +1 @@ -9dd04ee245b7d6f1f80aa2b428111cbac4a4e37d +04535177acab8a81c84b0b1b44ee3aea76b0e36e diff --git a/test/integration/gitignoreMenu/expected/repo/lg_ignore_file b/test/integration/gitignoreMenu/expected/repo/lg_ignore_file index 959aad479..3829ab872 100644 --- a/test/integration/gitignoreMenu/expected/repo/lg_ignore_file +++ b/test/integration/gitignoreMenu/expected/repo/lg_ignore_file @@ -1,2 +1 @@ - -myfile1 \ No newline at end of file +myfile1