# golib — gestion moderne des chemins (équivalent de `pathlib` de Python)

Source : https://docs.berkios.online/modules/golib/ · Section : Modules · Documentation officielle BERKIOS (https://docs.berkios.online)


Bibliothèque `golib` 1.0.0 : 37 commandes pour **lire, construire et comparer des chemins** de fichiers sans écrire de séparateurs à la main, avec les mêmes règles que `pathlib` (`PurePosixPath`, `PureWindowsPath`) et `os.path` de Python 3.12. Noms Python, français, espagnols et swahilis. Aucune permission : les commandes ne touchent pas au disque.

## Démarrage

Ajoutez `golib` au projet (Studio → *Code → Bibliothèques*), puis dans le code d'un composant :

```
quand clic
  joinpath "$chemin" "/projets" "facture" "2026.pdf"     # /projets/facture/2026.pdf
  name "$nom" "$chemin"                                  # 2026.pdf
  with_suffix "$copie" "$chemin" ".bak"                  # /projets/facture/2026.bak
  relative_to "$rel" "$chemin" "/projets"                # facture/2026.pdf
  splitext "$racine" "$ext" "$chemin"                    # /projets/facture/2026  et  .pdf
```

Sans bibliothèque, les mêmes fonctions existent comme commandes intégrées de la catégorie **Chemins** (`chemin-assembler`, `chemin-element`, `chemin-avec-suffixe`, `chemin-relatif-a`, `chemin-scinder-ext`…), sans conflit avec `chemin-joindre`, `chemin-nom` et `chemin-dossier` de la bibliothèque `fichiers`. Les commandes de golib sont des macros vers ces commandes intégrées.

## Règles à connaître

- **Résultat en premier** : `commande "$resultat" "chemin" …` (comme `randomy`). `splitext` et `split` écrivent deux résultats : `splitext "$racine" "$extension" "chemin"`.
- **Style POSIX ou Windows, reconnu automatiquement** : un chemin avec lecteur (`C:`), un chemin UNC (`\\serveur\partage`) ou des antislash sans barre oblique est lu comme un chemin Windows, sinon comme un chemin POSIX. `set_style posix` / `set_style windows` force le style, `set_style auto` revient au défaut.
- **Antislash doublés** : dans un texte BERKIOS CODE, `\\` désigne un antislash. Pour `C:\Users\ana`, écrivez `"C:\\Users\\ana"` (ou `"C:/Users/ana"`, lu lui aussi comme un chemin Windows grâce au lecteur).
- **Calcul lexical** : `normpath`, `abspath`, `relpath`, `relative_to`… calculent sur le texte ; `..` n'est jamais résolu à travers un lien symbolique, aucun fichier n'est lu.
- **Répertoire courant virtuel** : `abspath` et `relpath` partent de `getcwd` (`/` au départ) ; `chdir "/projets/app"` le change (sans disque).
- **Listes** : `parts`, `parents`, `suffixes` écrivent leurs éléments séparés par `, `.
- **Booléens** : `true` / `false`.
- **Erreurs** : comme en Python (`ValueError`), l'erreur arrête le script avec un message en français : nom vide, suffixe sans point, chemin qui n'est pas sous la base, mélange absolu/relatif dans `commonpath`…

## Commandes

| Syntaxe | Noms français · espagnol · swahili | Rôle |
|---|---|---|
| `name "Résultat" "Chemin"` | `nom` · `nombre` · `jina` | Dernier élément du chemin (Path.name) : « c.txt » pour a/b/c.txt ; vide pour la racine. |
| `stem "Résultat" "Chemin"` | `radical` · `nombre-base` · `jina-msingi` | Nom sans son dernier suffixe (Path.stem) : « archive.tar » pour archive.tar.gz. |
| `suffix "Résultat" "Chemin"` | `suffixe` · `sufijo` · `kiambishi` | Dernier suffixe avec son point (Path.suffix) : « .gz » ; vide pour .bashrc. |
| `suffixes "Résultat" "Chemin"` | `tous-suffixes` · `sufijos` · `viambishi` | Tous les suffixes, séparés par des virgules (Path.suffixes) : « .tar, .gz ». |
| `parent "Résultat" "Chemin"` | `dossier-parent` · `padre` · `mzazi` | Dossier parent (Path.parent) : a/b pour a/b/c ; « . » pour un nom seul. |
| `parents "Résultat" "Chemin"` | `dossiers-parents` · `padres` · `wazazi` | Tous les ancêtres, du plus proche au plus lointain (Path.parents). |
| `parts "Résultat" "Chemin"` | `parties` · `partes` · `sehemu` | Parties du chemin séparées par des virgules (Path.parts) ; l'ancre vient en premier. |
| `part_at "Résultat" "Chemin" position` | `partie-numero` · `parte-numero` · `sehemu-namba` | Une partie du chemin (Path.parts[i]) : 1 = la première, -1 = la dernière. |
| `drive "Résultat" "Chemin"` | `lecteur` · `unidad` · `diski` | Lecteur Windows (« C: » ou partage UNC) ; vide en POSIX (Path.drive). |
| `root "Résultat" "Chemin"` | `racine-chemin` · `raiz-ruta` · `mzizi` | Racine du chemin (Path.root) : « / » ou « \ » ; vide pour un chemin relatif. |
| `anchor "Résultat" "Chemin"` | `ancre` · `ancla` · `nanga` | Lecteur + racine (Path.anchor) : « C:\ », « / ». |
| `depth "Résultat" "Chemin"` | `profondeur` · `profundidad` · `kina` | Nombre d'éléments du chemin sans l'ancre (a/b/c donne 3). |
| `is_absolute "Résultat" "Chemin"` | `est-absolu` · `es-absoluta` · `ni-kamili` | true si le chemin est absolu (Path.is_absolute) ; sous Windows : lecteur ET racine. |
| `is_reserved "Résultat" "Chemin"` | `est-reserve` · `es-reservada` · `imehifadhiwa` | true si le nom est réservé par Windows (NUL, CON, COM1…) ; toujours false en POSIX. |
| `as_posix "Résultat" "Chemin"` | `en-posix` · `como-posix` · `kama-posix` | Chemin avec des / (Path.as_posix) : C:\a\b devient C:/a/b. |
| `as_windows "Résultat" "Chemin"` | `en-windows` · `como-windows` · `kama-windows` | Chemin au format Windows (a/b devient a\b). |
| `as_uri "Résultat" "Chemin"` | `en-uri` · `como-uri` · `kama-uri` | Adresse file:// d'un chemin absolu (Path.as_uri), encodée en UTF-8. |
| `joinpath "Résultat" "a" "b" ["c" …]` | `joindre` · `unir-ruta` · `unganisha-njia` | Assemble jusqu'à 8 morceaux (Path.joinpath ou opérateur /) : un morceau absolu remplace ce qui précède. |
| `with_name "Résultat" "Chemin" "nom.ext"` | `avec-nom` · `con-nombre` · `na-jina` | Remplace le dernier élément (Path.with_name). |
| `with_stem "Résultat" "Chemin" "radical"` | `avec-radical` · `con-nombre-base` · `na-jina-msingi` | Remplace le nom en gardant l'extension (Path.with_stem). |
| `with_suffix "Résultat" "Chemin" ".ext"` | `avec-suffixe` · `con-sufijo` · `na-kiambishi` | Remplace, ajoute ou retire (texte vide) le suffixe (Path.with_suffix). |
| `relative_to "Résultat" "Chemin" "Base" [remonter]` | `relatif-a` · `relativa-a` · `jamaa-na` | Chemin relatif à Base (Path.relative_to) ; « remonter » (walk_up) autorise les « .. ». |
| `is_relative_to "Résultat" "Chemin" "Base"` | `est-relatif-a` · `es-relativa-a` · `ni-jamaa-na` | true si le chemin est Base ou se trouve dessous (Path.is_relative_to). |
| `match "Résultat" "Chemin" "*.txt"` | `motif-correspond` · `coincide` · `lingana` | Motif comparé depuis la droite (Path.match) : * ? [abc] [!abc]. |
| `full_match "Résultat" "Chemin" "**/*.py"` | `motif-complet` · `coincide-total` · `lingana-kamili` | Motif sur le chemin entier (Path.full_match, Python 3.13) ; ** = zéro ou plusieurs éléments. |
| `equals "Résultat" "A" "B"` | `egaux` · `iguales` · `sawa` | true si les deux chemins sont identiques (sans casse sous Windows). |
| `normpath "Résultat" "Chemin"` | `normaliser` · `normalizar` · `sawazisha` | Réduit « . », « .. » et les séparateurs répétés (os.path.normpath). |
| `abspath "Résultat" "Chemin" ["Base"]` | `rendre-absolu` · `ruta-absoluta` · `njia-kamili` | Chemin absolu normalisé (os.path.abspath) depuis Base ou le répertoire courant virtuel. |
| `relpath "Résultat" "Chemin" ["Début"]` | `relatif-de` · `ruta-relativa` · `njia-jamaa` | Chemin relatif depuis Début (os.path.relpath). |
| `commonpath "Résultat" "a" "b" ["c" …]` | `commun` · `ruta-comun` · `njia-ya-pamoja` | Plus long dossier commun de 2 à 8 chemins (os.path.commonpath). |
| `splitext "$racine" "$extension" "Chemin"` | `scinder-ext` · `dividir-ext` · `gawa-kiambishi` | Sépare racine et extension (os.path.splitext). |
| `split "$tete" "$queue" "Chemin"` | `scinder` · `dividir-ruta` · `gawa-njia` | Sépare dossier et dernier élément (os.path.split). |
| `basename "Résultat" "Chemin"` | `queue` · `ultimo` · `wa-mwisho` | Dernier élément (os.path.basename) ; vide si le chemin finit par un séparateur. |
| `dirname "Résultat" "Chemin"` | `tete` · `cabeza` · `kichwa` | Tout sauf le dernier élément (os.path.dirname). |
| `set_style auto/posix/windows` | `style-chemin` · `estilo-ruta` · `mtindo-njia` | Choisit la lecture des chemins : auto (défaut), posix ou windows. |
| `getcwd "Résultat"` | `dossier-courant` · `directorio-actual` · `saraka-ya-sasa` | Répertoire courant virtuel (os.getcwd) : « / » au départ. |
| `chdir "Chemin"` | `aller-dans` · `ir-a` · `nenda` | Change le répertoire courant virtuel (os.chdir, sans disque). |

Le nom Python est le premier nom de chaque commande ; le nom qualifié (`golib.name`) fonctionne toujours.

## Différences avec pathlib

| pathlib | golib |
|---|---|
| objets `Path` | des textes (un chemin est toujours un texte) |
| `p / "x"` | `joinpath "$r" "$p" "x"` |
| `Path.exists()`, `read_text()`, `mkdir()`, `iterdir()`… | **absents** (golib ne touche pas au disque) : utilisez la bibliothèque `fichiers` avec le chemin calculé par golib |
| `Path.cwd()`, `os.getcwd()` | `getcwd` : répertoire courant **virtuel** |
| `Path.resolve()` | `abspath` (résolution lexicale ; pas de liens symboliques) |
| `os.path.isabs` | `is_absolute` (règle de `Path.is_absolute` : sous Windows, lecteur **et** racine) |
| `Path.match` | `match` (règle de Python 3.12 : `**` y vaut `*`) ; `full_match` suit Python 3.13 |
| `Path.expanduser`, `os.path.expandvars` | absents (pas d'environnement) |
| `Path.is_relative_to`, `relative_to(walk_up=True)` | `is_relative_to`, `relative_to … remonter` |
| `Path.with_segments`, sous-classes | absents |

## Vérification

- `studio/tests/path-engine.test.ts` compare le moteur (`studio/src/model/path-engine.ts`) à **CPython 3.12.3** sur 2 405 opérations et les propriétés de 73 chemins POSIX et Windows : mêmes résultats, y compris les cas limites (`//a`, `C:a`, `\\serveur\partage`, `.bashrc`, `a.`, `NUL.txt`, `..\x`, `.\C:x`). Les vecteurs sont générés par `python3 scripts/gen-path-reference.py`.
- `studio/tests/library-golib.test.ts` : validité de la bibliothèque, aucun conflit de nom avec les commandes intégrées, résultats en 4 langues, chemins Windows, erreurs.
- `full_match` suit Python 3.13 et n'a pas pu être comparé à CPython 3.13 (non disponible ici) : il est vérifié par des cas écrits à la main.

## Limites
- **Le port Dart n'est pas fait** : comme Randomy, les commandes fonctionnent dans l'aperçu du Studio, pas encore dans l'application Flutter générée (Dart n'est pas compilable dans l'environnement de développement ; les tables `scripts/generate-dart-script-tables.mjs` n'ont pas été régénérées).
- `joinpath` et `commonpath` acceptent 8 chemins au plus dans la bibliothèque (limite de 9 arguments des macros) ; les commandes intégrées `chemin-assembler` et `chemin-commun` n'ont pas cette limite.
- Un texte sans lecteur ni antislash est lu en POSIX : pour des chemins Windows avec des `/` seulement (`a/b/c`), utilisez `set_style windows`.
- Traductions espagnoles et swahilies non relues par des locuteurs natifs.
- Les noms réservés Windows (`is_reserved`) suivent la liste de Python 3.12 (`CON`, `PRN`, `AUX`, `NUL`, `COM1-9`, `LPT1-9`, `CONIN$`, `CONOUT$` et leurs variantes exposants).
