diff options
Diffstat (limited to 'client/go/internal/ioutil')
-rw-r--r-- | client/go/internal/ioutil/ioutil.go | 84 | ||||
-rw-r--r-- | client/go/internal/ioutil/ioutil_test.go | 57 |
2 files changed, 141 insertions, 0 deletions
diff --git a/client/go/internal/ioutil/ioutil.go b/client/go/internal/ioutil/ioutil.go new file mode 100644 index 00000000000..d3a33698d13 --- /dev/null +++ b/client/go/internal/ioutil/ioutil.go @@ -0,0 +1,84 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// File utilities. +// Author: bratseth + +package ioutil + +import ( + "bytes" + "encoding/json" + "errors" + "io" + "os" + "path/filepath" + "strings" +) + +// Exists returns true if the given path exists. +func Exists(path string) bool { + info, err := os.Stat(path) + return !errors.Is(err, os.ErrNotExist) && info != nil +} + +// IsDir returns true if the given path points to an existing directory. +func IsDir(path string) bool { + info, err := os.Stat(path) + return !errors.Is(err, os.ErrNotExist) && info != nil && info.IsDir() +} + +// IsFile returns true if the given path points to an existing regular file. +func IsFile(path string) bool { + info, err := os.Stat(path) + return !errors.Is(err, os.ErrNotExist) && info != nil && info.Mode().IsRegular() +} + +// IsExecutable returns true if the given path points to an executable file. +func IsExecutable(path string) bool { + info, err := os.Stat(path) + return !errors.Is(err, os.ErrNotExist) && + info != nil && + info.Mode().IsRegular() && + ((int(info.Mode()) & 0111) == 0111) +} + +// ReaderToString Returns the content of reader as a string. Read errors are ignored. +func ReaderToString(reader io.Reader) string { + var buffer strings.Builder + io.Copy(&buffer, reader) + return buffer.String() +} + +// ReaderToBytes returns the content of a reader as a byte array. Read errors are ignored. +func ReaderToBytes(reader io.Reader) []byte { + var buffer bytes.Buffer + buffer.ReadFrom(reader) + return buffer.Bytes() +} + +// ReaderToJSON returns the contents of reader as indented JSON. Read errors are ignored. +func ReaderToJSON(reader io.Reader) string { + bodyBytes, _ := io.ReadAll(reader) + var prettyJSON bytes.Buffer + parseError := json.Indent(&prettyJSON, bodyBytes, "", " ") + if parseError != nil { // Not JSON: Print plainly + return string(bodyBytes) + } + return prettyJSON.String() +} + +// AtomicWriteFile atomically writes data to filename. +func AtomicWriteFile(filename string, data []byte) error { + dir := filepath.Dir(filename) + tmpFile, err := os.CreateTemp(dir, "vespa") + if err != nil { + return err + } + defer os.Remove(tmpFile.Name()) + if _, err := tmpFile.Write(data); err != nil { + return err + } + if err := tmpFile.Close(); err != nil { + return err + } + return os.Rename(tmpFile.Name(), filename) +} diff --git a/client/go/internal/ioutil/ioutil_test.go b/client/go/internal/ioutil/ioutil_test.go new file mode 100644 index 00000000000..907132c9eaa --- /dev/null +++ b/client/go/internal/ioutil/ioutil_test.go @@ -0,0 +1,57 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ioutil + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPathExists(t *testing.T) { + assert.Equal(t, true, Exists("ioutil.go")) + assert.Equal(t, false, Exists("nosuchthing.go")) + + tmpDir := t.TempDir() + err := os.MkdirAll(tmpDir+"/no", 0755) + assert.Nil(t, err) + err = os.MkdirAll(tmpDir+"/no/such", 0) + assert.Nil(t, err) + assert.Equal(t, false, Exists(tmpDir+"/no/such/thing.go")) +} + +func TestIsDir(t *testing.T) { + tmpDir := t.TempDir() + err := os.MkdirAll(tmpDir+"/no", 0755) + assert.Nil(t, err) + assert.Equal(t, true, IsDir(tmpDir+"/no")) + err = os.MkdirAll(tmpDir+"/no/such", 0) + assert.Nil(t, err) + assert.Equal(t, true, IsDir(tmpDir+"/no/such")) + assert.Equal(t, false, IsDir(tmpDir+"/no/such/thing.go")) +} + +func TestIsRegularFile(t *testing.T) { + assert.Equal(t, true, IsFile("ioutil.go")) + assert.Equal(t, false, IsFile(".")) + tmpDir := t.TempDir() + err := os.MkdirAll(tmpDir+"/no", 0755) + assert.Nil(t, err) + err = os.MkdirAll(tmpDir+"/no/such", 0) + assert.Nil(t, err) + assert.Equal(t, false, IsFile(tmpDir+"/no/such/thing.go")) +} + +func TestIsExecutableFile(t *testing.T) { + assert.Equal(t, false, IsExecutable("io.go")) + assert.Equal(t, false, IsExecutable("nosuchthing.go")) + tmpDir := t.TempDir() + err := os.WriteFile(tmpDir+"/run.sh", []byte("#!/bin/sh\necho foo\n"), 0755) + assert.Nil(t, err) + assert.Equal(t, true, IsExecutable(tmpDir+"/run.sh")) + /* unix only: + out, err := BackTicksWithStderr.Run(tmpDir + "/run.sh") + assert.Nil(t, err) + assert.Equal(t, "foo\n", out) + */ +} |