path.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Package path provides functions for manipulating filesystem path names.
  2. package path
  3. import (
  4. "os"
  5. "path/filepath"
  6. "src.elv.sh/pkg/eval"
  7. "src.elv.sh/pkg/eval/errs"
  8. "src.elv.sh/pkg/eval/vars"
  9. )
  10. // Ns is the namespace for the re: module.
  11. var Ns = eval.BuildNsNamed("path").
  12. AddVars(map[string]vars.Var{
  13. "list-separator": vars.NewReadOnly(string(filepath.ListSeparator)),
  14. "separator": vars.NewReadOnly(string(filepath.Separator)),
  15. }).
  16. AddGoFns(map[string]any{
  17. "abs": filepath.Abs,
  18. "base": filepath.Base,
  19. "clean": filepath.Clean,
  20. "dir": filepath.Dir,
  21. "ext": filepath.Ext,
  22. "eval-symlinks": filepath.EvalSymlinks,
  23. "is-abs": filepath.IsAbs,
  24. "is-dir": isDir,
  25. "is-regular": isRegular,
  26. "join": filepath.Join,
  27. "temp-dir": tempDir,
  28. "temp-file": tempFile,
  29. }).Ns()
  30. type isOpts struct{ FollowSymlink bool }
  31. func (opts *isOpts) SetDefaultOptions() {}
  32. func isDir(opts isOpts, path string) bool {
  33. var fi os.FileInfo
  34. var err error
  35. if opts.FollowSymlink {
  36. fi, err = os.Stat(path)
  37. } else {
  38. fi, err = os.Lstat(path)
  39. }
  40. return err == nil && fi.Mode().IsDir()
  41. }
  42. func isRegular(opts isOpts, path string) bool {
  43. var fi os.FileInfo
  44. var err error
  45. if opts.FollowSymlink {
  46. fi, err = os.Stat(path)
  47. } else {
  48. fi, err = os.Lstat(path)
  49. }
  50. return err == nil && fi.Mode().IsRegular()
  51. }
  52. type mktempOpt struct{ Dir string }
  53. func (o *mktempOpt) SetDefaultOptions() {}
  54. func tempDir(opts mktempOpt, args ...string) (string, error) {
  55. var pattern string
  56. switch len(args) {
  57. case 0:
  58. pattern = "elvish-*"
  59. case 1:
  60. pattern = args[0]
  61. default:
  62. return "", errs.ArityMismatch{What: "arguments",
  63. ValidLow: 0, ValidHigh: 1, Actual: len(args)}
  64. }
  65. return os.MkdirTemp(opts.Dir, pattern)
  66. }
  67. func tempFile(opts mktempOpt, args ...string) (*os.File, error) {
  68. var pattern string
  69. switch len(args) {
  70. case 0:
  71. pattern = "elvish-*"
  72. case 1:
  73. pattern = args[0]
  74. default:
  75. return nil, errs.ArityMismatch{What: "arguments",
  76. ValidLow: 0, ValidHigh: 1, Actual: len(args)}
  77. }
  78. return os.CreateTemp(opts.Dir, pattern)
  79. }