mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
feat: automate project bootstrap and registry
This commit is contained in:
11
CLAUDE.md
11
CLAUDE.md
@@ -17,7 +17,7 @@ Ces fichiers sont la mémoire durable inter-projets. Consulte-les avant de propo
|
|||||||
une solution dans leur domaine respectif.
|
une solution dans leur domaine respectif.
|
||||||
|
|
||||||
| Fichier | Contenu |
|
| Fichier | Contenu |
|
||||||
|---|---|
|
| ------------------------------------- | ---------------------------------------------- |
|
||||||
| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles |
|
| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles |
|
||||||
| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés |
|
| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés |
|
||||||
| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend |
|
| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend |
|
||||||
@@ -39,9 +39,11 @@ Puis propose le contenu à ajouter dans le format du fichier cible.
|
|||||||
|
|
||||||
## Projets actifs
|
## Projets actifs
|
||||||
|
|
||||||
| Projet | Stack | Localisation | État |
|
La liste des projets actifs est maintenue dans `_projects.conf`.
|
||||||
|---|---|---|---|
|
|
||||||
| app-alexandrie | NestJS + Expo (React Native) + Prisma + pnpm monorepo | `/Volumes/TeraSSD/Projets_Dev/__Mindleaf/app-alexandrie` | Epic 2 en préparation |
|
Ce fichier constitue le registre central des projets (stack, scope, état).
|
||||||
|
Les scripts de l’environnement Lead_tech l’utilisent pour résoudre
|
||||||
|
automatiquement les chemins selon la machine (Mac / NUC).
|
||||||
|
|
||||||
## Patterns clés à appliquer systématiquement
|
## Patterns clés à appliquer systématiquement
|
||||||
|
|
||||||
@@ -54,6 +56,7 @@ Puis propose le contenu à ajouter dans le format du fichier cible.
|
|||||||
## Infrastructure NUC
|
## Infrastructure NUC
|
||||||
|
|
||||||
Convention de structure Docker sur le NUC (Proxmox) :
|
Convention de structure Docker sur le NUC (Proxmox) :
|
||||||
|
|
||||||
- `/srv/projects` — code applicatif
|
- `/srv/projects` — code applicatif
|
||||||
- `/srv/docker-data` — données persistantes (bind mounts explicites)
|
- `/srv/docker-data` — données persistantes (bind mounts explicites)
|
||||||
- `/srv/backups` — dumps et archives
|
- `/srv/backups` — dumps et archives
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Ces fichiers sont la mémoire durable inter-projets. Consulte-les avant de propo
|
|||||||
une solution dans leur domaine respectif.
|
une solution dans leur domaine respectif.
|
||||||
|
|
||||||
| Fichier | Contenu |
|
| Fichier | Contenu |
|
||||||
|---|---|
|
| ------------------------------------- | ---------------------------------------------- |
|
||||||
| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles |
|
| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles |
|
||||||
| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés |
|
| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés |
|
||||||
| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend |
|
| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend |
|
||||||
@@ -34,7 +34,11 @@ Puis propose le contenu à ajouter dans le format du fichier cible.
|
|||||||
|
|
||||||
## Projets actifs
|
## Projets actifs
|
||||||
|
|
||||||
{{PROJECTS_TABLE}}
|
La liste des projets actifs est maintenue dans `_projects.conf`.
|
||||||
|
|
||||||
|
Ce fichier constitue le registre central des projets (stack, scope, état).
|
||||||
|
Les scripts de l’environnement Lead_tech l’utilisent pour résoudre
|
||||||
|
automatiquement les chemins selon la machine (Mac / NUC).
|
||||||
|
|
||||||
## Patterns clés à appliquer systématiquement
|
## Patterns clés à appliquer systématiquement
|
||||||
|
|
||||||
@@ -47,6 +51,7 @@ Puis propose le contenu à ajouter dans le format du fichier cible.
|
|||||||
## Infrastructure NUC
|
## Infrastructure NUC
|
||||||
|
|
||||||
Convention de structure Docker sur le NUC (Proxmox) :
|
Convention de structure Docker sur le NUC (Proxmox) :
|
||||||
|
|
||||||
- `/srv/projects` — code applicatif
|
- `/srv/projects` — code applicatif
|
||||||
- `/srv/docker-data` — données persistantes (bind mounts explicites)
|
- `/srv/docker-data` — données persistantes (bind mounts explicites)
|
||||||
- `/srv/backups` — dumps et archives
|
- `/srv/backups` — dumps et archives
|
||||||
|
|||||||
@@ -1,6 +1,53 @@
|
|||||||
# Configuration des projets actifs
|
# Registre des projets (source de vérité)
|
||||||
# Format : nom|stack|path_nuc|path_mac|etat
|
#
|
||||||
# Laisser path_nuc ou path_mac vide si le projet n'existe pas sur cette machine
|
# Format principal :
|
||||||
# Exemple NUC seulement : mon-projet|Stack|/srv/projects/mon-projet||En cours
|
# nom|stack|scope|etat
|
||||||
|
#
|
||||||
app-alexandrie|NestJS + Expo (React Native) + Prisma + pnpm monorepo|/srv/projects/app-alexandrie|/Volumes/TeraSSD/Projets_Dev/__Mindleaf/app-alexandrie|Epic 2 en préparation
|
# Ce fichier sert de registre central pour les projets de développement.
|
||||||
|
# Il est utilisé par les scripts du repo Lead_tech et peut être lu par les agents
|
||||||
|
# (Claude, Codex, BMAD) pour comprendre l’architecture globale.
|
||||||
|
#
|
||||||
|
# Signification des champs :
|
||||||
|
#
|
||||||
|
# nom : nom du repository / dossier projet
|
||||||
|
# stack : stack principale (utile pour les agents et les audits techniques)
|
||||||
|
# scope : localisation logique du projet
|
||||||
|
# etat : statut actuel du projet
|
||||||
|
#
|
||||||
|
# Résolution automatique des chemins :
|
||||||
|
#
|
||||||
|
# Le champ `scope` représente d'abord une **catégorie logique de projet**
|
||||||
|
# (perso, mindleaf, lab, archive), utile pour le classement et les agents.
|
||||||
|
#
|
||||||
|
# Sur Mac, le `scope` détermine aussi la base du chemin :
|
||||||
|
# - perso → /Volumes/TeraSSD/Projets_Dev/<nom>
|
||||||
|
# - mindleaf → /Volumes/TeraSSD/Projets_Dev/__Mindleaf/<nom>
|
||||||
|
# - lab → /Volumes/TeraSSD/Labs/<nom>
|
||||||
|
# - archive → /Volumes/TeraSSD/Archives_Projets/<nom>
|
||||||
|
#
|
||||||
|
# Sur le NUC, le `scope` ne change pas le chemin physique :
|
||||||
|
# - tous les projets vivent dans /srv/projects/<nom>
|
||||||
|
#
|
||||||
|
# Le `scope` reste néanmoins utile sur le NUC comme information logique
|
||||||
|
# (catégorie, contexte métier, filtres futurs, audits inter-projets, etc.).
|
||||||
|
#
|
||||||
|
# Valeurs recommandées pour scope :
|
||||||
|
# - perso
|
||||||
|
# - mindleaf
|
||||||
|
# - lab
|
||||||
|
# - archive
|
||||||
|
#
|
||||||
|
# Valeurs typiques pour etat :
|
||||||
|
# - dev
|
||||||
|
# - active
|
||||||
|
# - maintenance
|
||||||
|
# - archived
|
||||||
|
#
|
||||||
|
# Les scripts peuvent utiliser ce fichier pour :
|
||||||
|
# - résoudre le chemin d’un projet
|
||||||
|
# - lister les projets actifs
|
||||||
|
# - analyser les stacks
|
||||||
|
# - automatiser certains audits inter-projets
|
||||||
|
#
|
||||||
|
# Les lignes commençant par # sont ignorées.
|
||||||
|
app-alexandrie|NestJS + Expo (React Native) + Prisma + pnpm monorepo|mindleaf|Epic 2 en préparation
|
||||||
@@ -1,11 +1,19 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
PROJECTS_CONF="$REPO_ROOT/_projects.conf"
|
||||||
|
|
||||||
PROJECT_NAME="${1:-}"
|
PROJECT_NAME="${1:-}"
|
||||||
OS="$(uname -s)"
|
OS="$(uname -s)"
|
||||||
TARGET_BASE=""
|
TARGET_BASE=""
|
||||||
PROJECT_PATH=""
|
PROJECT_PATH=""
|
||||||
|
|
||||||
|
PROJECT_SCOPE=""
|
||||||
|
PROJECT_STACK=""
|
||||||
|
PROJECT_STATE="dev"
|
||||||
|
|
||||||
if [ -z "$PROJECT_NAME" ]; then
|
if [ -z "$PROJECT_NAME" ]; then
|
||||||
echo "Usage: mkproj <nom_du_projet>"
|
echo "Usage: mkproj <nom_du_projet>"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -16,16 +24,28 @@ choose_mac_target_base() {
|
|||||||
echo "Choisir le type de projet :"
|
echo "Choisir le type de projet :"
|
||||||
echo " 1) Projet perso -> /Volumes/TeraSSD/Projets_Dev"
|
echo " 1) Projet perso -> /Volumes/TeraSSD/Projets_Dev"
|
||||||
echo " 2) Projet Mindleaf -> /Volumes/TeraSSD/Projets_Dev/__Mindleaf"
|
echo " 2) Projet Mindleaf -> /Volumes/TeraSSD/Projets_Dev/__Mindleaf"
|
||||||
printf "Votre choix [1/2] : "
|
echo " 3) Projet lab -> /Volumes/TeraSSD/Labs"
|
||||||
|
echo " 4) Projet archive -> /Volumes/TeraSSD/Archives_Projets"
|
||||||
|
printf "Votre choix [1/2/3/4] : "
|
||||||
read -r choice
|
read -r choice
|
||||||
|
|
||||||
case "$choice" in
|
case "$choice" in
|
||||||
1)
|
1)
|
||||||
|
PROJECT_SCOPE="perso"
|
||||||
TARGET_BASE="/Volumes/TeraSSD/Projets_Dev"
|
TARGET_BASE="/Volumes/TeraSSD/Projets_Dev"
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
|
PROJECT_SCOPE="mindleaf"
|
||||||
TARGET_BASE="/Volumes/TeraSSD/Projets_Dev/__Mindleaf"
|
TARGET_BASE="/Volumes/TeraSSD/Projets_Dev/__Mindleaf"
|
||||||
;;
|
;;
|
||||||
|
3)
|
||||||
|
PROJECT_SCOPE="lab"
|
||||||
|
TARGET_BASE="/Volumes/TeraSSD/Labs"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
PROJECT_SCOPE="archive"
|
||||||
|
TARGET_BASE="/Volumes/TeraSSD/Archives_Projets"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Choix invalide."
|
echo "Choix invalide."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -38,6 +58,24 @@ choose_target_base() {
|
|||||||
Linux)
|
Linux)
|
||||||
echo "Environnement détecté : NUC/Linux"
|
echo "Environnement détecté : NUC/Linux"
|
||||||
TARGET_BASE="/srv/projects"
|
TARGET_BASE="/srv/projects"
|
||||||
|
echo "Choisir le scope logique du projet :"
|
||||||
|
echo " 1) perso"
|
||||||
|
echo " 2) mindleaf"
|
||||||
|
echo " 3) lab"
|
||||||
|
echo " 4) archive"
|
||||||
|
printf "Votre choix [1/2/3/4] : "
|
||||||
|
read -r choice
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
1) PROJECT_SCOPE="perso" ;;
|
||||||
|
2) PROJECT_SCOPE="mindleaf" ;;
|
||||||
|
3) PROJECT_SCOPE="lab" ;;
|
||||||
|
4) PROJECT_SCOPE="archive" ;;
|
||||||
|
*)
|
||||||
|
echo "Choix invalide."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
Darwin)
|
Darwin)
|
||||||
choose_mac_target_base
|
choose_mac_target_base
|
||||||
@@ -49,6 +87,30 @@ choose_target_base() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prompt_project_metadata() {
|
||||||
|
printf "Stack principale [à préciser] : "
|
||||||
|
read -r PROJECT_STACK
|
||||||
|
PROJECT_STACK="${PROJECT_STACK:-à préciser}"
|
||||||
|
|
||||||
|
printf "État du projet [dev] : "
|
||||||
|
read -r PROJECT_STATE
|
||||||
|
PROJECT_STATE="${PROJECT_STATE:-dev}"
|
||||||
|
}
|
||||||
|
|
||||||
|
register_project_in_conf() {
|
||||||
|
if [ ! -f "$PROJECTS_CONF" ]; then
|
||||||
|
echo "Erreur : fichier introuvable : $PROJECTS_CONF" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -Eq "^${PROJECT_NAME}\|" "$PROJECTS_CONF"; then
|
||||||
|
echo "Erreur : le projet $PROJECT_NAME existe déjà dans _projects.conf" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%s|%s|%s|%s\n" "$PROJECT_NAME" "$PROJECT_STACK" "$PROJECT_SCOPE" "$PROJECT_STATE" >> "$PROJECTS_CONF"
|
||||||
|
}
|
||||||
|
|
||||||
create_readme() {
|
create_readme() {
|
||||||
cat <<EOF > "$PROJECT_PATH/README.md"
|
cat <<EOF > "$PROJECT_PATH/README.md"
|
||||||
# $PROJECT_NAME
|
# $PROJECT_NAME
|
||||||
@@ -61,6 +123,7 @@ Projet initialisé avec l'environnement Lead_tech.
|
|||||||
- \`AGENTS.md\` : symlink vers \`CLAUDE.md\`
|
- \`AGENTS.md\` : symlink vers \`CLAUDE.md\`
|
||||||
- \`README.md\` : documentation projet
|
- \`README.md\` : documentation projet
|
||||||
- \`.gitignore\` : exclusions Git de base
|
- \`.gitignore\` : exclusions Git de base
|
||||||
|
- \`_projects.conf\` (Lead_tech) : registre logique des projets
|
||||||
|
|
||||||
## Commandes utiles
|
## Commandes utiles
|
||||||
|
|
||||||
@@ -111,10 +174,14 @@ tmp/
|
|||||||
# AI tools
|
# AI tools
|
||||||
.claude/
|
.claude/
|
||||||
.codex/
|
.codex/
|
||||||
|
|
||||||
|
# Agent compatibility file (symlink to CLAUDE.md)
|
||||||
|
AGENTS.md
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
choose_target_base
|
choose_target_base
|
||||||
|
prompt_project_metadata
|
||||||
|
|
||||||
if [ ! -d "$TARGET_BASE" ]; then
|
if [ ! -d "$TARGET_BASE" ]; then
|
||||||
echo "Le dossier cible n'existe pas : $TARGET_BASE"
|
echo "Le dossier cible n'existe pas : $TARGET_BASE"
|
||||||
@@ -139,8 +206,11 @@ gen-claude "$PROJECT_NAME"
|
|||||||
create_readme
|
create_readme
|
||||||
create_gitignore
|
create_gitignore
|
||||||
|
|
||||||
|
register_project_in_conf
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Projet créé : $PROJECT_PATH"
|
echo "Projet créé : $PROJECT_PATH"
|
||||||
|
echo "Projet enregistré dans : $PROJECTS_CONF"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Prochaines étapes :"
|
echo "Prochaines étapes :"
|
||||||
echo " cd $PROJECT_PATH"
|
echo " cd $PROJECT_PATH"
|
||||||
|
|||||||
77
scripts/resolve-project-path.sh
Executable file
77
scripts/resolve-project-path.sh
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
PROJECTS_CONF="$REPO_ROOT/_projects.conf"
|
||||||
|
OS="$(uname -s)"
|
||||||
|
PROJECT_NAME="${1:-}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: resolve-project-path.sh <nom_du_projet>" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -z "$PROJECT_NAME" ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$PROJECTS_CONF" ]; then
|
||||||
|
echo "Erreur : fichier introuvable : $PROJECTS_CONF" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
resolve_base_path() {
|
||||||
|
local scope="$1"
|
||||||
|
|
||||||
|
case "$OS" in
|
||||||
|
Linux)
|
||||||
|
case "$scope" in
|
||||||
|
perso|mindleaf|lab|archive)
|
||||||
|
echo "/srv/projects"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Erreur : scope inconnu sur Linux : $scope" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
Darwin)
|
||||||
|
case "$scope" in
|
||||||
|
perso)
|
||||||
|
echo "/Volumes/TeraSSD/Projets_Dev"
|
||||||
|
;;
|
||||||
|
mindleaf)
|
||||||
|
echo "/Volumes/TeraSSD/Projets_Dev/__Mindleaf"
|
||||||
|
;;
|
||||||
|
lab)
|
||||||
|
echo "/Volumes/TeraSSD/Labs"
|
||||||
|
;;
|
||||||
|
archive)
|
||||||
|
echo "/Volumes/TeraSSD/Archives_Projets"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Erreur : scope inconnu sur macOS : $scope" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Erreur : système non supporté : $OS" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
while IFS='|' read -r name stack scope state; do
|
||||||
|
[[ -z "$name" || "$name" == \#* ]] && continue
|
||||||
|
|
||||||
|
if [ "$name" = "$PROJECT_NAME" ]; then
|
||||||
|
BASE_PATH="$(resolve_base_path "$scope")"
|
||||||
|
echo "$BASE_PATH/$name"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done < "$PROJECTS_CONF"
|
||||||
|
|
||||||
|
echo "Erreur : projet introuvable dans _projects.conf : $PROJECT_NAME" >&2
|
||||||
|
exit 1
|
||||||
@@ -9,39 +9,16 @@ set -euo pipefail
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
SOURCE="$REPO_ROOT/_AI_INSTRUCTIONS.md"
|
SOURCE="$REPO_ROOT/_AI_INSTRUCTIONS.md"
|
||||||
PROJECTS_CONF="$REPO_ROOT/_projects.conf"
|
|
||||||
|
|
||||||
# --- Détection machine ---
|
# --- Détection machine ---
|
||||||
OS="$(uname -s)"
|
OS="$(uname -s)"
|
||||||
CHANGED=0
|
CHANGED=0
|
||||||
|
|
||||||
# --- Construire la table markdown des projets ---
|
|
||||||
build_projects_table() {
|
|
||||||
local os="$1"
|
|
||||||
echo "| Projet | Stack | Localisation | État |"
|
|
||||||
echo "|---|---|---|---|"
|
|
||||||
while IFS='|' read -r nom stack path_nuc path_mac etat; do
|
|
||||||
# Ignorer lignes vides et commentaires
|
|
||||||
[[ -z "$nom" || "$nom" == \#* ]] && continue
|
|
||||||
if [ "$os" = "Darwin" ]; then
|
|
||||||
path="$path_mac"
|
|
||||||
else
|
|
||||||
path="$path_nuc"
|
|
||||||
fi
|
|
||||||
if [ -z "$path" ]; then
|
|
||||||
echo "| $nom | $stack | *non disponible sur cette machine* | $etat |"
|
|
||||||
else
|
|
||||||
echo "| $nom | $stack | \`$path\` | $etat |"
|
|
||||||
fi
|
|
||||||
done < "$PROJECTS_CONF"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_repo_claude() {
|
generate_repo_claude() {
|
||||||
local header="$1"
|
local header="$1"
|
||||||
local dest="$2"
|
local dest="$2"
|
||||||
local projects_table
|
|
||||||
local tmp
|
local tmp
|
||||||
projects_table="$(build_projects_table "$OS")"
|
|
||||||
tmp="$(mktemp)"
|
tmp="$(mktemp)"
|
||||||
|
|
||||||
mkdir -p "$(dirname "$dest")"
|
mkdir -p "$(dirname "$dest")"
|
||||||
@@ -49,14 +26,7 @@ generate_repo_claude() {
|
|||||||
{
|
{
|
||||||
echo "$header"
|
echo "$header"
|
||||||
echo ""
|
echo ""
|
||||||
# Remplacer {{PROJECTS_TABLE}} par la table générée
|
cat "$SOURCE"
|
||||||
while IFS= read -r line; do
|
|
||||||
if [ "$line" = "{{PROJECTS_TABLE}}" ]; then
|
|
||||||
echo "$projects_table"
|
|
||||||
else
|
|
||||||
echo "$line"
|
|
||||||
fi
|
|
||||||
done < "$SOURCE"
|
|
||||||
} > "$tmp"
|
} > "$tmp"
|
||||||
|
|
||||||
if [ ! -f "$dest" ] || ! cmp -s "$tmp" "$dest"; then
|
if [ ! -f "$dest" ] || ! cmp -s "$tmp" "$dest"; then
|
||||||
|
|||||||
Reference in New Issue
Block a user