Files
saselang-bible/chapters/037-dependances-et-scopes.md
2026-09-12 08:56:27 +02:00

8.7 KiB

37. Dépendances et scopes

37.1 Deux axes indépendants — V1 REQUIS — FIGÉ

Une dépendance est décrite selon deux axes distincts :

kind   = nature logique de la dépendance
source = moyen utilisé pour la localiser/résoudre

V1 fixe au minimum les kind suivants :

saselang
native

Les sources prévues par le schéma V1 sont :

workspace
registry
local
git
artifact
system

Toutes les combinaisons ne sont pas nécessairement implémentées dès la première toolchain V1. Le schéma doit néanmoins permettre de les représenter sans refonte ultérieure.

Les dépendances npm/JVM/WASM et autres écosystèmes sont FUTUR V3+, mais doivent pouvoir être ajoutées comme nouveaux kind/modes de résolution sans changer l'identité canonique des dépendances.

37.2 Syntaxe unique des dépendances — V1 REQUIS — FIGÉE EN PRINCIPE

Tous les scopes et toutes les sources utilisent la même enveloppe TOML :

[dependencies."vendor/package@requirement"]
kind = "saselang"
source = "registry"
locator = "saselang"

Il n'existe pas en parallèle des raccourcis incompatibles de type :

foo = "^1.2"
foo = "../foo"

La clé canonique reste :

vendor/package@requirement

locator désigne le moyen physique de retrouver la dépendance selon source. Sa sémantique exacte dépend de cette source, mais son rôle reste unique.

Exemples :

[dependencies."acme/math@^2.4"]
kind = "saselang"
source = "git"
locator = "https://example.org/acme/math.git"
[dependencies."acme/local-tools@^1.0"]
kind = "saselang"
source = "local"
locator = "../local-tools"
[dependencies."acme/parser@=1.4.2"]
kind = "saselang"
source = "artifact"
locator = "../libs/parser.saselib"
[dependencies."sdl/sdl@^3.0"]
kind = "native"
source = "system"
locator = "SDL3"

37.3 Dépendance workspace — V1 REQUIS — FIGÉE EN PRINCIPE

Le workspace peut définir un catalogue :

[workspace.dependencies."sdl/sdl@^3.0"]
kind = "native"
source = "system"
locator = "SDL3"

Un projet doit sélectionner explicitement l'entrée :

[dependencies."sdl/sdl@^3.0"]
kind = "native"
source = "workspace"

Le kind doit correspondre à celui défini par le catalogue. Une entrée du catalogue n'est jamais injectée automatiquement dans tous les projets.

37.4 Scopes V1 — V1 REQUIS — FIGÉS

Les scopes requis en V1 sont :

dependencies
build.dependencies

dev.dependencies
dev.unit.dependencies
dev.integration.dependencies
dev.environment.dependencies

Les scopes suivants sont réservés mais non normatifs tant que leurs workflows ne sont pas définis :

dev.benchmark.dependencies
dev.documentation.dependencies
dev.example.dependencies

dependencies contient les dépendances du produit.

build.dependencies constitue un graphe de visibilité séparé destiné aux outils/hooks de build ; une build-dependency ne devient pas importable par le produit.

dev.dependencies est commun aux contextes de développement.

Les scopes dev.unit, dev.integration et dev.environment spécialisent respectivement les tests unitaires, les tests d'intégration et les environnements/outils externes de développement/test.

37.5 Héritage des scopes — V1 REQUIS — FIGÉ

dev.unit effective =
    dependencies
  + dev.dependencies
  + dev.unit.dependencies

Même règle pour dev.integration et dev.environment.

build.dependencies n'est pas ajouté à la visibilité des imports du produit ni des tests ; il appartient au graphe du système de build.

37.6 Remplacement entre scopes — V1 REQUIS — FIGÉ

L'unité de shadowing entre scopes est l'identité :

vendor/package

Dès qu'un scope enfant déclare au moins une entrée pour cette identité, toutes les entrées héritées de cette même identité sont masquées dans ce scope.

Si plusieurs versions doivent réellement coexister dans le scope enfant, toutes leurs contraintes disjointes sont redéclarées explicitement dans ce scope.

Aucune fusion implicite champ par champ n'est effectuée.

37.7 Multi-version direct — V1 REQUIS — FIGÉ

Un même scope effectif peut contenir plusieurs selectors d'une même identité uniquement si leurs ensembles de versions sont deux à deux disjoints.

Valide :

sdl/sdl@2.1.*
sdl/sdl@^3.0

Interdit :

sdl/sdl@^3.0
sdl/sdl@3.1.*

Le resolver doit détecter les intersections de ranges et produire une erreur de manifest déterministe avant compilation.

37.8 Dépendance Saselang normale — V1 REQUIS — FIGÉ

Une dépendance de kind = "saselang" désigne toujours un package logique :

vendor/package@requirement

L'artifact de bibliothèque Saselang consommé après résolution/build est une .saselib.

Une source local ou git désigne normalement les sources du package ; artifact peut désigner directement une .saselib précompilée.

37.9 Dépendances natives — V1 REQUIS — FIGÉ EN PRINCIPE

Une bibliothèque native est également encapsulée derrière :

vendor/package@requirement

Par exemple :

sdl/sdl@^3.0

peut représenter physiquement :

Linux   -> libSDL3.so / SONAME approprié
Windows -> SDL3.dll + import library éventuelle
macOS   -> libSDL3.dylib ou framework approprié

Le nom physique n'est jamais l'identité logique de la dépendance.

Le même schéma de dépendance doit pouvoir porter des mappings conditionnés par target/platform/ABI/distribution. La syntaxe exacte du mapping natif sera finalisée avec la FFI et le linker, mais aucune nouvelle forme d'identité ne devra être introduite.

37.9.1 Variants natifs et sélection par environnement — V1 REQUIS — SQUELETTE FIGÉ

Une dépendance native possède une déclaration logique commune et peut ajouter une liste homogène de variants lorsque sa représentation physique dépend de l'environnement.

Exemple conceptuel :

[dependencies."sdl/sdl@^3.0"]
kind = "native"
source = "system"
locator = "SDL3"

[[dependencies."sdl/sdl@^3.0".variants]]
platform = "linux"
library = "SDL3"

[[dependencies."sdl/sdl@^3.0".variants]]
platform = "windows"
library = "SDL3"

Un variant peut contraindre une combinaison des dimensions suivantes :

target-family
platform
architecture
abi
distribution
distribution-version
capabilities

Les variants n'introduisent jamais une nouvelle identité de dépendance : l'identité logique reste vendor/package@requirement.

Un variant plus spécifique prévaut sur un variant strictement moins spécifique lorsque les deux correspondent. Si plusieurs variants applicables sont incomparables en spécificité et qu'aucun n'est l'unique meilleur candidat, le manifest est ambigu et la toolchain doit produire une erreur déterministe. L'ordre textuel des variants ne départage jamais un conflit.

Exemple d'ambiguïté à refuser pour un target Linux x86_64 GNU :

variant A : platform=linux, architecture=x86_64
variant B : platform=linux, abi=gnu

Aucun des deux n'est strictement plus spécifique que l'autre.

Le noyau V1 des propriétés physiques peut comprendre :

library
linkage = auto | static | shared
deployment = auto | external | bundled
search-paths
include-paths

Le modèle réserve sans obligation d'implémentation complète en V1 :

runtime-files
link-files/import-libraries
frameworks
system-packages
resources
plugins

Une dépendance native représente donc un package natif logique pouvant comporter plusieurs composants physiques ; elle n'est jamais réduite au modèle « une dépendance = un unique fichier .so/.dll ».

37.10 Requirements SemVer — V1 REQUIS — FIGÉ

Les versions suivent strictement SemVer 2.0.0.

Les requirements V1 doivent au minimum pouvoir exprimer :

=1.4.7
^4.5
~1.4.2
3.1.*
>=1.0
>=1.2,<2.0

Une version exacte canonique comporte toujours MAJOR.MINOR.PATCH.

Une forme abrégée telle que 2.1 ne peut être acceptée que comme requirement/range dont la signification est définie sans ambiguïté ; elle n'est jamais une version exacte SemVer incomplète.

37.11 Imports de dépendances — V1 REQUIS — FIGÉ EN PRINCIPE

Toute utilisation d'un symbole provenant d'une dépendance externe au package courant passe par un import explicite :

import type namespace.Type
    from "vendor/package@requirement"
    as LocalType;

Même principe pour func, const et var.

as est facultatif tant que le nom local est unique ; il devient obligatoire en cas de collision locale.

Le from doit référencer un selector effectivement déclaré dans le graphe effectif du fichier. Il ne déclenche aucune résolution indépendante.

La qualification complète sans import reste limitée aux symboles du package courant.