Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions internal/filedata/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package filedata

import (
"bytes"
"encoding/json"
"fmt"
"os"
Expand Down Expand Up @@ -67,6 +68,23 @@ func parseDocument(rawData []byte) (Document, error) {
return data, err
}

// parseFileContent parses a file's content like parseDocument, and also reports whether the
// content holds a document. YAML with no document, such as only a comment or "---", parses
// as a document with no entries, like an empty file. JSON content is always an object, so it
// always holds one, even "{}".
func parseFileContent(rawData []byte) (Document, bool, error) {
doc, err := parseDocument(rawData)
if err != nil || detectJSON(rawData) || doc.Flags != nil || doc.FlagValues != nil || doc.Segments != nil {
return doc, true, err
}
asJSON, err := yaml.YAMLToJSON(rawData)
if err != nil {
// COVERAGE: unreachable, because parseDocument converted the same content
return doc, true, nil
}
return doc, !bytes.Equal(bytes.TrimSpace(asJSON), []byte("null")), nil
}

func detectJSON(rawData []byte) bool {
// A valid JSON file for our purposes must be an object, i.e. it must start with '{'
return strings.HasPrefix(strings.TrimLeftFunc(string(rawData), unicode.IsSpace), "{")
Expand Down
17 changes: 14 additions & 3 deletions internal/filedata/poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,20 @@ func (p *Poller) run() {
func observeAll(paths []string) []fileState {
states := make([]fileState, len(paths))
for i, path := range paths {
if info, err := os.Stat(path); err == nil {
states[i] = fileState{exists: true, modTime: info.ModTime(), size: info.Size()}
}
states[i] = observe(path)
}
return states
}

// observe examines one file. os.Stat follows symbolic links, so the state is that of the
// file a link points to.
func observe(path string) fileState {
if info, err := os.Stat(path); err == nil {
return fileState{exists: true, modTime: info.ModTime(), size: info.Size()}
}
return fileState{}
}

func (s fileState) equal(other fileState) bool {
return s.exists == other.exists && s.modTime.Equal(other.modTime) && s.size == other.size
}
Loading
Loading