Compare commits
6 Commits
8ad911886e
...
d2c3493d68
Author | SHA1 | Date |
---|---|---|
Robert Kaussow | d2c3493d68 | |
Robert Kaussow | 211b38e908 | |
renovate[bot] | 3cb24ef473 | |
Robert Kaussow | 830d37fa00 | |
Robert Kaussow | 25469ebab3 | |
Robert Kaussow | 7143086616 |
|
@ -0,0 +1,54 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// DeleteDir deletes the directory at the given path.
|
||||
// It returns nil if the deletion succeeds, or the deletion error otherwise.
|
||||
// If the directory does not exist, DeleteDir returns nil.
|
||||
func DeleteDir(path string) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
// IsDir returns whether the given path is a directory. If the path does not exist, it returns (false, nil).
|
||||
// If there is an error checking the path, it returns (false, err).
|
||||
func IsDir(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
// IsDirEmpty checks if the directory at the given path is empty.
|
||||
// It returns true if the directory is empty, false if not empty, or an error if there was a problem checking it.
|
||||
func IsDirEmpty(path string) (bool, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Readdir(1)
|
||||
if err == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if errors.Is(err, io.EOF) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsDirEmpty(t *testing.T) {
|
||||
t.Run("empty directory", func(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "test")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
isEmpty, err := IsDirEmpty(dir)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !isEmpty {
|
||||
t.Error("expected directory to be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("non-empty directory", func(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "test")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
file, err := os.CreateTemp(dir, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file: %v", err)
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
isEmpty, err := IsDirEmpty(dir)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if isEmpty {
|
||||
t.Error("expected directory to be non-empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("non-existent directory", func(t *testing.T) {
|
||||
dir := filepath.Join(os.TempDir(), "non-existent")
|
||||
|
||||
isEmpty, err := IsDirEmpty(dir)
|
||||
if err == nil {
|
||||
t.Error("expected an error for non-existent directory")
|
||||
}
|
||||
|
||||
if isEmpty {
|
||||
t.Error("expected directory to be non-empty")
|
||||
}
|
||||
|
||||
if !errors.Is(err, fs.ErrNotExist) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
11
file/file.go
11
file/file.go
|
@ -34,17 +34,6 @@ func ReadStringOrFile(input string) (string, bool, error) {
|
|||
return string(result), true, nil
|
||||
}
|
||||
|
||||
// DeleteDir deletes the directory at the given path.
|
||||
// It returns nil if the deletion succeeds, or the deletion error otherwise.
|
||||
// If the directory does not exist, DeleteDir returns nil.
|
||||
func DeleteDir(path string) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
// ExpandFileList takes a list of file globs and expands them into a list
|
||||
// of matching file paths. It returns the expanded file list and any errors
|
||||
// from glob matching. This allows safely passing user input globs through to
|
||||
|
|
2
go.mod
2
go.mod
|
@ -10,6 +10,7 @@ require (
|
|||
github.com/stretchr/testify v1.9.0
|
||||
github.com/urfave/cli/v2 v2.27.2
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/sys v0.20.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -29,6 +30,5 @@ require (
|
|||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -74,8 +74,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
type Cmd struct {
|
||||
*execabs.Cmd
|
||||
Private bool
|
||||
Trace *bool
|
||||
}
|
||||
|
||||
func (c *Cmd) Run() error {
|
||||
if c.Trace == nil {
|
||||
c.SetTrace(true)
|
||||
}
|
||||
|
||||
if c.Env == nil {
|
||||
c.Env = os.Environ()
|
||||
}
|
||||
|
||||
if c.Stdout == nil {
|
||||
c.Stdout = os.Stdout
|
||||
}
|
||||
|
||||
if c.Stderr == nil {
|
||||
c.Stderr = os.Stderr
|
||||
}
|
||||
|
||||
if c.Private {
|
||||
c.Stdout = io.Discard
|
||||
}
|
||||
|
||||
if *c.Trace {
|
||||
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(c.Args, " "))
|
||||
}
|
||||
|
||||
if err := c.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Wait()
|
||||
}
|
||||
|
||||
func (c *Cmd) SetTrace(trace bool) {
|
||||
c.Trace = &trace
|
||||
}
|
Loading…
Reference in New Issue