- package os
-
- import (
- "context"
- "errors"
- "fmt"
- "io"
- "os"
- "os/signal"
- "syscall"
- )
-
- type logger interface {
- Info(msg string, keyvals ...interface{})
- }
-
- // TrapSignal catches SIGTERM and SIGINT, executes the cleanup function,
- // and exits with code 0.
- func TrapSignal(ctx context.Context, logger logger, cb func()) {
- opctx, opcancel := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
-
- go func() {
- defer opcancel()
- defer opcancel()
- <-opctx.Done()
- logger.Info("captured signal, exiting...")
- if cb != nil {
- cb()
- }
- os.Exit(0)
- }()
- }
-
- // EnsureDir ensures the given directory exists, creating it if necessary.
- // Errors if the path already exists as a non-directory.
- func EnsureDir(dir string, mode os.FileMode) error {
- err := os.MkdirAll(dir, mode)
- if err != nil {
- return fmt.Errorf("could not create directory %q: %w", dir, err)
- }
- return nil
- }
-
- func FileExists(filePath string) bool {
- _, err := os.Stat(filePath)
- return !os.IsNotExist(err)
- }
-
- // CopyFile copies a file. It truncates the destination file if it exists.
- func CopyFile(src, dst string) error {
- srcfile, err := os.Open(src)
- if err != nil {
- return err
- }
- defer srcfile.Close()
-
- info, err := srcfile.Stat()
- if err != nil {
- return err
- }
- if info.IsDir() {
- return errors.New("cannot read from directories")
- }
-
- // create new file, truncate if exists and apply same permissions as the original one
- dstfile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode().Perm())
- if err != nil {
- return err
- }
- defer dstfile.Close()
-
- _, err = io.Copy(dstfile, srcfile)
- return err
- }
|