Ges­tion de dépen­dances Git pour IBM i : un ges­tion­naire de packages ins­pi­ré de npm

Ges­tion de dépen­dances Git pour IBM i : un ges­tion­naire de packages ins­pi­ré de npm

ven 23 janvier 2026 0 Par Ibmiiste

Le pro­blème

Déve­lop­per sur IBM i (AS/400) en 2026 pré­sente des défis uniques. Contrai­re­ment aux éco­sys­tèmes modernes dotés de ges­tion­naires de packages (npm pour Node.js, pip pour Python, com­po­ser pour PHP), l’é­co­sys­tème IBM i manque d’ou­tils stan­dar­di­sés pour gérer les dépen­dances externes. Lorsque vous sou­hai­tez uti­li­ser une biblio­thèque RPGLE open-source comme log­fo­ri, vous devez :

  1. Clo­ner manuel­le­ment le dépôt Git
  2. Copier les fichiers dans votre projet
  3. Mettre à jour manuel­le­ment vos che­mins d’in­clu­sion (includePath)
  4. Gérer manuel­le­ment les mises à jour
  5. Gérer les dépen­dances tran­si­tives à la main

C’est exac­te­ment le pro­blème que résol­vaient npm, pip et autres avant leur création.

La solu­tion : ibmi-dependencies

ibmi-depen­den­cies est un ges­tion­naire de dépen­dances Git pour pro­jets IBM i qui s’in­tègre par­fai­te­ment avec TOBI (The Open Build Interface).

Fonc­tion­na­li­tés clés

1. Fichier de confi­gu­ra­tion décla­ra­tif (dependencies.json)

Ins­pi­ré de package.json et requirements.txt, le fichier dependencies.json per­met de décla­rer vos dépen­dances de manière standardisée :

{
  "$schema": "./schema/dependencies.schema.json",
  "name": "mon-projet-rpg",
  "version": "1.0.0",
  "dependencies": {
    "logfori": {
      "repository": "https://github.com/IBMiservices/logfori.git",
      "version": "^1.0.0",
      "ref": "main"
    },
    "autre-lib": {
      "repository": "https://github.com/user/lib.git",
      "version": "~2.1.0",
      "exclude": ["tests", "docs"]
    }
  },
  "config": {
    "targetDir": "dep",
    "cleanGit": true,
    "recursiveDependencies": true
  }
}

2. Sup­port de ver­sions séman­tiques (sem­ver)

Le sys­tème sup­porte les contraintes de ver­sions fami­lières aux déve­lop­peurs modernes :

  • ^1.0.0 : com­pa­tible avec 1.x.x (mises à jour mineures)
  • ~2.1.0 : com­pa­tible avec 2.1.x (patches uniquement)
  • >=1.0.0 : ver­sion minimale
  • latest : der­nière ver­sion disponible

3. Fichier de ver­rouillage (lock file)

Un dependencies-lock.json est géné­ré auto­ma­ti­que­ment, enre­gis­trant les com­mits SHA exacts pour garan­tir la repro­duc­ti­bi­li­té des builds :

{
  "packages": {
    "logfori": {
      "repository": "https://github.com/IBMiservices/logfori.git",
      "commit": "a3f5b2c1d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3",
      "version": "1.2.5",
      "installedAt": "2026-01-15T10:30:00Z"
    }
  }
}

À quoi sert le fichier de verrouillage ?

Le lock­file résout plu­sieurs pro­blèmes critiques :

  1. Repro­duc­ti­bi­li­té des builds : Même si dependencies.json spé­ci­fie "version": "^1.0.0", le lock­file enre­gistre la ver­sion exacte ins­tal­lée (ex : 1.2.5). Tous les déve­lop­peurs et le ser­veur CI/CD obtiennent exac­te­ment les mêmes dépendances.
  2. Pro­tec­tion contre les mises à jour non dési­rées : Sans lock­file, ^1.0.0 pour­rait ins­tal­ler 1.3.0 aujourd’­hui et 1.4.0 demain. Le lock­file « gèle » la ver­sion jus­qu’à ce que vous déci­diez expli­ci­te­ment de mettre à jour.
  3. Tra­ça­bi­li­té : Vous savez exac­te­ment quel com­mit SHA a été uti­li­sé pour chaque dépen­dance, faci­li­tant le debug­ging et les audits de sécurité.
  4. Cohé­rence d’é­quipe : Évite le clas­sique « ça marche sur ma machine » cau­sé par des ver­sions dif­fé­rentes entre développeurs.

Le lock­file doit être ver­sion­né dans Git avec dependencies.json pour garan­tir que toute l’é­quipe tra­vaille avec les mêmes versions.

4. Détec­tion de dépen­dances circulaires

Le sys­tème détecte auto­ma­ti­que­ment les dépen­dances cir­cu­laires avant l’ins­tal­la­tion, évi­tant les erreurs au moment du build :

❌ ERREUR: Dépendance circulaire détectée:
   pkg-a → pkg-b → pkg-c → pkg-a

5. Ges­tion des dépen­dances transitives

Avec recursiveDependencies: true, le sys­tème ins­talle auto­ma­ti­que­ment les dépen­dances de vos dépen­dances, comme npm le fait :

mon-projet
├── logfori (dépendance directe)
│   └── message-handler (dépendance transitive)
└── autre-lib (dépendance directe)

6. Vali­da­tion par sché­ma JSON

Un sché­ma JSON com­plet (dependencies.schema.json) valide votre confi­gu­ra­tion et four­nit l’au­to­com­plé­tion dans VS Code :

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["name", "version"],
  "properties": {
    "name": {
      "type": "string",
      "pattern": "^[a-z0-9-_]+$",
      "description": "Nom du projet"
    }
  }
}

7. Inté­gra­tion auto­ma­tique avec iproj.json

Lors de l’ins­tal­la­tion, le sys­tème met à jour auto­ma­ti­que­ment votre fichier iproj.json (com­pa­tible TOBI) pour inclure les che­mins des dépendances :

{
  "description": "Mon projet IBM i",
  "version": "1.0.0",
  "objlib": "&BUILDLIB",
  "includePath": [
    "ref",
    "dep/logfori/ref",
    "dep/autre-lib/ref"
  ],
  "buildCommand": "gmake all"
}

Archi­tec­ture technique

Le pro­jet est entiè­re­ment écrit en Python 3 (3.6+) sans dépen­dances externes obligatoires :

.vscode-deps/
├── install_deps_v2.py     # Script d'installation principal
├── lockfile.py            # Gestion du fichier de verrouillage
└── tests.py               # Suite de tests unitaires

Points tech­niques intéressants

1. Ges­tion des réfé­rences Git multiples

Le sys­tème sup­porte plu­sieurs types de réfé­rences Git :

  • Branches ("ref": "main")
  • Tags ("ref": "v1.0.0")
  • Com­mits SHA ("ref": "a3f5b2c")

2. Algo­rithme de détec­tion de cycles

Uti­lise un par­cours en pro­fon­deur (DFS) avec tra­cking des ancêtres pour détec­ter les cycles :

def check_circular_dependencies(pkg_name, dependencies, visited=None, ancestors=None):
    if visited is None:
        visited = set()
    if ancestors is None:
        ancestors = set()
    
    if pkg_name in ancestors:
        cycle = list(ancestors) + [pkg_name]
        raise CircularDependencyError(f"Cycle: {' → '.join(cycle)}")
    
    if pkg_name in visited:
        return
    
    visited.add(pkg_name)
    ancestors.add(pkg_name)
    
    # Parcours récursif des dépendances
    for dep_name in pkg_dependencies.keys():
        check_circular_dependencies(dep_name, dependencies, visited, ancestors)
    
    ancestors.remove(pkg_name)

3. Mat­ching de ver­sions sémantiques

Implé­men­ta­tion d’un par­ser sem­ver simple mais robuste sup­por­tant les contraintes complexes :

def matches_constraint(version, constraint):
    if constraint == "latest" or constraint == "*":
        return True
    
    if constraint.startswith("^"):
        # Compatible avec version majeure
        return major_match and version >= base_version
    
    if constraint.startswith("~"):
        # Compatible avec version mineure
        return major_match and minor_match and version >= base_version

4. Tests complets

Suite de tests uni­taires couvrant :

  • Vali­da­tion du sché­ma JSON
  • Créa­tion et mise à jour du lockfile
  • Détec­tion de dépen­dances circulaires
  • Mat­ching de contraintes de versions
python .vscode-deps/tests.py                    # Tous les tests
python -m unittest .vscode-deps.tests.TestLockfile -v  # Tests spécifiques
pytest .vscode-deps/tests.py --cov=.vscode-deps       # Avec couverture

Work­flow complet

Voi­ci un work­flow typique d’utilisation :

# 1. Cloner les outils dans votre projet
git clone https://github.com/IBMiservices/ibmi-dependencies.git .temp
cp -r .temp/.vscode-deps .
cp .temp/dependencies.json .
cp -r .temp/schema .
rm -rf .temp

# 2. Installer jsonschema (optionnel mais recommandé)
pip install jsonschema

# 3. Configurer vos dépendances dans dependencies.json
# (édition manuelle ou via CLI)

# 4. Installer les dépendances
python .vscode-deps/install_deps_v2.py

# 5. Build avec TOBI (sur IBM i)
# Le build est géré par TOBI via iproj.json et Rules.mk

# 6. Versionner dependencies.json et dependencies-lock.json
git add dependencies.json dependencies-lock.json
git commit -m "Add dependencies"

Ges­tion des mises à jour

Mettre à jour une dépen­dance est simple :

# Modifier dependencies.json et réinstaller
# Changer "version": "^1.0.0" → "version": "^2.0.0"
python .vscode-deps/install_deps_v2.py

Le lock­file sera auto­ma­ti­que­ment mis à jour avec le nou­veau com­mit SHA.

Cas d’u­sage réels

1. Par­tage de biblio­thèques utilitaires

Votre équipe déve­loppe des uti­li­taires RPGLE com­muns (log­ging, ges­tion d’er­reurs, helpers) :

{
  "dependencies": {
    "team-utils": {
      "repository": "https://git.entreprise.com/rpg/utils.git",
      "version": "^2.0.0"
    }
  }
}

Tous les pro­jets peuvent main­te­nant uti­li­ser ces uti­li­taires de manière standardisée.

2. Inté­gra­tion conti­nue (CI/CD)

Sur votre ser­veur CI/CD, le build est repro­duc­tible grâce au lockfile :

# Dans votre pipeline GitLab CI / Jenkins / GitHub Actions
- pip install jsonschema
- python .vscode-deps/install_deps_v2.py
- makei build

3. Onboar­ding de nou­veaux développeurs

Un nou­veau déve­lop­peur clone le pro­jet et obtient immé­dia­te­ment toutes les dépendances :

git clone https://github.com/entreprise/projet-rpg.git
cd projet-rpg
python .vscode-deps/install_deps_v2.py
# Prêt à développer !

Com­pa­rai­son avec d’autres écosystèmes

Fonc­tion­na­li­ténpmpipcom­po­seribmi-depen­den­cies
Fichier de config déclaratif✅ package.json✅ requirements.txt✅ composer.json✅ dependencies.json
Lock file✅ package-lock.json✅ Pipfile.lock✅ composer.lock✅ dependencies-lock.json
Contraintes de versions✅ Sem­ver✅ Sem­ver✅ Sem­ver✅ Sem­ver
Dépen­dances transitives
Regis­try central✅ npmjs.com✅ PyPI✅ Packa­gist⚠️ Git uniquement
Vali­da­tion par schéma

Limi­ta­tions et évo­lu­tions futures

Limi­ta­tions actuelles

  1. Pas de regis­try cen­tral : Néces­site des URLs Git complètes
  2. Per­for­mance : Le clo­nage Git peut être lent pour de gros dépôts
  3. Réso­lu­tion de conflits : Les conflits de ver­sions entre dépen­dances tran­si­tives ne sont pas gérés automatiquement

Road­map

  • Sup­port d’une regis­try cen­tra­li­sée pour IBM i

Ins­tal­la­tion et utilisation

Le pro­jet est open-source sous licence Apache 2.0 :

🔗 GitHub : https://github.com/IBMiservices/ibmi-dependencies

Quick start

# Dans votre projet IBM i
git clone https://github.com/IBMiservices/ibmi-dependencies.git .temp
cp -r .temp/.vscode-deps .
cp .temp/dependencies.json .
cp -r .temp/schema .
rm -rf .temp

pip install jsonschema

# Configurer dependencies.json puis :
python .vscode-deps/install_deps_v2.py

Docu­men­ta­tion complète

Conclu­sion

ibmi-depen­den­cies apporte à l’é­co­sys­tème IBM i les pra­tiques modernes de ges­tion de dépen­dances dont béné­fi­cient déjà les déve­lop­peurs JavaS­cript, Python, PHP et autres. En combinant :

  • ✅ Décla­ra­tion stan­dar­di­sée des dépendances
  • ✅ Ver­sio­ning sémantique
  • ✅ Fichier de ver­rouillage pour la reproductibilité
  • ✅ Inté­gra­tion avec TOBI (The Open Build Interface)
  • ✅ Tests com­plets et vali­da­tion par schéma

… il faci­lite consi­dé­ra­ble­ment le déve­lop­pe­ment col­la­bo­ra­tif et la réuti­li­sa­tion de code sur IBM i.

Le pro­jet est en déve­lop­pe­ment actif et les contri­bu­tions sont les bien­ve­nues. Si vous déve­lop­pez sur IBM i et que vous cher­chez à moder­ni­ser votre work­flow, n’hé­si­tez pas à l’es­sayer et à par­ta­ger vos retours !