repowarden 0.0.0-stage → 4.1.0
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.
- package/LICENSE +21 -0
- package/README.md +103 -2
- package/bin/code-mort +33 -0
- package/bin/commit +412 -0
- package/bin/npm-publication +151 -0
- package/bin/proteger +283 -0
- package/bin/repogarde +20 -0
- package/bin/repowarden +63 -0
- package/bin/statut +100 -0
- package/bin/ticket +129 -0
- package/bin/tickets +135 -0
- package/hooks/commit-msg +64 -0
- package/hooks/lang/actions.sh +9 -0
- package/hooks/lang/ansible.sh +18 -0
- package/hooks/lang/cpp.sh +22 -0
- package/hooks/lang/dart.sh +20 -0
- package/hooks/lang/deno.sh +15 -0
- package/hooks/lang/docker.sh +26 -0
- package/hooks/lang/dotnet.sh +15 -0
- package/hooks/lang/elixir.sh +13 -0
- package/hooks/lang/go.sh +22 -0
- package/hooks/lang/gradle.sh +28 -0
- package/hooks/lang/helm.sh +28 -0
- package/hooks/lang/kubernetes.sh +29 -0
- package/hooks/lang/maven.sh +27 -0
- package/hooks/lang/node.sh +75 -0
- package/hooks/lang/packer.sh +16 -0
- package/hooks/lang/php.sh +20 -0
- package/hooks/lang/python.sh +79 -0
- package/hooks/lang/ruby.sh +24 -0
- package/hooks/lang/rust.sh +17 -0
- package/hooks/lang/shell.sh +9 -0
- package/hooks/lang/swift.sh +20 -0
- package/hooks/lang/tasks.sh +16 -0
- package/hooks/lang/terraform.sh +29 -0
- package/hooks/lib/common.sh +393 -0
- package/hooks/lib/compat.sh +24 -0
- package/hooks/lib/deadcode.sh +153 -0
- package/hooks/lib/forge.sh +39 -0
- package/hooks/lib/i18n/en.sh +393 -0
- package/hooks/lib/i18n/fr.sh +393 -0
- package/hooks/lib/i18n.sh +81 -0
- package/hooks/lib/lang.sh +338 -0
- package/hooks/lib/safety.sh +108 -0
- package/hooks/lib/tickets.sh +184 -0
- package/hooks/lib/ui.sh +40 -0
- package/hooks/post-checkout +26 -0
- package/hooks/post-merge +47 -0
- package/hooks/pre-commit +58 -0
- package/hooks/pre-push +91 -0
- package/hooks/prepare-commit-msg +48 -0
- package/install.sh +245 -0
- package/package.json +31 -4
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# JavaScript / TypeScript (React, Next.js, Vue, Angular, Nest…) : prettier, <pm> test
|
|
3
|
+
# Extensions de code (analyse du code mort) : les autres (md, yml, json…) ne
|
|
4
|
+
# sont rattachées à node que pour le formatage
|
|
5
|
+
# shellcheck disable=SC2034 # lu par deadcode.sh (${PLUGIN}_CODE_EXT)
|
|
6
|
+
NODE_CODE_EXT='\.(js|jsx|ts|tsx|mjs|cjs|mts|cts|vue|svelte|astro)$'
|
|
7
|
+
register node "package.json" '\.(js|jsx|ts|tsx|mjs|cjs|mts|cts|vue|svelte|astro|json|jsonc|css|scss|less|html|md|mdx|ya?ml|graphql)$' standalone
|
|
8
|
+
|
|
9
|
+
# Gestionnaire de paquets d'après le lockfile (y compris à la racine d'un monorepo)
|
|
10
|
+
node_pm() {
|
|
11
|
+
if find_up pnpm-lock.yaml >/dev/null; then echo pnpm
|
|
12
|
+
elif find_up yarn.lock >/dev/null; then echo yarn
|
|
13
|
+
elif find_up bun.lockb >/dev/null || find_up bun.lock >/dev/null; then echo bun
|
|
14
|
+
else echo npm
|
|
15
|
+
fi
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
node_format() {
|
|
19
|
+
local prettier
|
|
20
|
+
prettier="$(find_up node_modules/.bin/prettier || command -v prettier || true)"
|
|
21
|
+
[ -n "$prettier" ] || { tool_missing "Node : prettier introuvable (npm i -D prettier), formatage ignoré."; return 0; }
|
|
22
|
+
step_t lang.node.1
|
|
23
|
+
"$prettier" --write --ignore-unknown --log-level warn "$@"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
node_test() {
|
|
27
|
+
has node || { warn "Node : node absent, tests ignorés."; return 0; }
|
|
28
|
+
# Ignore le script "test" par défaut généré par npm init
|
|
29
|
+
if ! node -e 'const t=(require("./package.json").scripts||{}).test; process.exit(t && !/no test specified/.test(t) ? 0 : 1)'; then
|
|
30
|
+
info_t lang.node.2
|
|
31
|
+
return 0
|
|
32
|
+
fi
|
|
33
|
+
local pm; pm="$(node_pm)"
|
|
34
|
+
has "$pm" || { warn "Node : $pm absent, tests ignorés."; return 0; }
|
|
35
|
+
step_t lang.node.3 "$pm"
|
|
36
|
+
case "$pm" in
|
|
37
|
+
bun) bun run test ;;
|
|
38
|
+
npm) npm test --silent ;;
|
|
39
|
+
*) "$pm" test ;;
|
|
40
|
+
esac
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Code mort : TypeScript (variables, paramètres, imports inutilisés, code
|
|
44
|
+
# inaccessible : prouvé) ; knip s'il est installé dans le projet (fichiers,
|
|
45
|
+
# exports, dépendances non référencés : candidats)
|
|
46
|
+
node_deadcode() {
|
|
47
|
+
local ran=""
|
|
48
|
+
if [ -f tsconfig.json ] && [ -x node_modules/.bin/tsc ]; then
|
|
49
|
+
ran=1
|
|
50
|
+
node_modules/.bin/tsc --noEmit -p . --noUnusedLocals --noUnusedParameters \
|
|
51
|
+
--allowUnreachableCode false --pretty false 2>/dev/null |
|
|
52
|
+
sed -nE 's/^(.+)\(([0-9]+),[0-9]+\): error (TS6133|TS6138|TS6192|TS6196|TS6198|TS7027): (.*)$/prouve\t\1\t\2\t\4/p'
|
|
53
|
+
fi
|
|
54
|
+
if [ -x node_modules/.bin/knip ] && has node; then
|
|
55
|
+
ran=1
|
|
56
|
+
_tr dc.knip_file
|
|
57
|
+
local m_file="$_T"
|
|
58
|
+
_tr dc.knip_export
|
|
59
|
+
local m_export="$_T"
|
|
60
|
+
_tr dc.knip_dep
|
|
61
|
+
local m_dep="$_T"
|
|
62
|
+
node_modules/.bin/knip --reporter json --no-progress 2>/dev/null |
|
|
63
|
+
M_FILE="$m_file" M_EXPORT="$m_export" M_DEP="$m_dep" node -e '
|
|
64
|
+
let r; try { r = JSON.parse(require("fs").readFileSync(0, "utf8")); } catch { process.exit(0); }
|
|
65
|
+
const out = (f, l, m) => console.log(["candidat", f, l, m].join("\t"));
|
|
66
|
+
for (const f of r.files || []) out(f, 0, process.env.M_FILE);
|
|
67
|
+
for (const i of r.issues || []) {
|
|
68
|
+
for (const k of ["exports", "types", "nsExports", "nsTypes"])
|
|
69
|
+
for (const e of i[k] || []) out(i.file, e.line || 0, process.env.M_EXPORT + " " + e.name);
|
|
70
|
+
for (const k of ["dependencies", "devDependencies"])
|
|
71
|
+
for (const d of i[k] || []) out(i.file, 0, process.env.M_DEP + " " + d.name);
|
|
72
|
+
}'
|
|
73
|
+
fi
|
|
74
|
+
[ -n "$ran" ] || deadcode_tool_missing "JavaScript / TypeScript" "typescript / knip"
|
|
75
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Packer : packer fmt ; validation syntaxique au push / en CI
|
|
3
|
+
register packer "*.pkr.hcl" '\.(pkr|pkrvars)\.hcl$' standalone
|
|
4
|
+
|
|
5
|
+
packer_format() {
|
|
6
|
+
has packer || { tool_missing "Packer : packer absent, formatage ignoré."; return 0; }
|
|
7
|
+
step_t lang.packer.1
|
|
8
|
+
local f
|
|
9
|
+
for f in "$@"; do packer fmt "$f" >/dev/null || return 1; done
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
packer_test() {
|
|
13
|
+
has packer || { warn "Packer : packer absent, validation ignorée."; return 0; }
|
|
14
|
+
step_t lang.packer.2
|
|
15
|
+
packer validate -syntax-only .
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PHP (Laravel, Symfony…) : pint / php-cs-fixer, composer test / artisan / pest / phpunit
|
|
3
|
+
register php "composer.json" '\.php$'
|
|
4
|
+
|
|
5
|
+
php_format() {
|
|
6
|
+
if [ -x vendor/bin/pint ]; then step_t lang.php.1; vendor/bin/pint -q "$@"
|
|
7
|
+
elif [ -x vendor/bin/php-cs-fixer ]; then step "PHP : php-cs-fixer"; vendor/bin/php-cs-fixer fix -q "$@"
|
|
8
|
+
elif has php-cs-fixer; then step "PHP : php-cs-fixer"; php-cs-fixer fix -q "$@"
|
|
9
|
+
else tool_missing "PHP : ni pint ni php-cs-fixer, formatage ignoré."
|
|
10
|
+
fi
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
php_test() {
|
|
14
|
+
if grep -q '"test"[[:space:]]*:' composer.json && has composer; then step_t lang.php.2; composer test
|
|
15
|
+
elif [ -f artisan ]; then step "PHP : artisan test"; php artisan test
|
|
16
|
+
elif [ -x vendor/bin/pest ]; then step "PHP : pest"; vendor/bin/pest
|
|
17
|
+
elif [ -x vendor/bin/phpunit ]; then step "PHP : phpunit"; vendor/bin/phpunit
|
|
18
|
+
else info "PHP : aucun lanceur de tests trouvé (composer install ?)."
|
|
19
|
+
fi
|
|
20
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Python (Django, FastAPI, Flask, scripts…) : ruff/black, pytest ou manage.py test
|
|
3
|
+
# Les outils du projet (.venv, uv) sont prioritaires : même version pour tous.
|
|
4
|
+
register python "pyproject.toml setup.py setup.cfg requirements.txt Pipfile manage.py" '\.pyi?$' standalone
|
|
5
|
+
|
|
6
|
+
# Exécute dans l'environnement du projet (uv, poetry, pipenv, .venv)
|
|
7
|
+
python_run() {
|
|
8
|
+
if [ -f uv.lock ] && has uv; then uv run --no-sync "$@"
|
|
9
|
+
elif [ -f poetry.lock ] && has poetry; then poetry run "$@"
|
|
10
|
+
elif [ -f Pipfile.lock ] && has pipenv; then pipenv run "$@"
|
|
11
|
+
elif [ -d .venv/bin ]; then PATH="$PWD/.venv/bin:$PATH" "$@"
|
|
12
|
+
elif [ -d .venv/Scripts ]; then PATH="$PWD/.venv/Scripts:$PATH" "$@"
|
|
13
|
+
else "$@"
|
|
14
|
+
fi
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
# Vrai si l'outil $1 est disponible (dans le projet, sinon sur le poste)
|
|
18
|
+
python_has() { python_run "$1" --version >/dev/null 2>&1; }
|
|
19
|
+
|
|
20
|
+
python_format() {
|
|
21
|
+
if python_has ruff; then step_t lang.python.1; python_run ruff format -q "$@"
|
|
22
|
+
elif python_has black; then step "Python : black"; python_run black -q "$@"
|
|
23
|
+
else tool_missing "Python : ni ruff ni black installé, formatage ignoré."
|
|
24
|
+
fi
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Vrai si le projet contient des tests : un requirements.txt seul (outils de
|
|
28
|
+
# documentation, scripts) ne doit pas exiger pytest.
|
|
29
|
+
python_has_tests() {
|
|
30
|
+
[ -f manage.py ] && return 0
|
|
31
|
+
# -quit : premier fichier trouvé suffit (pas de tube vers grep -q : SIGPIPE)
|
|
32
|
+
[ -n "$(find . \( -name node_modules -o -name .venv -o -name .git -o -name site-packages \) -prune -o \
|
|
33
|
+
\( -name 'test_*.py' -o -name '*_test.py' -o -name conftest.py \) -print -quit 2>/dev/null)" ]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
python_test() {
|
|
37
|
+
local rc=0 cache
|
|
38
|
+
# Cache de bytecode neuf : Python réutilise un .pyc si la source a même taille
|
|
39
|
+
# et même date à la seconde près — fréquent quand le hook met de côté puis
|
|
40
|
+
# restaure des fichiers. Sans ça, les tests tourneraient sur l'ancien code.
|
|
41
|
+
cache="$(mktemp -d)"
|
|
42
|
+
export PYTHONPYCACHEPREFIX="$cache"
|
|
43
|
+
# Django sans pytest-django : runner intégré
|
|
44
|
+
if [ -f manage.py ] && ! grep -qs pytest-django pyproject.toml requirements*.txt setup.cfg Pipfile; then
|
|
45
|
+
step_t lang.python.2
|
|
46
|
+
python_run python manage.py test || rc=$?
|
|
47
|
+
rm -rf "$cache"
|
|
48
|
+
return "$rc"
|
|
49
|
+
fi
|
|
50
|
+
if ! python_has_tests; then info_t lang.python.3; rm -rf "$cache"; return 0; fi
|
|
51
|
+
if ! python_has pytest; then warn_t lang.python.4; rm -rf "$cache"; return 0; fi
|
|
52
|
+
step_t lang.python.5
|
|
53
|
+
# Racine du projet importable (comme « python -m pytest ») : tests/ importe
|
|
54
|
+
# le paquet sans installation ni conftest.py
|
|
55
|
+
PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}" python_run pytest -q -p no:cacheprovider || rc=$?
|
|
56
|
+
rm -rf "$cache"
|
|
57
|
+
# 5 = aucun test collecté : pas une erreur
|
|
58
|
+
if [ "$rc" -eq 5 ]; then info_t lang.python.6; return 0; fi
|
|
59
|
+
return "$rc"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Code mort : ruff (imports et variables inutilisés, redéfinitions : prouvé) ;
|
|
63
|
+
# vulture (confiance 100 % : prouvé, en dessous : candidat — les frameworks
|
|
64
|
+
# appellent des fonctions par leur nom)
|
|
65
|
+
python_deadcode() {
|
|
66
|
+
local ran=""
|
|
67
|
+
if python_has ruff; then
|
|
68
|
+
ran=1
|
|
69
|
+
python_run ruff check --select F401,F811,F841 --output-format concise --quiet --exit-zero . 2>/dev/null |
|
|
70
|
+
sed -nE 's/^(.+):([0-9]+):[0-9]+: F[0-9]+ (\[\*\] )?(.*)$/prouve\t\1\t\2\t\4/p'
|
|
71
|
+
fi
|
|
72
|
+
if python_has vulture; then
|
|
73
|
+
ran=1
|
|
74
|
+
python_run vulture . --min-confidence 60 --exclude ".venv,venv,node_modules,build,dist,site-packages" 2>/dev/null |
|
|
75
|
+
sed -nE -e 's/^(.+):([0-9]+): (.*) \(100% confidence\)$/prouve\t\1\t\2\t\3/p' \
|
|
76
|
+
-e 's/^(.+):([0-9]+): (.*) \(([0-9]+)% confidence\)$/candidat\t\1\t\2\t\3 (\4 %)/p'
|
|
77
|
+
fi
|
|
78
|
+
[ -n "$ran" ] || deadcode_tool_missing Python "ruff / vulture"
|
|
79
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Ruby (Rails…) : rubocop -a / standardrb, rails test / rspec / rake test
|
|
3
|
+
register ruby "Gemfile" '(\.(rb|rake|gemspec)|(^|/)(Rakefile|Gemfile))$'
|
|
4
|
+
|
|
5
|
+
ruby_format() {
|
|
6
|
+
if grep -qs '^ rubocop ' Gemfile.lock; then
|
|
7
|
+
step_t lang.ruby.1
|
|
8
|
+
bundle exec rubocop -a --format quiet --fail-level F "$@"
|
|
9
|
+
elif grep -qs '^ standard ' Gemfile.lock; then
|
|
10
|
+
step_t lang.ruby.2
|
|
11
|
+
bundle exec standardrb --fix "$@" || true # les offenses non corrigeables ne bloquent pas
|
|
12
|
+
else
|
|
13
|
+
tool_missing "Ruby : ni rubocop ni standard dans le Gemfile, formatage ignoré."
|
|
14
|
+
fi
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
ruby_test() {
|
|
18
|
+
has bundle || { warn "Ruby : bundler absent, tests ignorés."; return 0; }
|
|
19
|
+
if [ -x bin/rails ]; then step_t lang.ruby.3; bin/rails test
|
|
20
|
+
elif [ -d spec ] && grep -qs '^ rspec' Gemfile.lock; then step "Ruby : rspec"; bundle exec rspec
|
|
21
|
+
elif [ -f Rakefile ]; then step "Ruby : rake test"; bundle exec rake test
|
|
22
|
+
else info "Ruby : aucun lanceur de tests trouvé."
|
|
23
|
+
fi
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Rust : rustfmt (fichiers stagés uniquement), cargo test
|
|
3
|
+
register rust "Cargo.toml" '\.rs$' standalone outermost
|
|
4
|
+
|
|
5
|
+
rust_format() {
|
|
6
|
+
has rustfmt || { tool_missing "Rust : rustfmt absent, formatage ignoré."; return 0; }
|
|
7
|
+
local edition
|
|
8
|
+
edition="$(grep -hsE '^[[:space:]]*edition[[:space:]]*=' Cargo.toml ./*/Cargo.toml | grep -oE '20[0-9]{2}' | sed -n 1p)"
|
|
9
|
+
step_t lang.rust.1
|
|
10
|
+
rustfmt --edition "${edition:-2021}" "$@"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
rust_test() {
|
|
14
|
+
has cargo || { warn "Rust : cargo absent, tests ignorés."; return 0; }
|
|
15
|
+
step_t lang.rust.2
|
|
16
|
+
cargo test --quiet
|
|
17
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Scripts shell : shfmt (respecte .editorconfig, sinon indentation 4 espaces)
|
|
3
|
+
register shell "" '\.(sh|bash)$' standalone
|
|
4
|
+
|
|
5
|
+
shell_format() {
|
|
6
|
+
has shfmt || { tool_missing "Shell : shfmt absent, formatage ignoré."; return 0; }
|
|
7
|
+
step_t lang.shell.1
|
|
8
|
+
if find_up .editorconfig >/dev/null; then shfmt -w "$@"; else shfmt -w -i 4 -ci "$@"; fi
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Swift (SwiftPM) : swift-format / SwiftFormat si une config existe, swift test
|
|
3
|
+
# Pas de style canonique en Swift : formatage seulement avec .swift-format ou .swiftformat
|
|
4
|
+
register swift "Package.swift" '\.swift$' standalone
|
|
5
|
+
|
|
6
|
+
swift_format() {
|
|
7
|
+
if find_up .swift-format >/dev/null && swift format --version >/dev/null 2>&1; then
|
|
8
|
+
step_t lang.swift.1; swift format --in-place "$@"
|
|
9
|
+
elif find_up .swiftformat >/dev/null && has swiftformat; then
|
|
10
|
+
step_t lang.swift.2; swiftformat --quiet "$@"
|
|
11
|
+
else
|
|
12
|
+
tool_missing "Swift : pas de .swift-format/.swiftformat (ou outil absent), formatage ignoré."
|
|
13
|
+
fi
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
swift_test() {
|
|
17
|
+
[ -d Tests ] || { info "Swift : pas de dossier Tests/."; return 0; }
|
|
18
|
+
has swift || { warn "Swift : swift absent, tests ignorés."; return 0; }
|
|
19
|
+
step_t lang.swift.3; swift test
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Projets sans langage reconnu : cible "test" d'un Makefile, justfile ou Taskfile
|
|
3
|
+
register tasks "Makefile makefile GNUmakefile justfile Justfile .justfile Taskfile.yml Taskfile.yaml" '^$' fallback
|
|
4
|
+
|
|
5
|
+
tasks_test() {
|
|
6
|
+
if compgen -G "[Mm]akefile" >/dev/null || [ -f GNUmakefile ]; then
|
|
7
|
+
if has make && make -n test >/dev/null 2>&1; then step_t lang.tasks.1; make test; return; fi
|
|
8
|
+
fi
|
|
9
|
+
if compgen -G "*ustfile" >/dev/null || [ -f .justfile ]; then
|
|
10
|
+
if has just && just --show test >/dev/null 2>&1; then step_t lang.tasks.2; just test; return; fi
|
|
11
|
+
fi
|
|
12
|
+
if compgen -G "Taskfile.y*ml" >/dev/null; then
|
|
13
|
+
if has task && grep -q '^\* test:' <<<"$(task --list-all 2>/dev/null)"; then step_t lang.tasks.3; task test; return; fi
|
|
14
|
+
fi
|
|
15
|
+
info_t lang.tasks.4
|
|
16
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Terraform / OpenTofu : fmt ; init (sans backend) + validate + tflint au push / en CI
|
|
3
|
+
register terraform "*.tf" '\.(tf|tfvars|tftest\.hcl)$' standalone
|
|
4
|
+
|
|
5
|
+
terraform_bin() { command -v terraform || command -v tofu || true; }
|
|
6
|
+
|
|
7
|
+
terraform_format() {
|
|
8
|
+
local bin
|
|
9
|
+
bin="$(terraform_bin)"
|
|
10
|
+
[ -n "$bin" ] || { tool_missing "Terraform : terraform/tofu absent, formatage ignoré."; return 0; }
|
|
11
|
+
step_t lang.terraform.1
|
|
12
|
+
"$bin" fmt "$@" >/dev/null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
terraform_test() {
|
|
16
|
+
local bin
|
|
17
|
+
bin="$(terraform_bin)"
|
|
18
|
+
[ -n "$bin" ] || { warn "Terraform : terraform/tofu absent, validation ignorée."; return 0; }
|
|
19
|
+
step_t lang.terraform.2
|
|
20
|
+
# Providers partagés entre modules et entre lancements
|
|
21
|
+
TF_PLUGIN_CACHE_DIR="${TF_PLUGIN_CACHE_DIR:-$(cache_dir terraform-plugins)}" \
|
|
22
|
+
"$bin" init -backend=false -input=false -no-color >/dev/null || return 1
|
|
23
|
+
"$bin" validate -no-color || return 1
|
|
24
|
+
if has tflint; then
|
|
25
|
+
step_t lang.terraform.3
|
|
26
|
+
tflint --init >/dev/null 2>&1
|
|
27
|
+
tflint --no-color || return 1
|
|
28
|
+
fi
|
|
29
|
+
}
|