diff --git a/format/format.go b/format/format.go index e276be0e6..0e02dd55b 100644 --- a/format/format.go +++ b/format/format.go @@ -102,6 +102,10 @@ func (f *Format) format(path string) error { } func write(path string, contents []byte) error { + originalFileInfo, err := os.Stat(path) + if err != nil { + return err + } f, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)) if err != nil { return err @@ -113,5 +117,8 @@ func write(path string, contents []byte) error { if err := f.Close(); err != nil { return err } + if err := os.Chmod(f.Name(), originalFileInfo.Mode()); err != nil { + return err + } return os.Rename(f.Name(), path) } diff --git a/format/format_test.go b/format/format_test.go index 152f6124a..7670e7248 100644 --- a/format/format_test.go +++ b/format/format_test.go @@ -16,6 +16,19 @@ func TestFormat_Format(t *testing.T) { assert.True(t, fx.isFormatted("api/api.go")) } +func TestFormat_PermissionsPreserved(t *testing.T) { + fx := setup(t) + + originalFileInfo, err := os.Stat(filepath.Join(fx.basedir, "main.go")) + if err != nil { + t.Fatal(err) + } + + assert.NoError(t, New().Build(&Config{SearchDir: fx.basedir})) + assert.True(t, permissionsEqual(t, filepath.Join(fx.basedir, "main.go"), originalFileInfo.Mode())) + assert.True(t, permissionsEqual(t, filepath.Join(fx.basedir, "api/api.go"), originalFileInfo.Mode())) +} + func TestFormat_ExcludeDir(t *testing.T) { fx := setup(t) assert.NoError(t, New().Build(&Config{ @@ -96,6 +109,14 @@ func (fx *fixture) isFormatted(file string) bool { return !bytes.Equal(testFiles[file], contents) } +func permissionsEqual(t *testing.T, path string, expectedMode os.FileMode) bool { + fileInfo, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + return expectedMode == fileInfo.Mode() +} + var testFiles = map[string][]byte{ "api/api.go": []byte(`package api