-
Notifications
You must be signed in to change notification settings - Fork 493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lookPath
should accept an optional path
override
#3141
lookPath
should accept an optional path
override
#3141
Comments
Two threads, maybe not solving this issue:
|
I am doing something similar to: That's exactly what I imagined it to look like: chezmoi/internal/chezmoi/lookpath.go Lines 15 to 28 in 547de5b
My issue is one step further; I would like to pick tools based on what's now available in paths. For instance installing on Solaris often puts tools in So:
Is more to the goal. So perhaps: package chezmoi
import (
"filepath"
"os"
"os/exec"
"sync"
)
var (
lookPathCacheMutex sync.Mutex
lookPathCache = make(map[string]string)
foundExecutableCacheMutex sync.Mutex
foundExecutableCache = make(map[string]struct{})
)
// LookPath is like os/exec.LookPath except that the first positive result is
// cached.
func LookPath(file string) (string, error) {
lookPathCacheMutex.Lock()
defer lookPathCacheMutex.Unlock()
if path, ok := lookPathCache[file]; ok {
return path, nil
}
path, err := exec.LookPath(file)
if err == nil {
lookPathCache[file] = path
}
return path, err
}
func LookPathIn(file string, paths string) (string, error) {
foundExecutableCacheMutex.Lock()
defer foundExecutableCacheMutex.Unlock()
// stolen from: /usr/lib/go-1.20/src/os/exec/lp_unix.go:52
for _, dir := range filepath.SplitList(paths) {
if dir == "" {
continue
}
path := filepath.Join(dir, file)
if err := findExecutable(path); err == nil {
if !filepath.IsAbs(path) && execerrdot.Value() != "0" {
return path, &Error{file, os.ErrDot}
}
return path, nil
}
}
return path, err
}
// stolen from: /usr/lib/go-1.20/src/os/exec/lp_unix.go:52
func findExecutable(file string) error {
if path, ok := foundExecutableCache[file]; ok {
return file, nil
}
d, err := os.Stat(file)
if err != nil {
return err
}
m := d.Mode()
if m.IsDir() {
return syscall.EISDIR
}
err = unix.Eaccess(file, unix.X_OK)
// ENOSYS means Eaccess is not available or not implemented.
// EPERM can be returned by Linux containers employing seccomp.
// In both cases, fall back to checking the permission bits.
if err == nil || (err != syscall.ENOSYS && err != syscall.EPERM) {
return err
}
if m&0111 != 0 {
return nil
}
return fs.ErrPermission
}
Sorry I did this in the comments there are probably major issues with this example |
I think that, as a separate function, this could be quite useful. Without this, I would need to do something like: $ # run the commands to install bun, which installs in ~/.bun/bin/bun
$ chezmoi apply
# things apply without knowing that bun is present
$ exec $SHELL
# my shell config has bun file detection, and this is a fast way to replace the current shell with an updated shell
$ chezmoi apply
# things apply knowing that bun is present With this, it would be more like: $ # run the commands to install bun
$ chezmoi apply
# things apply knowing that bun will be present on next shell start
$ exec $SHELL |
@arran4, thanks, this makes sense :) Would you mind converting your comment in to a pull request? https://github.com/twpayne/chezmoi/pull/2833/files should give you a complete picture of which files need to be modified when adding a new template function. |
BREAKING CHANGE: `isExecutable` has major change for windows. It now does something
BREAKING CHANGE: `isExecutable` has major change for windows. It now does something
BREAKING CHANGE: `isExecutable` has major change for windows. It now does something
BREAKING CHANGE: `isExecutable` has major change for windows. It now does something
@twpayne Should I continue with this? |
If you need the functionality, then please do (and re-open this issue). I think it's possible to do within the current templating functionality, something like (warning: untested):
|
It's more of a want, however it would also take time for me to adapt the changes into my disorganized dotfiles. I think the push back warrants a different name at least. |
…ecutable of a particular name and returns the found path. As per: twpayne#3141
…ecutable of a particular name and returns the found path. As per: twpayne#3141
…ecutable of a particular name and returns the found path. As per: twpayne#3141
…ecutable of a particular name and returns the found path. As per: twpayne#3141
…ecutable of a particular name and returns the found path. As per: twpayne#3141
…ecutable of a particular name and returns the found path. As per: twpayne#3141
…ecutable of a particular name and returns the found path. As per: twpayne#3141
Implement `findExecutable` with strong caching. The main change from twpayne#3162 is that it now also accepts either a `file` or `file-list` for searching, so that one of several different options can be searched simultaneously for roughly equivalent implementations. See twpayne#3256 for the inspiration for this particular change. We *can* switch this to two template functions, but I think that the core implementation would best remain the way that it is. Resolves: twpayne#3141 Closes: twpayne#3162 Co-authored-by: Arran Ubels <arran4@gmail.com>
Implement `findExecutable` with strong caching. The main change from twpayne#3162 is that it now also accepts either a `file` or `file-list` for searching, so that one of several different options can be searched simultaneously for roughly equivalent implementations. See twpayne#3256 for the inspiration for this particular change. We *can* switch this to two template functions, but I think that the core implementation would best remain the way that it is. Resolves: twpayne#3141 Closes: twpayne#3162 Co-authored-by: Arran Ubels <arran4@gmail.com>
Implement `findExecutable` with strong caching. The main change from twpayne#3162 is that it now also accepts either a `file` or `file-list` for searching, so that one of several different options can be searched simultaneously for roughly equivalent implementations. See twpayne#3256 for the inspiration for this particular change. We *can* switch this to two template functions, but I think that the core implementation would best remain the way that it is. Resolves: twpayne#3141 Closes: twpayne#3162 Co-authored-by: Arran Ubels <arran4@gmail.com>
Implemented `findExecutable` with strong caching, extended from twpayne#3162. Also implemented `findOneExecutable` to search for any one executable from a list. Resolves: twpayne#3141 Closes: twpayne#3162 Co-authored-by: Arran Ubels <arran4@gmail.com>
Implemented `findExecutable` with strong caching, extended from twpayne#3162. Also implemented `findOneExecutable` to search for any one executable from a list. Resolves: twpayne#3141 Closes: twpayne#3162 Co-authored-by: Arran Ubels <arran4@gmail.com>
Is your feature request related to a problem? Please describe.
As part of my dotfiles script I'm building up a list of paths that will replace the existing paths as a result I want not just the "current state" of paths, but if something is found in the paths that I'm building up. One way to do this would be to provide an optional argument to
lookPath
where I could specify the value of$PATH
that I'm building upDescribe the solution you'd like
Would work along with:
Describe alternatives you've considered
I guess I could loop through it and use
stat
to build up a map of what's in there for a quick lookup later. But it seems slower.The text was updated successfully, but these errors were encountered: