gwm-cli 1.6.1

git worktree manager — TUI + CLI, native libgit2, per-repo bootstrap
Documentation
---
title: "prédicats when:"
description: file_exists / cmd_exists / env_set / env_eq / glob_exists, avec composition !, &&, ||.
---

# Prédicats `when:`

Le champ `when:` sur un hook de cycle de vie (`[[hooks.*]]`) — et sur le legacy `[[bootstrap.command]]` — conditionne les étapes shell. Les prédicats se composent avec des opérateurs booléens, de sorte qu'une seule étape peut exprimer « exécuter `bun install` si `package.json` existe ET si `bun` est sur le `$PATH`, mais jamais en CI ».

La même grammaire s'applique à chaque bloc `[[hooks.<phase>]]` (`pre_create`, `post_create`, `pre_bootstrap`, `post_bootstrap`, `pre_remove`, `post_remove`). Les exemples ci-dessous utilisent `[[bootstrap.command]]`, mais `when = "…"` se lit à l'identique sur `[[hooks.post_create]]`.

## atomes supportés

| Atome                         | Vrai quand …                                                                         |
|:------------------------------|:-------------------------------------------------------------------------------------|
| `file_exists:<path>`          | `<worktree>/<path>` se résout sur le disque                                           |
| `cmd_exists:<binary>`         | `<binary>` se résout sur le `$PATH` (lookup `which`)                                  |
| `env_set:<NAME>`              | `std::env::var(NAME)` retourne `Ok` (la variable est **définie**, possiblement vide) |
| `env_eq:<NAME>=<value>`       | `NAME` est définie et sa valeur égale `<value>` **exactement**                        |
| `glob_exists:<pattern>`       | au moins un chemin sous le worktree correspond à `<pattern>` (supporte `**`)          |

Les atomes sont sensibles à la casse. Les espaces autour des deux-points et autour des opérateurs booléens sont tolérés. Les mots-clés inconnus valent `true` par défaut afin que les anciennes configs continuent de tourner, tandis que `gwm doctor` (check #3) les fait remonter en Warning.

## composition booléenne

| Opérateur | Signification | Précédence       |
|:----------|:--------------|:-----------------|
| `!`       | NOT           | la plus haute    |
| `&&`      | AND           | intermédiaire    |
| `\|\|`    | OR            | la plus basse    |

Ainsi `!a && b || c` se parse comme `((!a) && b) || c` — comme dans la plupart des langages.

Les espaces autour des opérateurs sont tolérés, mais les opérateurs eux-mêmes doivent être exactement `!`, `&&`, `||` — pas de `not`, `and`, `or`, pas d'Unicode.

## exemples

```toml
# Run only when composer.json exists at the worktree root.
[[bootstrap.command]]
name = "composer install"
run  = "composer install --no-interaction --prefer-dist"
when = "file_exists:composer.json"

# Prefer bun if available, otherwise fall back to npm — and never in CI.
[[bootstrap.command]]
name = "install (bun)"
run  = "bun install"
when = "file_exists:package.json && cmd_exists:bun && !env_set:CI"

[[bootstrap.command]]
name = "install (npm fallback)"
run  = "npm ci"
when = "file_exists:package.json && !cmd_exists:bun && !env_set:CI"

# Build docs only when there's something to build and we're not in CI.
[[bootstrap.command]]
name = "build docs"
run  = "./scripts/full-build.sh"
when = "glob_exists:docs/**/*.md && !env_set:CI"

# Apply staging-only seeds when APP_ENV is exactly "staging".
[[bootstrap.command]]
name = "staging seed"
run  = "php artisan db:seed --class=StagingSeeder"
when = "file_exists:artisan && env_eq:APP_ENV=staging"

# Allow a long-running prep step only when the user opts in via env.
[[bootstrap.command]]
name = "warm up cache"
run  = "./scripts/warmup.sh"
when = "env_eq:GWM_WARMUP=1"
```

## `when:` omis

Une étape sans `when:` s'exécute inconditionnellement — équivalent à `when = "true"` (qui n'est pas un littéral que vous pouvez taper ; il suffit d'omettre le champ). Courant pour des commandes de maintenance comme `git lfs pull` qui sont peu coûteuses et toujours sûres.

## couverture par doctor

Le check **#3** de `gwm doctor` (``when` predicates supported`) parse chaque `[[bootstrap.command]].when` et fait remonter les mots-clés inconnus :

```
! `when` predicates supported
    1 unsupported keyword: file_exits
    → did you mean file_exists?
```

Notez le **`!`** (Warning) — la commande fautive s'exécute quand même (vaut `true` par défaut), donc le bootstrap n'est pas bloqué, mais l'utilisateur voit la faute de frappe au moment de la config au lieu d'attendre un échec déroutant.

## en lien

- [Pipeline de bootstrap]/fr/configuration/bootstrap — où se situe l'étape `[[bootstrap.command]]`
- [schéma `.gwm.toml`]/fr/configuration/gwm-toml#bootstrapcommand — la liste complète des champs
- [Intégrations → `gwm doctor`]/fr/integrations/doctor — checks #2 (références de guards) et #3 (grammaire des prédicats)