// Package path provides functions for manipulating filesystem path names.
package path import ( ) // Ns is the namespace for the re: module. var Ns = eval.NsBuilder{}.AddGoFns("path:", fns).Ns() var fns = map[string]interface{}{ "abs": filepath.Abs, "base": filepath.Base, "clean": filepath.Clean, "dir": filepath.Dir, "ext": filepath.Ext, "eval-symlinks": filepath.EvalSymlinks, "is-abs": filepath.IsAbs, "is-dir": isDir, "is-regular": isRegular, "temp-dir": tempDir, "temp-file": tempFile, } //elvdoc:fn abs // // ```elvish // path:abs $path // ``` // // Outputs `$path` converted to an absolute path. // // ```elvish-transcript // ~> cd ~ // ~> path:abs bin // ▶ /home/user/bin // ``` //elvdoc:fn base // // ```elvish // path:base $path // ``` // // Outputs the last element of `$path`. This is analogous to the POSIX `basename` command. See the // [Go documentation](https://pkg.go.dev/path/filepath#Base) for more details. // // ```elvish-transcript // ~> path:base ~/bin // ▶ bin // ``` //elvdoc:fn clean // // ```elvish // path:clean $path // ``` // // Outputs the shortest version of `$path` equivalent to `$path` by purely lexical processing. This // is most useful for eliminating unnecessary relative path elements such as `.` and `..` without // asking the OS to evaluate the path name. See the [Go // documentation](https://pkg.go.dev/path/filepath#Clean) for more details. // // ```elvish-transcript // ~> path:clean ./../bin // ▶ ../bin // ``` //elvdoc:fn dir // // ```elvish // path:dir $path // ``` // // Outputs all but the last element of `$path`, typically the path's enclosing directory. See the // [Go documentation](https://pkg.go.dev/path/filepath#Dir) for more details. This is analogous to // the POSIX `dirname` command. // // ```elvish-transcript // ~> path:dir /a/b/c/something // ▶ /a/b/c // ``` //elvdoc:fn ext // // ```elvish // ext $path // ``` // // Outputs the file name extension used by `$path` (including the separating period). If there is no // extension the empty string is output. See the [Go // documentation](https://pkg.go.dev/path/filepath#Ext) for more details. // // ```elvish-transcript // ~> path:ext hello.elv // ▶ .elv // ``` //elvdoc:fn is-abs // // ```elvish // is-abs $path // ``` // // Outputs `$true` if the path is an abolute path. Note that platforms like Windows have different // rules than UNIX like platforms for what constitutes an absolute path. See the [Go // documentation](https://pkg.go.dev/path/filepath#IsAbs) for more details. // // ```elvish-transcript // ~> path:is-abs hello.elv // ▶ false // ~> path:is-abs /hello.elv // ▶ true // ``` //elvdoc:fn eval-symlinks // // ```elvish-transcript // ~> mkdir bin // ~> ln -s bin sbin // ~> path:eval-symlinks ./sbin/a_command // ▶ bin/a_command // ``` // // Outputs `$path` after resolving any symbolic links. If `$path` is relative the result will be // relative to the current directory, unless one of the components is an absolute symbolic link. // This function calls `path:clean` on the result before outputing it. This is analogous to the // external `realpath` or `readlink` command found on many systems. See the [Go // documentation](https://pkg.go.dev/path/filepath#EvalSymlinks) for more details. //elvdoc:fn is-dir // // ```elvish // is-dir &follow-symlink=$false $path // ``` // // Outputs `$true` if the path resolves to a directory. If the final element of the path is a // symlink, even if it points to a directory, it still outputs `$false` since a symlink is not a // directory. Setting option `&follow-symlink` to true will cause the last element of the path, if // it is a symlink, to be resolved before doing the test. // // @cf eval-symlinks // // ```elvish-transcript // ~> touch not-a-dir // ~> path:is-dir not-a-dir // ▶ false // ~> path:is-dir /tmp // ▶ true // ``` type isOpts struct{ FollowSymlink bool } func ( *isOpts) () {} func ( isOpts, string) bool { var os.FileInfo var error if .FollowSymlink { , = os.Stat() } else { , = os.Lstat() } return == nil && .Mode().IsDir() } //elvdoc:fn is-regular // // ```elvish // is-regular &follow-symlink=$false $path // ``` // // Outputs `$true` if the path resolves to a regular file. If the final element of the path is a // symlink, even if it points to a regular file, it still outputs `$false` since a symlink is not a // regular file. Setting option `&follow-symlink` to true will cause the last element of the path, // if it is a symlink, to be resolved before doing the test. // // @cf eval-symlinks // // ```elvish-transcript // ~> touch not-a-dir // ~> path:is-regular not-a-dir // ▶ true // ~> path:is-dir /tmp // ▶ false // ``` func ( isOpts, string) bool { var os.FileInfo var error if .FollowSymlink { , = os.Stat() } else { , = os.Lstat() } return == nil && .Mode().IsRegular() } //elvdoc:fn temp-dir // // ```elvish // temp-dir &dir='' $pattern? // ``` // // Creates a new directory and outputs its name. // // The &dir option determines where the directory will be created; if it is an // empty string (the default), a system-dependent directory suitable for storing // temporary files will be used. The `$pattern` argument determins the name of // the directory, where the last star will be replaced by a random string; it // defaults to `elvish-*`. // // It is the caller's responsibility to remove the directory if it is intended // to be temporary. // // ```elvish-transcript // ~> path:temp-dir // ▶ /tmp/elvish-RANDOMSTR // ~> path:temp-dir x- // ▶ /tmp/x-RANDOMSTR // ~> path:temp-dir 'x-*.y' // ▶ /tmp/x-RANDOMSTR.y // ~> path:temp-dir &dir=. // ▶ elvish-RANDOMSTR // ~> path:temp-dir &dir=/some/dir // ▶ /some/dir/elvish-RANDOMSTR // ``` type mktempOpt struct{ Dir string } func ( *mktempOpt) () {} func ( mktempOpt, ...string) (string, error) { var string switch len() { case 0: = "elvish-*" case 1: = [0] default: return "", errs.ArityMismatch{ What: "arguments here", ValidLow: 0, ValidHigh: 1, Actual: len()} } return ioutil.TempDir(.Dir, ) } //elvdoc:fn temp-file // // ```elvish // temp-file &dir='' $pattern? // ``` // // Creates a new file and outputs a [file](language.html#file) object opened // for reading and writing. // // The &dir option determines where the file will be created; if it is an // empty string (the default), a system-dependent directory suitable for storing // temporary files will be used. The `$pattern` argument determins the name of // the file, where the last star will be replaced by a random string; it // defaults to `elvish-*`. // // It is the caller's responsibility to close the file with // [`file:close`](file.html#close). The caller should also remove the file if it // is intended to be temporary (with `rm $f[name]`). // // ```elvish-transcript // ~> f = path:temp-file // ~> put $f[name] // ▶ /tmp/elvish-RANDOMSTR // ~> echo hello > $f // ~> cat $f[name] // hello // ~> f = path:temp-file x- // ~> put $f[name] // ▶ /tmp/x-RANDOMSTR // ~> f = path:temp-file 'x-*.y' // ~> put $f[name] // ▶ /tmp/x-RANDOMSTR.y // ~> f = path:temp-file &dir=. // ~> put $f[name] // ▶ elvish-RANDOMSTR // ~> f = path:temp-file &dir=/some/dir // ~> put $f[name] // ▶ /some/dir/elvish-RANDOMSTR // ``` func ( mktempOpt, ...string) (*os.File, error) { var string switch len() { case 0: = "elvish-*" case 1: = [0] default: return nil, errs.ArityMismatch{ What: "arguments here", ValidLow: 0, ValidHigh: 1, Actual: len()} } return ioutil.TempFile(.Dir, ) }