code.oscarkilo.com/klex-git/util/files.go

..
commit.go
commit_test.go
committest/
files.go
files_test.go
paths.go
paths_test.go
root.go
root_test.go
run.go
run_test.go
package util

import (
  "bufio"
  "encoding/json"
  "io"
  "io/ioutil"
  "os"
  "path"
)

func EnsureFileExists(file string) error {
  if _, err := os.Stat(file); os.IsNotExist(err) {
    os.MkdirAll(path.Dir(file), 0755)
    f, err := os.Create(file);
    if err != nil {
      return err
    }
    f.Close()
  }
  return nil
}

// AddLineTo appends the line to the file, unless it already exists.
// If the file doesn't exist, it will be created, including directories.
func AddLineTo(file string, line string) error {
  if !LineExistsIn(file, line) {
    if fileIsMissingNewline(file) {
      err := AppendStringTo(file, "\n")
      if err != nil {
        return err
      }
    }
    return AppendStringTo(file, line + "\n")
  }
  return nil
}

// LineExistsIn returns true if the line exists in the file.
func LineExistsIn(file string, line string) bool {
  // read one line at a time
  f, err := os.Open(file)
  if err != nil {
    return false
  }
  defer f.Close()
  scanner := bufio.NewScanner(f)
  for scanner.Scan() {
    if scanner.Text() == line {
      return true
    }
  }
  return false
}

// isFileEmpty returns true if the file is empty or non-existent.
func isFileEmpty(file string) bool {
  f, err := os.Open(file)
  if err != nil {
    return true
  }
  defer f.Close()
  _, err = f.Seek(0, 2)
  return err == nil
}

// AppendStringTo appends the string to the file.
func AppendStringTo(file string, str string) error {
  EnsureFileExists(file)
  f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0644)
  if err != nil {
    return err
  }
  defer f.Close()
  _, err = io.WriteString(f, str)
  return err
}

// ReadJsonFile parses the contents of 'file' as a JSON object.
func ReadJsonFile(file string, obj interface{}) error {
  f, err := os.Open(file)
  if err != nil {
    return err
  }
  defer f.Close()
  return json.NewDecoder(f).Decode(obj)
}

// fileIsMissingNewline returns true if the file ends in a non-newline byte.
func fileIsMissingNewline(file string) bool {
  f, err := os.Open(file)
  if err != nil {
    return false
  }
  defer f.Close()
  _, err = f.Seek(-1, 2)
  if err != nil {
    return false
  }
  b := make([]byte, 1)
  _, err = f.Read(b)
  return err != nil || b[0] != '\n'
}

// ReadDir reads all the files in the directory.
// Obviously, don't do this if the whole contents don't fit in RAM.
func ReadDir(dir string) (map[string]string, error) {
  files, err := ioutil.ReadDir(dir)
  if err != nil {
    return nil, err
  }
  res := make(map[string]string)
  for _, f := range files {
    fpath := path.Join(dir, f.Name())
    contents, err := ioutil.ReadFile(fpath)
    if err != nil {
      return nil, err
    }
    res[f.Name()] = string(contents)
  }
  return res, nil
}

func IsDir(fpath string) bool {
  fi, err := os.Stat(fpath)
  return err == nil && fi.IsDir()
}