devzone 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,9 @@
3
3
  # clusters Kubernetes, puis récapitulatif de ce qui reste à faire (devzone).
4
4
  # Séquentiel : le récapitulatif voit l'identité tout juste posée ; l'échec
5
5
  # d'une étape n'empêche pas les suivantes.
6
+ # Jamais de question (gh, kubectl et ses plugins d'authentification) : sortie
7
+ # invisible derrière make, une attente bloquerait (voir post-create.sh)
8
+ exec </dev/null
6
9
  ICI="$(dirname "$0")"
7
10
  bash "$ICI/git-identite.sh" || echo "démarrage : identité git non traitée (bash $ICI/git-identite.sh)"
8
11
  bash "$ICI/kube-config.sh" || echo "démarrage : clusters non traités (bash $ICI/kube-config.sh)"
@@ -3,6 +3,12 @@
3
3
  # - volumes montés au démarrage seulement
4
4
  # - npm fourni par la feature node, ajoutée après le Dockerfile
5
5
  set -euo pipefail
6
+ # Jamais de question : le CLI devcontainer lance cette étape sous terminal,
7
+ # sortie envoyée dans .devzone.log par make, donc invisible ; une question
8
+ # (repowarden install propose « repowarden bots » dans un dépôt GitHub dont
9
+ # gh est administrateur) attendrait indéfiniment. Entrée vide : chaque outil
10
+ # passe en mode non interactif (bots : « plus tard, repowarden bots »)
11
+ exec </dev/null
6
12
 
7
13
  # Volumes nommés créés en root → rendre au user vscode
8
14
  # (et ~/.config, créé par Docker pour monter ~/.config/opencode)
package/.gitattributes CHANGED
@@ -1,5 +1,10 @@
1
- # Scripts lancés dans le conteneur Linux : fins de ligne LF même sur un
2
- # checkout Windows (bash échoue sur les CRLF)
3
- *.sh text eol=lf
4
- Dockerfile text eol=lf
5
- Makefile text eol=lf
1
+ # Scripts lancés par un interpréteur (bash, bats, Python) : fins de ligne LF
2
+ # même sur un checkout Windows (l'interpréteur échoue sur les CRLF)
3
+ *.sh text eol=lf
4
+ *.bats text eol=lf
5
+ *.py text eol=lf
6
+ Dockerfile text eol=lf
7
+ Makefile text eol=lf
8
+ # Scripts bash sans extension (lancés directement)
9
+ bin/devzone text eol=lf
10
+ .devcontainer/devzone text eol=lf
package/Makefile CHANGED
@@ -2,10 +2,9 @@
2
2
  DC := npx -y @devcontainers/cli
3
3
  WS := --workspace-folder $(CURDIR)
4
4
  FILTRE := --filter "label=devcontainer.local_folder=$(CURDIR)"
5
- LOG := $(CURDIR)/.devzone.log
6
5
 
7
6
  .DEFAULT_GOAL := help
8
- .PHONY: help hors-conteneur up shell stop down rebuild status test-fonctionnel desinstaller
7
+ .PHONY: help hors-conteneur up shell stop down rebuild status test-fonctionnel test-cli desinstaller
9
8
 
10
9
  # Ces commandes pilotent le conteneur depuis la machine : lancées dans le
11
10
  # conteneur, elles créeraient un devzone dans son Docker interne, sans rien
@@ -19,9 +18,10 @@ hors-conteneur:
19
18
  help: ## Liste les commandes
20
19
  @grep -E '^[a-z-]+:.*## ' $(MAKEFILE_LIST) | awk -F':.*## ' '{printf " make %-16s %s\n", $$1, $$2}'
21
20
 
21
+ # up et rebuild : étapes affichées, journal complet dans .devzone.log, question
22
+ # posée dans le conteneur signalée au lieu d'attendre (lancer.sh)
22
23
  up: hors-conteneur ## Lance le conteneur (le crée si absent)
23
- @$(DC) up $(WS) >$(LOG) 2>&1 && echo "devzone lancé" \
24
- || { tail -15 $(LOG); echo "échec — log complet : .devzone.log"; exit 1; }
24
+ @bash lancer.sh up "$(CURDIR)"
25
25
 
26
26
  shell: hors-conteneur up ## Ouvre un shell dans le conteneur
27
27
  @$(DC) exec $(WS) bash
@@ -35,8 +35,7 @@ down: hors-conteneur ## Supprime le conteneur (volumes, image et Docker interne
35
35
  docker rm -f $$ids >/dev/null && echo "devzone supprimé (désinstallation complète : make desinstaller)"; fi
36
36
 
37
37
  rebuild: hors-conteneur ## Reconstruit de zéro (après modif de .devcontainer/)
38
- @$(DC) up $(WS) --remove-existing-container >$(LOG) 2>&1 && echo "devzone reconstruit" \
39
- || { tail -15 $(LOG); echo "échec — log complet : .devzone.log"; exit 1; }
38
+ @bash lancer.sh rebuild "$(CURDIR)"
40
39
 
41
40
  status: hors-conteneur ## État du conteneur
42
41
  @docker ps -a $(FILTRE) --format '{{.Status}}' | grep . || echo "aucun conteneur"
@@ -44,5 +43,8 @@ status: hors-conteneur ## État du conteneur
44
43
  test-fonctionnel: hors-conteneur ## Tests fonctionnels : devzone isolé, construit puis supprimé (5 à 10 min)
45
44
  @bash test/fonctionnel.sh
46
45
 
46
+ test-cli: hors-conteneur ## Tests de la CLI dans un vrai terminal : devzone isolé, puis supprimé (10 à 15 min)
47
+ @bash test/cli-terminal.sh
48
+
47
49
  desinstaller: hors-conteneur ## Supprime tout ce que devzone a créé, après confirmation (GARDER=connexions : garde les connexions)
48
50
  @GARDER="$(GARDER)" bash desinstaller.sh
package/README.md CHANGED
@@ -15,7 +15,7 @@ Environnement de développement complet dans un conteneur (devcontainer) : les m
15
15
 
16
16
  ## Démarrage rapide
17
17
 
18
- 1. **Prérequis** : Docker (Docker Desktop, ou Docker Engine sous Linux), puis **soit** VS Code + extension *Dev Containers*, **soit** Node (pour `npx`) et `make`. Facultatif, pour Kubernetes : activer le cluster de Docker Desktop (*Settings → Kubernetes → Enable Kubernetes*). Sous Windows : cloner avec Git for Windows (les scripts restent en fins de ligne LF grâce à `.gitattributes`).
18
+ 1. **Prérequis** : Docker (Docker Desktop, ou Docker Engine sous Linux), puis **soit** VS Code + extension *Dev Containers*, **soit** Node (pour `npx`) et `make`. Facultatif, pour Kubernetes : activer le cluster de Docker Desktop (*Settings → Kubernetes → Enable Kubernetes*). Sous Windows : cloner avec Git for Windows (les scripts restent en fins de ligne LF grâce à `.gitattributes`, et la commande npm trouve le `bash` qu'elle exige).
19
19
  2. **Obtenir devzone**, au choix :
20
20
  - `npx devzone mon-devzone` : crée le dossier `mon-devzone/` et lance le conteneur (paquet npm `devzone`, une fois publié) ;
21
21
  - ou `git clone https://github.com/SimBienvenueHoulBoumi/devzone.git`.
@@ -70,7 +70,7 @@ Le choix est **propre à chaque utilisateur** et gardé dans le volume `devzone-
70
70
  | État | — | `make status` | — |
71
71
  | **Désinstaller** (tout ce que devzone a créé, après confirmation) | — | `make desinstaller` | `bash desinstaller.sh` |
72
72
 
73
- `make` seul affiche la liste. Les journaux de `up` et `rebuild` vont dans `.devzone.log` ; seule la fin s'affiche en cas d'échec.
73
+ `make` seul affiche la liste. `up` et `rebuild` affichent leurs étapes (construction de l'image, installation, démarrage, puis l'état de devzone) et un signe de vie au moins toutes les 30 s ; le journal complet va dans `.devzone.log` (sa fin s'affiche en cas d'échec). Aucune étape automatique ne pose de question : si l'une le faisait, `make` l'afficherait et s'arrêterait au lieu d'attendre en silence (voir [Dépannage](#dépannage)).
74
74
 
75
75
  > Ne pas lancer `make up` pendant que VS Code ouvre ou reconstruit le conteneur : deux lancements simultanés créent des conteneurs en double.
76
76
 
@@ -198,8 +198,12 @@ Empreinte d'une archive : `curl -fsSL <url> | shasum -a 256`.
198
198
  |---|---|---|---|
199
199
  | Commande `devzone` du conteneur et commande npm (unitaires) | `bats test/` | dans le conteneur | quelques secondes |
200
200
  | Fonctionnels : un devzone construit et utilisé comme par un utilisateur (outils, modules, Kubernetes avec kind, hooks repowarden, redémarrage, rebuild) | `make test-fonctionnel` | sur ta machine (Docker, Node) | 5 à 10 min |
201
+ | CLI dans un vrai terminal : chaque commande tapée comme par un humain (pseudo-terminal), avec un délai maximal ; une commande qui attend une entrée échoue. Cibles `make` (`help`, `up`, `shell`, `status`, `stop`, `down`, `rebuild`, `desinstaller`), commande npm (`devzone <dossier>`, `desinstaller`, `--version`, `--help`), commande `devzone` du conteneur, scripts de démarrage | `make test-cli` | sur ta machine (Docker, Node, Python 3) | 10 à 15 min |
202
+ | Windows (local et CI) | `bash test/windows.sh` | macOS/Linux (local) ou Windows Git Bash (CI) | quelques secondes |
201
203
 
202
- Les tests fonctionnels travaillent sur une copie du dépôt, avec leurs propres volumes (`devzone-test-…`), puis suppriment tout (conteneur, volumes, image), même en cas d'échec : ton devzone, tes connexions et le cluster de ta machine ne sont jamais touchés (seul un cluster kind de test est utilisé). En CI, le workflow `fonctionnel` les lance sur chaque PR qui modifie `.devcontainer/`, `test/` ou le `Makefile`, et à la main (*Actions → fonctionnel → Run workflow*).
204
+ **Windows (CI) : ce qui est vérifié / ce qui n'est pas (conteneur, VS Code).** Le job `windows` vérifie sous `windows-latest` (checkout avec `core.autocrlf=true`, comme un poste Windows) : aucun CRLF dans les scripts (tout fichier suivi commençant par `#!`, plus le `Makefile`) ; empaquetage npm (`npm pack`) et installation de l'archive — dans un préfixe npm isolé sous `$TMP` (le global de la machine n'est jamais touché) ; `devzone --version`, `devzone --help`, option inconnue (avec sortie en erreur) ; `devzone <dossier>` avec `DEVZONE_SANS_DEMARRER=1` (création des fichiers attendus, dossier non vide refusé sans écrasement) ; `devzone desinstaller` hors d'un dossier devzone refusé. Le même parcours passe ensuite par `cmd`, c'est-à-dire le raccourci `.cmd` de npm, avec cette fois une installation globale réelle (le cas d'un utilisateur Windows). Ce qui n'est **pas** vérifié sous Windows CI : `make up` et le conteneur Linux (impossibles sur les runners Windows de GitHub), ainsi que VS Code et Docker Desktop (vérifiés à la main).
205
+
206
+ Les tests fonctionnels et ceux de la CLI travaillent sur une copie du dépôt, avec leurs propres volumes (`devzone-test-…`), puis suppriment tout (conteneur, volumes, image), même en cas d'échec : ton devzone, tes connexions et le cluster de ta machine ne sont jamais touchés (seul un cluster kind de test est utilisé). En CI, le workflow `fonctionnel` les lance (trois jobs : fonctionnel, cli et windows) sur chaque PR qui modifie `.devcontainer/`, `test/`, `bin/`, le `Makefile`, `lancer.sh`, `desinstaller.sh`, `.gitattributes` ou `package.json`, et à la main (*Actions → fonctionnel → Run workflow*).
203
207
 
204
208
  ## Versions et livraison
205
209
 
@@ -225,6 +229,7 @@ Prérequis de la livraison automatique : la GitHub App du dépôt (`repowarden a
225
229
 
226
230
  | Symptôme | Cause | Solution |
227
231
  |---|---|---|
232
+ | `make up` ou `make rebuild` semble figé | une étape longue (première construction de l'image : plusieurs minutes), ou une question posée dans le conteneur | `make` affiche un signe de vie avec la dernière ligne du journal au moins toutes les 30 s : suivre le détail avec `tail -f .devzone.log`. Une question (ligne finissant par `[o/N]`, `?`…) est signalée et le lancement arrêté : la [signaler](https://github.com/SimBienvenueHoulBoumi/devzone/issues), puis `make rebuild`. Version antérieure de devzone, figée sur « Configurer les bots … ? [o/N] » (invisible) : `Ctrl+C`, mettre devzone à jour puis `make rebuild` ; les bots se configurent à la main dans le conteneur : `repowarden bots` |
228
233
  | `git push` refusé : « refusing to allow an OAuth App to create or update workflow … without `workflow` scope » | jeton `gh` sans la permission `workflow` | `gh auth refresh -h github.com -s workflow` |
229
234
  | PR bloquée, run `action_required`, bandeau « Approve workflows to run » | PR ouverte ou poussée par le bot `github-actions` : pour les événements `pull_request` `opened`, `synchronize` et `reopened`, GitHub attend l'accord d'une personne ayant l'écriture ([doc GitHub](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow)) | vérifier les changements (surtout `.github/workflows/`), puis *Approve workflows to run* ; pour ne plus avoir à le faire : `repowarden app init` dans le projet |
230
235
  | PR de livraison bloquée : « aucune préversion vX.Y.Z-next.N » | la préversion n'est pas encore publiée (sans `preversion-on-push`, elle part le soir) | attendre celle du soir, *Actions → release → Run workflow* sur `develop`, `preversion-on-push: true`, ou ne plus l'exiger : `preversion-obligatoire: false` |
@@ -249,26 +254,29 @@ devzone/
249
254
  │ ├── devcontainer.json # features (langages, Docker, Kubernetes, gh), volumes, extensions VS Code
250
255
  │ ├── devcontainer-lock.json # versions figées des features
251
256
  │ ├── devzone # commande devzone : modules (ia, kubernetes), versions des assistants IA
252
- │ ├── post-create.sh # premier démarrage : droits des volumes, git, repowarden, modules actifs
257
+ │ ├── post-create.sh # premier démarrage : droits des volumes, git, repowarden, modules actifs (sans question)
253
258
  │ ├── demarrage.sh # chaque démarrage : identité git, clusters, puis récapitulatif (devzone)
254
259
  │ ├── kube-config.sh # contextes kind ; module kubernetes : cluster de l'hôte, metrics-server
255
260
  │ ├── metrics-server.sh # metrics-server sur les clusters locaux (CPU et RAM dans k9s)
256
261
  │ └── git-identite.sh # identité git déduite du compte gh si elle manque
257
262
  ├── .github/workflows/
258
- │ ├── fonctionnel.yml # tests fonctionnels (PR touchant .devcontainer/, test/ ou le Makefile)
263
+ │ ├── fonctionnel.yml # tests fonctionnels et de la CLI sous terminal (PR touchant le conteneur, les tests ou la CLI)
259
264
  │ ├── repowarden.yml # vérifications repowarden de chaque PR (PR mal visée reciblée vers develop)
260
265
  │ ├── tickets.yml # suivi des tickets : branche, PR brouillon, statuts jusqu'à la production
261
266
  │ ├── release.yml # préversions sur develop, livraison develop → main
262
267
  │ └── nettoyage.yml # branches mergées supprimées (main et develop conservées)
263
268
  ├── .repowarden.conf # réglages repowarden : flux develop → main
264
269
  ├── Makefile # pilotage sans VS Code
270
+ ├── lancer.sh # make up / rebuild : étapes affichées, question du conteneur signalée
265
271
  ├── desinstaller.sh # make desinstaller : retire tout ce que devzone a créé
266
272
  ├── bin/devzone # commande npm : npx devzone <dossier>, devzone desinstaller
267
273
  ├── package.json, LICENSE # paquet npm devzone (licence GPL-3.0-only)
268
274
  ├── test/
269
275
  │ ├── devzone.bats # tests de la commande devzone (bats test/)
270
- │ ├── cli.bats # tests de la commande npm et du contenu du paquet
271
- │ └── fonctionnel.sh # tests fonctionnels (make test-fonctionnel)
276
+ │ ├── cli.bats # tests de la commande npm, du contenu du paquet et de lancer.sh
277
+ │ ├── fonctionnel.sh # tests fonctionnels (make test-fonctionnel)
278
+ │ ├── cli-terminal.sh # tests de la CLI dans un vrai terminal (make test-cli)
279
+ │ └── terminal.py # lance une commande sous pseudo-terminal, avec délai maximal
272
280
  └── workspace/ # tes projets (ignorés par git, chacun son dépôt)
273
281
  ```
274
282
 
package/bin/devzone CHANGED
@@ -10,9 +10,14 @@ set -euo pipefail
10
10
 
11
11
  PAQUET="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || echo "${BASH_SOURCE[0]}")")/.." && pwd)"
12
12
  # Fichiers d'un devzone (même liste que « files » de package.json, sans bin/)
13
- FICHIERS=(.devcontainer Makefile .gitattributes desinstaller.sh README.md LICENSE)
13
+ FICHIERS=(.devcontainer Makefile .gitattributes lancer.sh desinstaller.sh README.md LICENSE)
14
14
 
15
- version() { node -p "require('$PAQUET/package.json').version" 2>/dev/null || echo inconnue; }
15
+ version() {
16
+ # Chemin passé en argument à node, jamais écrit dans le code JavaScript de -p :
17
+ # sous Git Bash $PAQUET vaut /c/… et seul un argument séparé est reconverti
18
+ # pour un programme Windows (cygpath inutile)
19
+ node -p 'require(process.argv[1]).version' "$PAQUET/package.json" 2>/dev/null || echo inconnue
20
+ }
16
21
 
17
22
  aide() {
18
23
  cat <<EOF
@@ -44,7 +49,7 @@ workspace/*
44
49
  .devzone.log
45
50
  .devzone.etat
46
51
  EOF
47
- chmod +x "$cible/desinstaller.sh"
52
+ chmod +x "$cible/desinstaller.sh" "$cible/lancer.sh"
48
53
  cible="$(cd "$cible" && pwd)"
49
54
  echo "✔ devzone $(version) créé dans $cible"
50
55
  if [ -n "${DEVZONE_SANS_DEMARRER:-}" ]; then
@@ -55,11 +60,7 @@ EOF
55
60
  if command -v make >/dev/null 2>&1; then
56
61
  make -C "$cible" up
57
62
  else
58
- npx -y @devcontainers/cli up --workspace-folder "$cible" >"$cible/.devzone.log" 2>&1 || {
59
- tail -15 "$cible/.devzone.log"
60
- echo "✖ échec ; journal : $cible/.devzone.log" >&2
61
- exit 1
62
- }
63
+ bash "$cible/lancer.sh" up "$cible"
63
64
  fi
64
65
  echo "Ensuite : cd $cible && make shell (ou ouvre le dossier dans VS Code : Reopen in Container)."
65
66
  }
package/lancer.sh ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ # Lance le conteneur sur l'hôte, sans jamais rester muet :
3
+ # bash lancer.sh up [dossier] (make up)
4
+ # bash lancer.sh rebuild [dossier] (make rebuild : reconstruit de zéro)
5
+ # Sortie complète du CLI devcontainer dans <dossier>/.devzone.log ; dans le
6
+ # terminal : les étapes clés, un signe de vie au plus toutes les
7
+ # DEVZONE_SIGNE_DE_VIE secondes (30), et une question posée dans le conteneur
8
+ # (dernière ligne du journal restée sans réponse DEVZONE_ATTENTE_QUESTION
9
+ # secondes, 20) est affichée et le lancement arrêté : personne ne peut y
10
+ # répondre (le CLI tourne sans entrée), attendre serait bloquer indéfiniment.
11
+ # Portable : bash 3.2 (macOS) et Linux.
12
+ set -uo pipefail
13
+
14
+ mode="${1:-}"
15
+ DOSSIER="${2:-$PWD}"
16
+ case "$mode" in
17
+ up) options=() fini="devzone lancé" ;;
18
+ rebuild) options=(--remove-existing-container) fini="devzone reconstruit" ;;
19
+ *)
20
+ echo "usage : bash lancer.sh up|rebuild [dossier]" >&2
21
+ exit 2
22
+ ;;
23
+ esac
24
+ LOG="$DOSSIER/.devzone.log"
25
+ VIE="${DEVZONE_SIGNE_DE_VIE:-30}"
26
+ QUESTION="${DEVZONE_ATTENTE_QUESTION:-20}"
27
+ ESC="$(printf '\033')"
28
+
29
+ # Ligne du journal lisible : sans codes de couleur ni retours chariot
30
+ propre() { sed "s/${ESC}\[[0-9;?]*[A-Za-z]//g" | tr -d '\r'; }
31
+ # Dernière ligne non vide du journal, raccourcie
32
+ derniere() { tail -c 2000 "$LOG" | propre | grep -v '^[[:space:]]*$' | tail -1 | cut -c1-110; }
33
+
34
+ # Question en attente : dernière ligne inachevée (sans retour à la ligne,
35
+ # comme une invite) qui finit par [o/N], [y/N], ? ou une demande de mot de passe
36
+ motif='(\[[^]]*/[^]]*\]|\?|[Pp]assword[^:]*:|[Mm]ot de passe[^:]*:)[[:space:]]*$'
37
+ question() {
38
+ local ligne
39
+ # Dernier octet : vide après $( ) si c'est un retour à la ligne
40
+ [ -n "$(tail -c 1 "$LOG")" ] || return 1
41
+ ligne="$(tail -c 600 "$LOG" | propre | tail -1)"
42
+ [[ "$ligne" =~ $motif ]] || return 1
43
+ printf '%s\n' "$ligne" | cut -c1-200
44
+ }
45
+
46
+ # Étapes clés, chacune affichée une fois ; état de devzone recopié tel quel
47
+ vus=" "
48
+ lues=0
49
+ etapes() {
50
+ local total ligne
51
+ total="$(wc -l <"$LOG" | tr -d ' ')"
52
+ [ "$total" -gt "$lues" ] || return 0
53
+ while IFS= read -r ligne; do
54
+ case "$ligne" in
55
+ *"Start: Run: docker buildx build"* | *"Start: Run: docker build"*) annoncer image "Construction de l'image (plusieurs minutes la première fois)" ;;
56
+ *"Start: Run: docker run"*) annoncer conteneur "Création du conteneur" ;;
57
+ *"Running the postCreateCommand"*) annoncer postcreate "Installation dans le conteneur (repowarden, modules)" ;;
58
+ *"Running the postStartCommand"*) annoncer poststart "Démarrage (identité git, clusters, état)" ;;
59
+ "devzone prêt"* | "devzone : "* | " ✔ "* | " ✖ "* | " ○ "* | " ⚠ "* | " "[!\ ]* | "git-identite : "* | "kube-config : "* | "metrics-server : "*)
60
+ echo " $ligne"
61
+ derniere_annonce="$(date +%s)"
62
+ ;;
63
+ esac
64
+ done < <(sed -n "$((lues + 1)),${total}p" "$LOG" | propre)
65
+ lues="$total"
66
+ }
67
+ annoncer() {
68
+ case "$vus" in *" $1 "*) return 0 ;; esac
69
+ vus="$vus$1 "
70
+ echo "▶ $2"
71
+ derniere_annonce="$(date +%s)"
72
+ }
73
+
74
+ arreter() {
75
+ [ -n "${pid:-}" ] || return 0
76
+ pkill -TERM -P "$pid" 2>/dev/null || true
77
+ kill -TERM "$pid" 2>/dev/null || true
78
+ wait "$pid" 2>/dev/null || true
79
+ pid=""
80
+ }
81
+ trap 'arreter; echo; echo "interrompu — journal : .devzone.log"; exit 130' INT TERM
82
+
83
+ : >"$LOG"
84
+ debut="$(date +%s)"
85
+ derniere_annonce="$debut"
86
+ echo "▶ Lancement de devzone (journal complet : .devzone.log)"
87
+ # Entrée vide : le CLI ne relaie rien ; une question posée dans le conteneur
88
+ # resterait sans réponse, d'où sa détection ci-dessous
89
+ npx -y @devcontainers/cli up --workspace-folder "$DOSSIER" ${options[@]+"${options[@]}"} </dev/null >"$LOG" 2>&1 &
90
+ pid=$!
91
+
92
+ taille=0
93
+ calme=0
94
+ while kill -0 "$pid" 2>/dev/null; do
95
+ sleep 1
96
+ t="$(wc -c <"$LOG" | tr -d ' ')"
97
+ if [ "$t" != "$taille" ]; then
98
+ taille="$t"
99
+ calme=0
100
+ etapes
101
+ else
102
+ calme=$((calme + 1))
103
+ fi
104
+ if [ "$calme" -ge "$QUESTION" ] && q="$(question)"; then
105
+ arreter
106
+ echo "✖ Une étape du conteneur pose une question et attend une réponse (journal immobile depuis $calme s) :" >&2
107
+ echo " $q" >&2
108
+ echo " Personne ne peut y répondre ici : lancement arrêté au lieu d'attendre indéfiniment." >&2
109
+ echo " Journal complet : .devzone.log ; signale-le : https://github.com/SimBienvenueHoulBoumi/devzone/issues" >&2
110
+ echo " Le conteneur est peut-être incomplet : make rebuild pour repartir de zéro." >&2
111
+ exit 1
112
+ fi
113
+ maintenant="$(date +%s)"
114
+ if [ $((maintenant - derniere_annonce)) -ge "$VIE" ]; then
115
+ ecoule=$((maintenant - debut))
116
+ info="en cours depuis $((ecoule / 60)) min $((ecoule % 60)) s"
117
+ [ "$calme" -lt "$VIE" ] || info="$info, aucune nouvelle ligne depuis $calme s"
118
+ echo " … $info : $(derniere)"
119
+ derniere_annonce="$maintenant"
120
+ fi
121
+ done
122
+ wait "$pid"
123
+ code=$?
124
+ pid=""
125
+ etapes
126
+ if [ "$code" -eq 0 ]; then
127
+ echo "$fini"
128
+ else
129
+ tail -15 "$LOG" | propre
130
+ echo "échec — log complet : .devzone.log"
131
+ exit 1
132
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devzone",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Zone de dev conteneurisée : Java, Node, Python, Docker, Kubernetes et outils repowarden, dans un devcontainer",
5
5
  "license": "GPL-3.0-only",
6
6
  "repository": {
@@ -24,6 +24,7 @@
24
24
  ".devcontainer/",
25
25
  "Makefile",
26
26
  ".gitattributes",
27
+ "lancer.sh",
27
28
  "desinstaller.sh",
28
29
  "README.md",
29
30
  "LICENSE"