Conversation
kamal-*: support git-style external commands in .kamal/bin and on PATH
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7a409ecdc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR adds support for external commands that can extend Kamal's functionality, following a plugin pattern similar to Git's git-foo extension model. External commands are resolved when no builtin command matches, looking first in .kamal/bin/<name> (project-local), then for kamal-<name> on PATH. These external commands bypass config loading, allowing them to work even with broken or missing configuration files, while builtin commands (including prefix matches) are never shadowed.
Changes:
- Added dispatch override in
Kamal::Cli::Mainto resolve and execute external commands - Implemented
resolve_external_commandmethod with security guards against path traversal, directories, non-executable files, and flags - Added comprehensive test coverage for external command resolution, priority, and security scenarios
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| lib/kamal/cli/main.rb | Implements dispatch override and external command resolution with security checks |
| test/cli/main_test.rb | Adds 11 comprehensive tests covering external command behavior and security |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Unknown commands are resolved as external executables before falling through to aliases or the error handler. Lookup order: 1. .kamal/bin/<name> (project-local) 2. kamal-<name> on PATH (system-wide) Builtin commands and unambiguous prefix matches are never shadowed. The external command is exec'd with remaining argv, replacing the kamal process.
Summary
git-fooon PATH.kamal/bin/<name>(project-local), thenkamal-<name>on PATHdep→deploy) are never shadoweddeploy.ymlTest plan
.kamal/bin/foo→ exec called with correct pathkamal-bar→ exec calledversionwith.kamal/bin/versionpresent)verwith.kamal/bin/verpresent).kamal/binskipped../foo) rejected