You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.6 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package os
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "os"
  8. "os/signal"
  9. "syscall"
  10. )
  11. type logger interface {
  12. Info(msg string, keyvals ...interface{})
  13. }
  14. // TrapSignal catches SIGTERM and SIGINT, executes the cleanup function,
  15. // and exits with code 0.
  16. func TrapSignal(ctx context.Context, logger logger, cb func()) {
  17. opctx, opcancel := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
  18. go func() {
  19. defer opcancel()
  20. defer opcancel()
  21. <-opctx.Done()
  22. logger.Info("captured signal, exiting...")
  23. if cb != nil {
  24. cb()
  25. }
  26. os.Exit(0)
  27. }()
  28. }
  29. // EnsureDir ensures the given directory exists, creating it if necessary.
  30. // Errors if the path already exists as a non-directory.
  31. func EnsureDir(dir string, mode os.FileMode) error {
  32. err := os.MkdirAll(dir, mode)
  33. if err != nil {
  34. return fmt.Errorf("could not create directory %q: %w", dir, err)
  35. }
  36. return nil
  37. }
  38. func FileExists(filePath string) bool {
  39. _, err := os.Stat(filePath)
  40. return !os.IsNotExist(err)
  41. }
  42. // CopyFile copies a file. It truncates the destination file if it exists.
  43. func CopyFile(src, dst string) error {
  44. srcfile, err := os.Open(src)
  45. if err != nil {
  46. return err
  47. }
  48. defer srcfile.Close()
  49. info, err := srcfile.Stat()
  50. if err != nil {
  51. return err
  52. }
  53. if info.IsDir() {
  54. return errors.New("cannot read from directories")
  55. }
  56. // create new file, truncate if exists and apply same permissions as the original one
  57. dstfile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode().Perm())
  58. if err != nil {
  59. return err
  60. }
  61. defer dstfile.Close()
  62. _, err = io.Copy(dstfile, srcfile)
  63. return err
  64. }