mirror of
https://github.com/gechandesu/runcmd.git
synced 2026-01-02 13:49:34 +03:00
65 lines
1.9 KiB
V
65 lines
1.9 KiB
V
module runcmd
|
|
|
|
import os
|
|
|
|
// new creates new Command instance with given command name and arguments.
|
|
pub fn new(name string, arg ...string) &Command {
|
|
return &Command{
|
|
path: name
|
|
args: arg
|
|
}
|
|
}
|
|
|
|
// is_present returns true if cmd is present on system. cmd may be a command
|
|
// name or filepath (relative or absolute).
|
|
// The result relies on `look_path()` output, see its docs for command search
|
|
// details.
|
|
pub fn is_present(cmd string) bool {
|
|
_ := look_path(cmd) or { return false }
|
|
return true
|
|
}
|
|
|
|
// look_path returns the absolute path to executable file. cmd may be a command
|
|
// name or filepath (relative or absolute). If the name contains a slash, then the
|
|
// PATH search is not performed, instead the path will be resolved and the file
|
|
// existence and its permissions will be checked (execution must be allowed).
|
|
// Note: To use executables located in the current working directory use './file'
|
|
// instead of just 'file'. Searching for executable files in the current directory
|
|
// is disabled for security reasons. See https://go.dev/blog/path-security.
|
|
pub fn look_path(cmd string) !string {
|
|
if cmd.is_blank() {
|
|
return os.ExecutableNotFoundError{}
|
|
}
|
|
|
|
// Do not search executable in PATH if its name contains a slashes (as POSIX-shells does),
|
|
// See PATH in: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
|
|
|
|
if cmd.contains('/') {
|
|
actual_path := os.abs_path(os.expand_tilde_to_home(os.norm_path(cmd)))
|
|
if is_executable_file(actual_path) {
|
|
return actual_path
|
|
} else {
|
|
return os.ExecutableNotFoundError{}
|
|
}
|
|
}
|
|
|
|
paths := os.getenv('PATH').split(os.path_delimiter)
|
|
|
|
for path in paths {
|
|
if path in ['', '.'] {
|
|
// Prohibit current directory.
|
|
continue
|
|
}
|
|
actual_path := os.abs_path(os.join_path_single(path, cmd))
|
|
if is_executable_file(actual_path) {
|
|
return actual_path
|
|
}
|
|
}
|
|
|
|
return os.ExecutableNotFoundError{}
|
|
}
|
|
|
|
fn is_executable_file(file string) bool {
|
|
return os.is_file(file) && os.is_executable(file)
|
|
}
|