5.2 KiB
34. Packages, identité et collisions de namespaces
34.1 Identité indépendante du namespace — V1 REQUIS — FIGÉ
L'identité d'un package est indépendante de ses namespaces internes.
Identité canonique :
vendor/package
Coordonnée exacte :
vendor/package@version
Sélecteur de dépendance :
vendor/package@requirement
Exemples :
saselang/core@1.4.0
saselang/compiler-core@^0.8
acme/http-client@>=2.5,<3.0
sdl/sdl@3.1.*
Le vendor/package désigne l'identité logique. La version exacte ou l'exigence SemVer ne change jamais cette identité ; elle sélectionne une instance/résolution de cette identité.
Le namespace interne peut être totalement différent et ne doit pas être dérivé automatiquement de vendor/package.
34.2 Syntaxe des identifiants package — V1 REQUIS — FIGÉE EN PRINCIPE
Pour vendor et package :
[a-z][a-z0-9]*(?:-[a-z0-9]+)*
Règles :
- ASCII lowercase ;
-sépare les mots à l'intérieur d'un composant ;_est interdit ;- aucune conversion automatique
-<->_n'existe ; /séparevendoretpackage;@introduit une version exacte ou un requirement SemVer.
Cette convention doit fonctionner de manière identique dans les manifests, le resolver, le lockfile, les outils et la qualification from des imports.
34.3 Collision de namespaces — V1 REQUIS — FIGÉ
Deux packages peuvent légalement définir le même namespace et le même nom de symbole sans représenter le même type.
Par exemple, deux packages peuvent chacun fournir :
namespace parser.ast;
public class Node
L'identité sémantique réelle d'un symbole inclut au minimum :
instance de package résolue
+ namespace
+ symbole
Ainsi :
acme/parser@2.4.1 :: parser.ast.Node
other/parser@5.0.0 :: parser.ast.Node
sont deux types distincts.
34.4 Qualification d'import par dépendance — V1 REQUIS — FIGÉ
Tout symbole provenant d'une dépendance externe doit être importé explicitement avec une clause from contenant son sélecteur canonique :
from "vendor/package@requirement"
Direction syntaxique :
import func some.namespace::function from "sdl/sdl@2.1.*" as sdlfun1;
import type some.namespace.Type from "acme/parser@^3.0" as ParserType;
La grammaire finale des différentes formes import type|func|const|var reste à harmoniser avec la grammaire lexicale complète, mais les règles sémantiques suivantes sont figées :
fromest obligatoire pour toute provenance extérieure au package courant ;- le sélecteur
vendor/package@requirementdoit correspondre à un requirement effectivement déclaré dans le scope de dépendances applicable au fichier/package ; fromne déclenche jamais une résolution ad hoc ;- le lockfile associe ce requirement à une version exacte résolue ;
- les dépendances transitives ne sont pas directement importables : un package qui utilise directement leur API doit les déclarer comme dépendances directes ;
- après l'import, le code utilise le nom local du symbole ou son alias ; la coordonnée package n'apparaît pas dans les expressions ordinaires.
Sans from, un import ne peut viser que le package courant.
L'alias as reste facultatif lorsque le nom local obtenu est unique dans le fichier. Il devient nécessaire lorsque plusieurs imports produiraient le même nom local ou lorsqu'un renommage explicite est souhaité.
34.5 Plusieurs versions directes d'une même identité — V1 REQUIS — FIGÉ EN PRINCIPE
Un même package consommateur peut déclarer plusieurs requirements directs pour le même vendor/package afin d'utiliser plusieurs lignées incompatibles en parallèle.
Exemple conceptuel :
sdl/sdl@2.1.*
sdl/sdl@^3.0
Le code choisit explicitement l'instance souhaitée avec from :
import func ... from "sdl/sdl@2.1.*" as sdlfun1;
import func ... from "sdl/sdl@^3.0" as sdlfun2;
Si les deux imports exposent le même nom terminal dans le même fichier, des alias locaux distincts sont obligatoires. La sélection de version ne peut pas être reportée à un chemin pleinement qualifié utilisé directement dans le corps du code.
Pour un même scope effectif de dépendances, deux requirements portant sur le même vendor/package doivent être disjoints.
Exemples autorisés :
sdl/sdl@2.1.*
sdl/sdl@^3.0
Exemples interdits :
sdl/sdl@>=1.0
sdl/sdl@^4.5
car les ensembles de versions acceptées se recouvrent.
De même :
sdl/sdl@^3.0
sdl/sdl@3.1.*
est interdit puisque 3.1.* appartient déjà à ^3.0.
Le resolver doit détecter l'intersection SemVer des requirements avant résolution. Une intersection non vide est une erreur de manifest, même si une version particulière permettrait techniquement de satisfaire les deux requirements.
Cette règle supprime toute ambiguïté entre plusieurs slots directs de la même identité et rend from "vendor/package@requirement" déterministe.
Le graphe transitif peut lui aussi contenir plusieurs versions d'une même identité. Chaque instance résolue conserve une identité de type distincte lorsque les versions ne sont pas unifiées par le resolver.