Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/shell.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,27 @@ Your prompt gains a `(frank)` prefix so you always know aliases are active. Run
| `php` | `docker compose exec app php` |
| `tinker` | `docker compose exec app php artisan tinker` |
| `npm` | `docker compose exec app npm` |
| `pnpm` | `docker compose exec app pnpm` |
| `bun` | `docker compose exec app bun` |
| `corepack` | `docker compose exec app corepack` |
| `psql` | `docker compose exec db psql …` *(pgsql only)* |
| `mysql` | `docker compose exec db mysql …` *(mysql/mariadb only)* |
| `redis-cli` | `docker compose exec redis redis-cli` *(redis only)* |

The database aliases are only added when the matching service is configured, so `psql` won't appear in a MySQL project and vice versa.

## Pinning the package manager

By default the container's `npm`/`pnpm` resolve to whatever [corepack](https://nodejs.org/api/corepack.html) fetches on first use — i.e. the latest published version. To pin an exact, integrity-verified version, run `corepack use` once inside the project:

```sh
corepack use pnpm@11 # or: frank exec corepack use pnpm@11
```

This stamps the `packageManager` field in your `package.json` (e.g. `pnpm@11.2.1+sha256.<hash>`). From then on every install is hash-verified and reproducible. `package.json` is the source of truth — Frank does not track the version, so this is the standard corepack workflow, nothing Frank-specific.

> **Note:** corepack manages `npm` and `pnpm`. `bun`'s version comes from the image build, not corepack — `corepack use bun@…` has no effect.

## Custom Aliases

You can define your own aliases in `frank.yaml` under the `aliases` key. Two forms are supported:
Expand Down
1 change: 1 addition & 0 deletions internal/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var aliasTable = []struct {
{"npm", execSail + " npm", ""},
{"pnpm", execSail + " pnpm", ""},
{"bun", execSail + " bun", ""},
{"corepack", execSail + " corepack", ""}, // pin pkg mgr: `corepack use pnpm@11` stamps package.json
// Service-conditional aliases
{"psql", dc + " exec pgsql psql -U sail", "pgsql"},
{"mysql", dc + " exec db mysql -u root -proot", "mysql"},
Expand Down
4 changes: 2 additions & 2 deletions internal/shell/shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestActivate(t *testing.T) {
cfg := testConfig("pgsql", "mailpit")
output := Activate(cfg)

for _, name := range []string{"artisan", "composer", "php", "tinker", "npm", "bun"} {
for _, name := range []string{"artisan", "composer", "php", "tinker", "npm", "bun", "corepack"} {
if !strings.Contains(output, "alias "+name+"=") {
t.Errorf("expected core alias %q in output:\n%s", name, output)
}
Expand Down Expand Up @@ -96,7 +96,7 @@ func TestActivate_FRANK_ALIASES(t *testing.T) {
end := strings.Index(output[start:], `"`)
aliasLine := output[start : start+end]

for _, name := range []string{"artisan", "composer", "php", "tinker", "npm", "bun", "psql", "pest"} {
for _, name := range []string{"artisan", "composer", "php", "tinker", "npm", "bun", "corepack", "psql", "pest"} {
if !strings.Contains(aliasLine, name) {
t.Errorf("_FRANK_ALIASES missing %q, got: %s", name, aliasLine)
}
Expand Down