Skip to content

Commit

Permalink
os: Improve FileExists behaviour
Browse files Browse the repository at this point in the history
At the moment, FileExists returns false if and only if os.Stat()
returns a 'FileNotExist' error. In other error cases, FileExists would
return true, while in reality it cannot know.

This commit inverts this behaviour, FileExists() now only returns true
if it's almost sure that the file really exists. When in doubt, it will
return false. As far as I can tell, the existing users should not be
negatively impacted by this change.
  • Loading branch information
cfergeau authored and guillaumerose committed Jan 26, 2021
1 parent ca9236f commit 6c8ea26
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
10 changes: 7 additions & 3 deletions pkg/os/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,14 @@ func WriteFileIfContentChanged(path string, newContent []byte, perm os.FileMode)
return true, nil
}

// FileExists returns true if the file at path exists.
// It returns false if it does not exist, or if there was an error when checking for its existence.
// This means there can be false negatives if Lstat fails because of permission issues (file exists,
// but is not reachable by the current user)
func FileExists(path string) bool {
_, err := os.Stat(path)
if err != nil && os.IsNotExist(err) {
info, err := os.Lstat(path)
if err != nil {
return false
}
return true
return !info.IsDir()
}
29 changes: 29 additions & 0 deletions pkg/os/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,32 @@ func TestFileContentFuncs(t *testing.T) {
assert.Error(t, FileContentMatches(filename, []byte("aaaa")))
assert.NoError(t, FileContentMatches(filename, []byte("aaaaa")))
}

func TestFileExists(t *testing.T) {
dir, err := ioutil.TempDir("", "fileexists")
assert.NoError(t, err)
defer os.RemoveAll(dir)

filename := filepath.Join(dir, "testfile1")
_, err = WriteFileIfContentChanged(filename, []byte("content"), 0644)
assert.NoError(t, err)
assert.True(t, FileExists(filename))

_, err = WriteFileIfContentChanged(filename, []byte("newcontent"), 0000)
assert.NoError(t, err)
assert.True(t, FileExists(filename))

dirname := filepath.Join(dir, "testdir")
err = os.MkdirAll(dirname, 0700)
assert.NoError(t, err)
filename = filepath.Join(dirname, "testfile2")
_, err = WriteFileIfContentChanged(filename, []byte("content"), 0644)
assert.NoError(t, err)
assert.True(t, FileExists(filename))

err = os.Chmod(dirname, 0000)
assert.NoError(t, err)
assert.False(t, FileExists(filename))
filename = filepath.Join(dirname, "nonexistent")
assert.False(t, FileExists(filename))
}

0 comments on commit 6c8ea26

Please sign in to comment.