130
pkg/bbutil/filestats.go
Normal file
130
pkg/bbutil/filestats.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package bbutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DirExists returns true if directory exists.
|
||||
func DirExists(path string) (bool, error) {
|
||||
stat, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return stat.IsDir(), nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
|
||||
// FileExistsOrProblem returns true if the file exists or if we can't determine its existence.
|
||||
func FileExistsOrProblem(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Touch updates the timestamp of a file.
|
||||
func Touch(name string) error {
|
||||
var err error
|
||||
_, err = os.Stat(name)
|
||||
if os.IsNotExist(err) {
|
||||
file, err := os.Create(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("TouchFile failed: %w", err)
|
||||
}
|
||||
file.Close()
|
||||
}
|
||||
|
||||
currentTime := time.Now().Local()
|
||||
return os.Chtimes(name, currentTime, currentTime)
|
||||
}
|
||||
|
||||
// ReadFileLines is like ioutil.ReadFile() but returns an []string.
|
||||
func ReadFileLines(filename string) ([]string, error) {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := string(b)
|
||||
s = strings.TrimSuffix(s, "\n")
|
||||
if s == "" {
|
||||
return []string{}, nil
|
||||
}
|
||||
l := strings.Split(s, "\n")
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// AddLinesToSortedFile adds a line to a sorted file.
|
||||
func AddLinesToSortedFile(filename string, newlines ...string) error {
|
||||
lines, err := ReadFileLines(filename)
|
||||
//fmt.Printf("DEBUG: read=%q\n", lines)
|
||||
if err != nil {
|
||||
return fmt.Errorf("AddLinesToSortedFile can't read %q: %w", filename, err)
|
||||
}
|
||||
if !sort.StringsAreSorted(lines) {
|
||||
return fmt.Errorf("AddLinesToSortedFile: file wasn't sorted: %v", filename)
|
||||
}
|
||||
lines = append(lines, newlines...)
|
||||
sort.Strings(lines)
|
||||
contents := strings.Join(lines, "\n") + "\n"
|
||||
//fmt.Printf("DEBUG: write=%q\n", contents)
|
||||
err = ioutil.WriteFile(filename, []byte(contents), 0o660)
|
||||
if err != nil {
|
||||
return fmt.Errorf("AddLinesToSortedFile can't write %q: %w", filename, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddLinesToFile adds lines to the end of a file.
|
||||
func AddLinesToFile(filename string, newlines ...string) error {
|
||||
lines, err := ReadFileLines(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("AddLinesToFile can't read %q: %w", filename, err)
|
||||
}
|
||||
lines = append(lines, newlines...)
|
||||
contents := strings.Join(lines, "\n") + "\n"
|
||||
err = ioutil.WriteFile(filename, []byte(contents), 0o660)
|
||||
if err != nil {
|
||||
return fmt.Errorf("AddLinesToFile can't write %q: %w", filename, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindDirInParent looks for target in CWD, or .., or ../.., etc.
|
||||
func FindDirInParent(target string) (string, error) {
|
||||
// Prevent an infinite loop by only doing "cd .." this many times
|
||||
maxDirLevels := 30
|
||||
relpath := "."
|
||||
for i := 0; i < maxDirLevels; i++ {
|
||||
// Does relpath contain our target?
|
||||
t := filepath.Join(relpath, target)
|
||||
//logDebug.Printf("Trying %q\n", t)
|
||||
_, err := os.Stat(t)
|
||||
if err == nil {
|
||||
return t, nil
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("stat failed FindDirInParent (%q): %w", t, err)
|
||||
}
|
||||
// Ok, it really wasn't found.
|
||||
|
||||
// If we are at the root, stop.
|
||||
if abs, err := filepath.Abs(relpath); err == nil && abs == "/" {
|
||||
break
|
||||
}
|
||||
// Try one directory up
|
||||
relpath = filepath.Join("..", relpath)
|
||||
}
|
||||
return "", fmt.Errorf("Not found")
|
||||
}
|
||||
Reference in New Issue
Block a user