Find the full path to an executable command. Args: cmd: The command to find Returns: Full path to the executable if found, None otherwise
(cmd: str)
| 77 | logger.debug("\n".join(message_parts)) |
| 78 | |
| 79 | def find_executable(cmd: str) -> Optional[str]: |
| 80 | """ |
| 81 | Find the full path to an executable command. |
| 82 | |
| 83 | Args: |
| 84 | cmd: The command to find |
| 85 | |
| 86 | Returns: |
| 87 | Full path to the executable if found, None otherwise |
| 88 | """ |
| 89 | # First check if it's already a full path |
| 90 | if os.path.isfile(cmd) and os.access(cmd, os.X_OK): |
| 91 | return cmd |
| 92 | |
| 93 | # Next check if it's in PATH |
| 94 | cmd_path = shutil.which(cmd) |
| 95 | if cmd_path: |
| 96 | logger.info(f"Found {cmd} in PATH at {cmd_path}") |
| 97 | return cmd_path |
| 98 | |
| 99 | # Try common locations |
| 100 | common_paths = [ |
| 101 | "/usr/local/bin", |
| 102 | "/usr/bin", |
| 103 | "/bin", |
| 104 | "/opt/homebrew/bin", |
| 105 | os.path.expanduser("~/.npm-global/bin"), |
| 106 | os.path.expanduser("~/.nvm/current/bin"), |
| 107 | ] |
| 108 | |
| 109 | for path in common_paths: |
| 110 | full_path = os.path.join(path, cmd) |
| 111 | if os.path.isfile(full_path) and os.access(full_path, os.X_OK): |
| 112 | logger.info(f"Found {cmd} at {full_path}") |
| 113 | return full_path |
| 114 | |
| 115 | logger.error(f"Could not find executable: {cmd}") |
| 116 | return None |
| 117 | |
| 118 | @dataclass |
| 119 | class ServerConfig: |
no outgoing calls
no test coverage detected