diff --git a/utils/file.go b/utils/file.go index a135a81d..ab765408 100644 --- a/utils/file.go +++ b/utils/file.go @@ -1,11 +1,79 @@ package utils import ( + "bufio" + "errors" + "io" "os" "path/filepath" + "regexp" ) func SelfPath() string { path, _ := filepath.Abs(os.Args[0]) return path } + +func SelfDir() string { + return filepath.Dir(SelfPath()) +} + +// FileExists reports whether the named file or directory exists. +func FileExists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + +// search a file in paths. +// this is offen used in search config file in /etc ~/ +func LookFile(filename string, paths ...string) (fullpath string, err error) { + for _, path := range paths { + if fullpath = filepath.Join(path, filename); FileExists(fullpath) { + return + } + } + err = errors.New(fullpath + " not found in paths") + return +} + +// like command grep -E +// for example: GrepE(`^hello`, "hello.txt") +// \n is striped while read +func GrepE(patten string, filename string) (lines []string, err error) { + re, err := regexp.Compile(patten) + if err != nil { + return + } + + fd, err := os.Open(filename) + if err != nil { + return + } + lines = make([]string, 0) + reader := bufio.NewReader(fd) + prefix := "" + for { + byteLine, isPrefix, er := reader.ReadLine() + if er != nil && er != io.EOF { + return nil, er + } + line := string(byteLine) + if isPrefix { + prefix += line + continue + } + + line = prefix + line + if re.MatchString(line) { + lines = append(lines, line) + } + if er == io.EOF { + break + } + } + return lines, nil +} diff --git a/utils/file_test.go b/utils/file_test.go index da3b1324..026d2cf6 100644 --- a/utils/file_test.go +++ b/utils/file_test.go @@ -1,9 +1,13 @@ package utils import ( + "path/filepath" + "reflect" "testing" ) +var noExistedFile = "/tmp/not_existed_file" + func TestSelfPath(t *testing.T) { path := SelfPath() if path == "" { @@ -11,3 +15,47 @@ func TestSelfPath(t *testing.T) { } t.Logf("SelfPath: %s", path) } + +func TestSelfDir(t *testing.T) { + dir := SelfDir() + t.Logf("SelfDir: %s", dir) +} + +func TestFileExists(t *testing.T) { + if !FileExists("/bin/echo") { + t.Errorf("/bin/echo should exists, but it didn't") + } + + if FileExists(noExistedFile) { + t.Errorf("Wierd, how could this file exists: %s", noExistedFile) + } +} + +func TestLookFile(t *testing.T) { + path, err := LookFile(filepath.Base(SelfPath()), SelfDir()) + if err != nil { + t.Error(err) + } + t.Log(path) + + path, err = LookFile(noExistedFile, ".") + if err == nil { + t.Errorf("err shouldnot be nil, got path: %s", SelfDir()) + } +} + +func TestGrepE(t *testing.T) { + _, err := GrepE("", noExistedFile) + if err == nil { + t.Error("expect file-not-existed error, but got nothing") + } + + path := filepath.Join(".", "testdata", "grepe.test") + lines, err := GrepE(`^\s*[^#]+`, path) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(lines, []string{"hello", "world"}) { + t.Errorf("expect [hello world], but receive %v", lines) + } +} diff --git a/utils/testdata/grepe.test b/utils/testdata/grepe.test new file mode 100644 index 00000000..6c014c40 --- /dev/null +++ b/utils/testdata/grepe.test @@ -0,0 +1,7 @@ +# empty lines + + + +hello +# comment +world