Interface en Ligne de Commande (CLI)
Documentation complète de la ligne de commande Catnip.
Console basse friction : des flags comme vecteurs de trajectoire.
Quand utiliser le CLI ?
Le CLI Catnip est conçu pour deux use cases principaux :
1. Développement et Exploration (REPL)
- Tester la syntaxe Catnip interactivement
- Débugger des expressions et scripts
- Explorer les fonctionnalités du langage
- Prototyper rapidement des transformations
catnip # Lance REPL
2. Scripts de Traitement de Données
- Scripts one-off de transformation de données
- Configuration DSL chargée depuis fichiers
- Automatisation de tâches simples
catnip transform_data.cat
Note importante : Embedded vs Standalone
Si tu écris beaucoup de scripts Catnip standalone → c'est probablement un use case où Python serait plus adapté.
Catnip est avant tout un moteur embedded :
| Use Case | Recommandation |
|---|---|
| Règles métier modifiables par administrateurs | Embedded - Stockez scripts en DB, exécutez dans app |
| Sandbox pour scripts utilisateur | Embedded - Isolation + APIs exposées |
| Pipelines ETL configurables | Embedded - Workflows définis par utilisateurs |
| Script de traitement ponctuel | Standalone possible, mais Python souvent meilleur |
| Application complète en Catnip | Pas le bon outil - Utilisez Python |
Règle empirique : Si votre script Catnip fait plus de 200 lignes ou nécessite imports complexes, vous devriez probablement utiliser Python avec Catnip embedded pour les parties configurables.
Voir docs/examples/embedding/ pour patterns d'intégration.
Modes d'Exécution
Runtime Rust Standalone (catnip-standalone)
Catnip fournit également un binaire Rust standalone qui embarque Python :
# Installation (depuis source uniquement)
cd catnip
make install-bins # Installe catnip-standalone + catnip-repl
# Utilisation (mêmes options que CLI Python)
catnip-standalone script.cat
catnip-standalone -c "2 + 3"
echo "x = 10; x * 2" | catnip-standalone --stdin
# Version
catnip-standalone --version
Caractéristiques :
- VM avec JIT
- Startup rapide pour scripts
- Pas de dépendance Python système
Note : Les binaires standalone ne sont pas inclus dans les wheels PyPI (manylinux) en raison de limitations de Python statique. Ils sont disponibles via :
- Installation locale :
make install-bins - GitHub releases : binaires précompilés par plateforme
- Cargo :
cargo install --path catnip_rs --bin catnip-standalone --features embedded
Voir docs/user/STANDALONE.md pour détails.
REPL Interactif
Lance une session interactive (mode par défaut) :
catnip
La REPL maintient un contexte persistant entre les commandes :
$ catnip
▸ x = 10
▸ x * 2
20
▸ factorial = (n) => { if (n <= 1) { 1 } else { n * factorial(n-1) } }
▸ factorial(5)
120
Exécution de Script
Forme courte (fallback automatique)
catnip script.cat
Si l'argument n'est pas une sous-commande reconnue (format, lint), Catnip l'interprète comme un fichier à exécuter.
Forme explicite (avec --)
catnip -- script.cat
Le séparateur -- force l'interprétation comme fichier, levant toute ambiguïté. Utile si un fichier s'appelle format
ou lint.
Avec options
# TCO activé
catnip -o tco:on script.cat
# Mode verbeux
catnip -v script.cat
# Multiple options
catnip -o tco:on -v --no-color script.cat
Évaluation de Commande
Évalue une expression et affiche le résultat :
catnip -c "2 + 3 * 4"
# Output: 14
catnip -c "debug(42)"
# Output: 42
catnip -c "x = 10; x * 2"
# Output: 20
Mode Pipe (stdin)
Lit depuis l'entrée standard :
echo "10 * 2" | catnip
# Output: 20
cat script.cat | catnip
# Avec options
echo "factorial(10)" | catnip -o tco:on
Options Globales
Configuration
--config FILE
Utilise un fichier de configuration alternatif :
# Utiliser une config custom
catnip --config my-catnip.toml script.cat
# Afficher la config utilisée
catnip --config my-catnip.toml config show
# Formatter avec config custom
catnip --config my-catnip.toml format code.cat
Par défaut, Catnip charge ~/.config/catnip/catnip.toml. L'option --config permet de spécifier un fichier alternatif, utile pour :
- Configs par projet (versionner
catnip.tomldans git) - Environnements différents (dev, staging, prod)
- Tests avec différentes configurations
Voir Configuration pour le format du fichier.
Options de Parsing
-p, --parsing LEVEL
Niveau de parsing (0-3, défaut : 3) :
0: Parse tree Tree-sitter (arbre brut)1: IR après transformer2: IR exécutable après analyse sémantique3: Exécute et affiche le résultat (défaut)
# Afficher l'IR
catnip -p 1 -c "2 + 3"
# Afficher l'IR optimisé
catnip -p 2 script.cat
Note : Cette option est principalement destinée au développement du langage et à l'inspection des résultats des
optimiseurs. Les utilisateurs finaux n'ont généralement pas besoin de modifier cette valeur (utiliser la valeur par
défaut 3).
Options d'Optimisation
-o, --optimize OPT
Active des optimisations (peut être utilisé plusieurs fois) :
TCO (Tail-Call Optimization) :
# Active TCO
catnip -o tco script.cat
catnip -o tco:on script.cat
# Désactive TCO
catnip -o tco:off script.cat
Niveau d'optimisation (défaut: 3 - optimisations complètes) :
# Niveaux explicites
catnip -o level:0 script.cat # Aucune optimisation
catnip -o level:1 script.cat # Légère (constant folding)
catnip -o level:2 script.cat # Moyenne (IR passes)
catnip -o level:3 script.cat # Aggressive (IR + CFG) - défaut
# Alias lisibles
catnip -o level:none script.cat # Niveau 0
catnip -o level:low script.cat # Niveau 1
catnip -o level:medium script.cat # Niveau 2
catnip -o level:high script.cat # Niveau 3 (défaut)
Le défaut level:3 active toutes les optimisations (constant folding, dead code elimination, CSE, etc.). Utiliser level:0 pour réduire la latence de compilation au détriment des performances d'exécution. Voir docs/dev/OPTIMIZATIONS.md pour les détails et trade-offs.
Options de Chargement de Modules
-f, --feature TARGET[:ALIAS]
Charge un module Python comme namespace :
# Module installé
catnip -f math script.cat
# Dans le script : math.sqrt(16)
# Fichier local
catnip -f ./module.py script.cat
# Dans le script : module.ma_fonction(10)
# Avec alias
catnip -f math:m script.cat
# Dans le script : m.sqrt(16)
# Injection directe (:!)
catnip -f math:! script.cat
# Dans le script : sqrt(16)
Charger plusieurs modules
catnip -f math:m -f random:r script.cat
catnip -f ./db.py:db -f ./api.py:api script.cat
# Mode mixte (namespace + injection)
catnip -f math:m -f random:! script.cat
Options de Debug
-v, --verbose
Affiche les étapes détaillées du pipeline :
catnip -v script.cat
--format FORMAT
Format de sortie pour les niveaux de parsing 1-2 :
text: Format texte lisible (défaut)json: Sérialisation JSON structurée de l'IR
# Afficher l'IR en JSON (niveau 1)
catnip -p 1 --format json -c "2 + 3"
# IR optimisé en JSON (niveau 2)
catnip -p 2 --format json script.cat
Le format JSON expose la structure complète de l'IR :
{
"ir": [{
"Op": {
"opcode": "Add",
"args": [{"Tuple": [{"Int": 2}, {"Int": 3}]}],
"kwargs": {},
"tail": false,
"start_byte": 0,
"end_byte": 5
}
}],
"level": 1
}
Utile pour :
- Analyse programmatique de l'IR
- Intégrations avec des outils externes
- Debugging des transformations du compilateur
- Inspection détaillée de la structure AST
Note : Le format JSON n'est disponible que pour les niveaux de parsing 1 et 2. Le niveau 0 (parse tree) et le niveau 3 (exécution) utilisent toujours le format texte.
--no-color
Désactive la sortie colorée :
catnip --no-color script.cat
--no-cache
Désactive le cache disque de compilation (parsing et bytecode). Par défaut, le cache est activé et stocke les résultats de parsing dans ~/.cache/catnip/ pour accélérer les exécutions suivantes.
# Exécuter sans utiliser le cache
catnip --no-cache script.cat
# Utile pour forcer une recompilation
catnip --no-cache -c "2 + 2"
Par défaut : Le cache est activé. Chaque script parsé est mis en cache avec sa configuration (niveau d'optimisation, TCO, etc.).
Désactivation persistante : Via config (fichier catnip.toml).
Variables d'environnement
Configuration
| Variable | Description | Valeurs |
|---|---|---|
CATNIP_OPTIMIZE |
Options d'optimisation (même syntaxe que -o) |
jit, tco:off, level:2, combinables avec virgule |
CATNIP_EXECUTOR |
Mode d'exécution | vm (défaut), ast, shadow |
NO_COLOR |
Désactive les couleurs (standard freedesktop.org) | toute valeur non vide |
Hiérarchie de priorité (croissante) :
défauts → catnip.toml → variables d'environnement → options CLI
# Activer JIT et réduire le niveau d'optimisation
CATNIP_OPTIMIZE=jit,level:2 catnip script.cat
# CLI override l'environnement
CATNIP_OPTIMIZE=jit catnip -o jit:off script.cat # JIT désactivé
# Voir les sources des valeurs
catnip config show --debug
Chemins XDG
| Variable | Défaut | Usage |
|---|---|---|
XDG_CONFIG_HOME |
~/.config |
Fichier config (catnip/catnip.toml) |
XDG_STATE_HOME |
~/.local/state |
Historique REPL (catnip/repl_history) |
XDG_CACHE_HOME |
~/.cache |
Cache de compilation (catnip/) |
XDG_DATA_HOME |
~/.local/share |
Données persistantes (catnip/) |
Mode d'Exécution
-x MODE, --executor MODE
Sélectionne le moteur d'exécution :
vm: Compilation bytecode + VM (défaut)ast: Interprétation AST (pour debug ou compatibilité)shadow: VM + AST en parallèle avec comparaison (validation optimisations)
# Mode VM (défaut)
catnip script.cat
# Mode AST (interpréteur classique)
catnip -x ast script.cat
# Mode shadow (compare VM et AST)
catnip -x shadow script.cat
# Via variable d'environnement
CATNIP_EXECUTOR=vm catnip script.cat # Équivalent à -x vm
CATNIP_EXECUTOR=ast catnip script.cat # Équivalent à -x ast
Performances : Le mode VM compile le code en bytecode et l'exécute sur une VM à pile, éliminant l'overhead Python ↔ VM.
La VM est le mode d'exécution par défaut. Utiliser -x ast si besoin de l'interpréteur classique.
Mode shadow : Exécute le code via VM et AST simultanément, puis compare les résultats. Utilisé principalement en tests pour valider que les optimisations VM produisent les mêmes résultats que l'AST.
Autres Options
--version
Affiche la version de Catnip :
catnip --version
--help
Affiche l'aide :
catnip --help
Sous-Commandes
Les sous-commandes sont extensibles via le système de plugins (entry points Python).
format
Formate le code source Catnip selon les conventions du projet.
Implémentation : Rust
# Formater un fichier (affiche sur stdout)
catnip format script.cat
# Formater plusieurs fichiers en place
catnip format src/*.cat --in-place
catnip format src/*.cat -i
# Formater depuis stdin
echo "x=1+2" | catnip format --stdin
catnip format --stdin < script.cat
# Vérifier si formaté (exit 1 si pas formaté - utile en CI)
catnip format --check src/*.cat
# Afficher le diff
catnip format --diff script.cat
# Options de style
catnip format --indent-size 2 script.cat
catnip format --line-length 100 script.cat
# Avec config custom
catnip --config my-catnip.toml format script.cat
Options :
--stdin: Lire depuis stdin--in-place,-i: Modifier fichiers en place--check: Vérifier formatage (exit 1 si non formaté)--diff: Afficher unified diff au lieu du code formaté--indent-size N: Taille indentation (défaut: 4 ou depuis config)--line-length N: Longueur ligne max (défaut: 88 ou depuis config)
Configuration : Section [format] dans catnip.toml :
[format]
indent_size = 4
line_length = 88
Variables d'environnement :
CATNIP_FORMAT_INDENT_SIZE=2CATNIP_FORMAT_LINE_LENGTH=100
Priorité : défaut < catnip.toml < ENV < CLI flags
Règles de style :
- Espaces autour des opérateurs binaires (
x + y,a == b) - Pas d'espace pour opérateurs unaires (
-x,not y) - Indentation 4 espaces par défaut (configurable)
- Espace avant
{, après, - Préserve commentaires et shebangs
- Max 2 newlines consécutifs
lint
Analyse statique du code (syntaxe, style, sémantique) :
# Analyse complète
catnip lint script.cat
# Syntaxe seulement (rapide)
catnip lint -l syntax script.cat
# Style seulement
catnip lint -l style script.cat
# Sémantique seulement
catnip lint -l semantic script.cat
# Depuis stdin
echo "x = y + 1" | catnip lint --stdin
Voir docs/tools/lint.md pour les codes de diagnostic.
commands
Liste les commandes disponibles (built-ins + plugins) :
# Liste avec descriptions
catnip commands
# Liste sans résolution (plus rapide)
catnip commands --no-resolve
plugins
Inspecte les plugins CLI enregistrés :
# Liste tous les plugins
catnip plugins
# Valide le chargement de chaque plugin
catnip plugins --check
# Exclut les commandes built-in
catnip plugins --no-builtins
# Affiche les entry points
catnip plugins --entrypoints
repl
Démarre explicitement la REPL (équivalent au mode par défaut) :
catnip repl
config
Gère la configuration persistante. Fichier par défaut : ~/.config/catnip/catnip.toml
# Afficher toutes les valeurs
catnip config show
# Afficher avec les sources (default/file/env/cli)
catnip config show --debug
# Obtenir une valeur
catnip config get jit
# Définir une valeur
catnip config set jit true
catnip config set optimize 2
catnip config set executor ast
# Afficher le chemin du fichier
catnip config path
# Utiliser un fichier alternatif
catnip --config my-catnip.toml config show
catnip --config my-catnip.toml config set jit false
Format du fichier : TOML avec sections
# ~/.config/catnip/catnip.toml
[repl]
no_color = false
# Cache de compilation (parsing/bytecode)
enable_cache = true # Activé par défaut
[optimize]
jit = false
tco = true
optimize = 3 # 0=none, 1=low, 2=medium, 3=high
executor = "vm" # vm, ast, shadow
[cache]
cache_max_size_mb = 100 # Limite 100 Mo (ou "unlimited")
cache_ttl_seconds = 86400 # TTL 24 heures (ou "unlimited")
[format]
indent_size = 4
line_length = 88
Voir catnip.toml.example dans le dépôt pour un fichier exemple commenté.
Clés disponibles :
no_color(bool) : Désactive sortie coloréejit(bool) : Active JIT (expérimental)tco(bool) : Active tail-call optimizationoptimize(int) : Niveau optimisation (0-3)executor(str) : Mode exécution (vm/ast/shadow)enable_cache(bool) : Active le cache disque (défaut:true, via fichier)cache_max_size_mb(int|"unlimited") : Taille max cache en Mocache_ttl_seconds(int|"unlimited") : TTL des entrées en secondes
Option --debug : Montre d'où vient chaque valeur :
$ CATNIP_OPTIMIZE=jit catnip -o jit:off config show --debug
Configuration (with sources):
executor: 'vm' [default]
jit: False [cli (-o jit:off)]
no_color: False [default]
optimize: 0 [default]
tco: True [default]
Sources possibles :
default: valeur par défaut hardcodéefile: fichiercatnip.tomlenv: variable d'environnement (CATNIP_OPTIMIZE,CATNIP_EXECUTOR,NO_COLOR)cli: option ligne de commande (-o,-x,--no-color)
cache
Gère le cache de compilation. Le cache est activé par défaut et stocke le parsing et bytecode dans ~/.cache/catnip/ (XDG_CACHE_HOME).
Comportement par défaut : Tous les scripts exécutés sont automatiquement mis en cache.
# Afficher statistiques du cache
catnip cache stats
# Nettoyer les entrées expirées (selon TTL et max_size)
catnip cache prune
# Simulation (dry-run)
catnip cache prune --dry-run
# Supprimer tout le cache
catnip cache clear
# Sans confirmation
catnip cache clear --force
Configuration du cache :
# Définir taille maximale (en Mo)
catnip config set cache_max_size_mb 100
# Définir TTL (en secondes)
catnip config set cache_ttl_seconds 7200 # 2 heures
# Désactiver les limites
catnip config set cache_max_size_mb unlimited
catnip config set cache_ttl_seconds unlimited
Format dans catnip.toml :
# Cache activé par défaut
enable_cache = true # Activer le cache disque (défaut)
[cache]
cache_max_size_mb = 100 # Limite 100 Mo (défaut)
cache_ttl_seconds = 86400 # TTL 24 heures (défaut)
# cache_max_size_mb = unlimited # Pas de limite de taille
# cache_ttl_seconds = unlimited # Pas d'expiration
Statistiques affichées :
- Nombre d'entrées
- Volume total (Mo)
- Limite de taille (si configurée)
- TTL (si configuré)
Debug du cache :
Pour voir les hits/misses en temps réel, activer le mode debug :
CATNIP_CACHE_DEBUG=1 catnip script.cat
Cela affiche sur stderr les événements cache ([cache] HIT ..., [cache] MISS ...).
Comportement de prune :
- Supprime les entrées dont l'âge dépasse
cache_ttl_seconds - Si la taille totale >
cache_max_size_mb, supprime les entrées les moins récemment accédées (LRU)
Plugins CLI
La CLI supporte l'ajout de sous-commandes via des packages Python externes.
Créer un plugin
# mon_plugin/__init__.py
import click
@click.command("mycommand")
@click.argument("file")
@click.pass_context
def mycommand(ctx, file):
"""Ma commande custom."""
verbose = ctx.obj.get("verbose", False)
# ...
# pyproject.toml du plugin
[project.entry-points."catnip.commands"]
mycommand = "mon_plugin:mycommand"
Utiliser un plugin
pip install mon-plugin
catnip mycommand file.cat # Automatiquement disponible
Les options globales (-v, --no-color, etc.) sont accessibles via ctx.obj.
Exemples Complets
Exécution Simple
# REPL
catnip
# Script
catnip script.cat
# Commande
catnip -c "print('Hello, Catnip!')"
# Pipe
echo "2 + 3" | catnip
Avec Optimisations
# TCO pour récursion profonde
catnip -o tco:on recursive_fibonacci.cat
# Mode verbeux + TCO
catnip -v -o tco:on script.cat
Avec Modules Python
# Module installé
catnip -f math script.cat
# Utilisation : math.sqrt(16)
# Module avec alias
catnip -f math:m script.cat
# Utilisation : m.sqrt(16)
# Fichier local
catnip -f ./host.py script.cat
# Utilisation : host.add(5, 10)
# Fichier avec alias
catnip -f ./host.py:api script.cat
# Utilisation : api.add(5, 10)
# Plusieurs modules
catnip -f pandas:pd -f numpy:np data_processing.cat
Debugging
# Afficher l'IR
catnip -p 2 -c "x = 10; x * 2"
# Mode verbeux
catnip -v script.cat
# Sans couleurs (pour logs)
catnip --no-color script.cat > output.log
Combinaisons Avancées
# Tout ensemble
catnip -v -o tco:on -f ./tools.py:t --no-color script.cat
# REPL avec module chargé
catnip -f math:m
# Puis dans la REPL : m.sqrt(42)
# Pipe avec options
cat data.cat | catnip -o tco:on -v
Ordre des Arguments
L'ordre recommandé pour la clarté :
catnip [OPTIONS] [--] [SCRIPT|SUBCOMMAND]
Exemples :
# Options avant le fichier
catnip -o tco:on -v script.cat # ✓ Recommandé
# Séparateur pour lever l'ambiguïté
catnip -o tco:on -- format.cat # ✓ 'format.cat' est un fichier, pas une commande
# Fallback automatique
catnip format.cat # ✗ Ambigu (fichier ou commande ?)
catnip -- format.cat # ✓ Explicite : c'est un fichier
Notes Techniques
Fallback Script
Si l'argument n'est pas une option (-x) ni une sous-commande reconnue, Catnip le traite comme un fichier script.
catnip script.cat # Fallback → exécute le fichier
catnip format script.cat # Sous-commande format
catnip lint script.cat # Sous-commande lint
catnip -- format.cat # Force fichier (même si "format" existe)
Séparateur --
Le séparateur -- garantit qu'aucune confusion ne peut survenir :
catnip format.cat # Ambigu : fichier "format.cat" ou commande "format" ?
catnip -- format.cat # Explicite : c'est le fichier "format.cat"
catnip format file.cat # Explicite : commande "format" sur fichier "file.cat"
Contexte REPL
La REPL maintient un contexte persistant :
$ catnip
▸ x = 10 # Définit x
▸ y = x * 2 # Utilise x
▸ y
20
▸ quit()