feat: Makefile remplace install.sh / prep.sh / uninstall.sh

- make install  : déploie tout dans ~/.local/ (aucune dépendance externe)
- make build    : génère les pages man via Pandoc (développeur uniquement)
- make uninstall: supprime les fichiers installés
- make clean    : supprime les pages man locales

Plus de fichiers de listing .config/files_local-* intermédiaires.
Plus de dépendance Pandoc côté utilisateur (pages man pré-buildées dans le dépôt).

README : liste des scripts avec liens vers la documentation, embed Obsidian supprimé.
DEVELOPER.md : workflow mis à jour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 21:42:44 +02:00
parent 3050b6d7c0
commit 647e1ae4ad
6 changed files with 156 additions and 303 deletions
+16 -16
View File
@@ -4,46 +4,46 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Workflow de développement
**Toujours lancer depuis la racine du projet** (vérifié par les scripts eux-mêmes).
**Toujours lancer depuis la racine du projet** (vérifié par le Makefile).
### Ajouter un nouveau script
1. Placer le script dans `local/bin/<nom>.sh`
2. Créer la documentation dans `local/share/doc/scripts-bash/<nom>.1.md` (format man Markdown)
3. Lancer `prep.sh` il génère la page man dans `local/share/man/man1/<nom>.1` et met à jour les listes dans `.config/`
4. Committer les trois fichiers + les fichiers `.config/` mis à jour
5. Pousser avec le remote HTTPS qui embarque le token Gitea dans l'URL
3. Lancer `make build` — génère la page man dans `local/share/man/man1/<nom>.1` via Pandoc
4. Committer les trois fichiers (`local/bin/`, `local/share/doc/`, `local/share/man/`)
5. Pousser
### Commandes principales
### Commandes
```bash
bash prep.sh # Génère les pages man (Pandoc) et met à jour les listes .config/
bash install.sh # Déploie tout dans ~/.local/{bin,share/...}
bash uninstall.sh # Supprime les fichiers déployés via ~/.config/a5l_scripts-bash_uninstall-list
make build # Développeur : génère les pages man depuis les .1.md (nécessite Pandoc)
make install # Utilisateur : déploie tout dans ~/.local/
make uninstall # Supprime les fichiers installés
make clean # Supprime les pages man générées localement
```
## Architecture
```
local/bin/ → scripts déployés dans ~/.local/bin (extensions .sh retirées à l'install)
local/bin/ → scripts déployés dans ~/.local/bin (.sh retiré à l'install)
local/share/doc/ → documentation source en Markdown (format man)
local/share/man/ → pages man générées par prep.sh via Pandoc (ne pas éditer manuellement)
local/share/man/ → pages man pré-générées via Pandoc (ne pas éditer manuellement)
local/share/ytdll/ → config et libs pour le script ytdll
.config/ → listes de fichiers utilisées par install.sh (générées par prep.sh)
ecoleA/ → scripts d'administration pour déploiements école
servers/linux/ → scripts serveur Linux
```
### Mécanisme install/uninstall
### Makefile
`install.sh` lit les listes `.config/files_local-*` (produites par `prep.sh`) pour savoir quoi copier. Chaque fichier déployé est enregistré dans `~/.config/a5l_scripts-bash_uninstall-list`, ce qui permet à `uninstall.sh` de tout supprimer proprement.
`make install` lit les sources directement avec `$(wildcard ...)` — pas de fichiers de listing intermédiaires. Les scripts `.sh` sont installés sans extension dans `~/.local/bin`. Les autres (PHP, sans extension) sont copiés tels quels.
Les scripts `.sh` sont installés **sans extension** dans `~/.local/bin`. Les autres fichiers (PHP, man, JSON) sont copiés tels quels.
`make build` est une cible développeur (nécessite Pandoc). Les pages man générées sont committées dans le dépôt pour que `make install` fonctionne sans Pandoc côté utilisateur.
### Documentation
Chaque script doit avoir une fiche `local/share/doc/scripts-bash/<nom>.1.md` avec au minimum les sections `# NOM`, `# SYNOPSIS`, `# DESCRIPTION`. Le frontmatter YAML (tags, nom, description) est utilisé dans Obsidian pour l'indexation via `liste-des-scripts.base`.
Chaque script doit avoir une fiche `local/share/doc/scripts-bash/<nom>.1.md` avec au minimum les sections `# NOM`, `# SYNOPSIS`, `# DESCRIPTION`.
### Remote Git
Le remote `origin` utilise HTTPS avec le token Gitea intégré dans l'URL (`https://user:TOKEN@git.abonnel.fr/...`). Ne pas passer en SSH sans mettre à jour tous les projets qui partagent ce token.
Le remote `origin` utilise HTTPS avec le token Gitea intégré dans l'URL (`https://user:TOKEN@git.abonnel.fr/...`).
+101
View File
@@ -0,0 +1,101 @@
# ──────────────────────────────────────────────────────────────
# XDG Base Directory Specification
# ──────────────────────────────────────────────────────────────
XDG_DATA_HOME ?= $(HOME)/.local/share
XDG_BIN_HOME ?= $(HOME)/.local/bin
INSTALL_BIN := $(XDG_BIN_HOME)
INSTALL_MAN := $(XDG_DATA_HOME)/man/man1
INSTALL_DOC := $(XDG_DATA_HOME)/doc/scripts-bash
INSTALL_YTDLL := $(XDG_DATA_HOME)/ytdll
# ──────────────────────────────────────────────────────────────
# Sources
# ──────────────────────────────────────────────────────────────
SCRIPTS_SH := $(wildcard local/bin/*.sh)
SCRIPTS_OTHER := $(wildcard local/bin/*.php) \
$(filter-out $(wildcard local/bin/*.*),$(wildcard local/bin/*))
DOC_SRC := $(wildcard local/share/doc/scripts-bash/*.md)
MAN_PAGES := $(patsubst local/share/doc/scripts-bash/%.md,local/share/man/man1/%,$(DOC_SRC))
# ──────────────────────────────────────────────────────────────
.PHONY: all build install uninstall clean
## Cible par défaut : installe tout dans ~/.local/
all: install
## build : génère les pages man depuis les .md (développeur, nécessite Pandoc)
build: $(MAN_PAGES)
local/share/man/man1/%: local/share/doc/scripts-bash/%.md
@mkdir -p $(dir $@)
pandoc -s $< -t man -o $@
@echo " MAN $@"
## install : déploie tout dans ~/.local/ (aucune dépendance externe)
install:
@[ -d "local/bin" ] || { echo "Erreur : lancer depuis la racine du projet scripts-bash"; exit 1; }
@mkdir -p "$(INSTALL_BIN)" "$(INSTALL_MAN)" "$(INSTALL_DOC)" "$(INSTALL_YTDLL)/lib"
@for f in $(SCRIPTS_SH); do \
dest="$(INSTALL_BIN)/$$(basename "$${f%.sh}")"; \
install -m 755 "$$f" "$$dest"; \
echo " BIN $$dest"; \
done
@for f in $(SCRIPTS_OTHER); do \
dest="$(INSTALL_BIN)/$$(basename "$$f")"; \
install -m 755 "$$f" "$$dest"; \
echo " BIN $$dest"; \
done
@for f in $(wildcard local/share/man/man1/*); do \
install -m 644 "$$f" "$(INSTALL_MAN)/$$(basename "$$f")"; \
echo " MAN $(INSTALL_MAN)/$$(basename "$$f")"; \
done
@for f in $(wildcard local/share/doc/scripts-bash/*); do \
install -m 644 "$$f" "$(INSTALL_DOC)/$$(basename "$$f")"; \
echo " DOC $(INSTALL_DOC)/$$(basename "$$f")"; \
done
@for f in $(wildcard local/share/ytdll/*); do \
[ -f "$$f" ] || continue; \
install -m 644 "$$f" "$(INSTALL_YTDLL)/$$(basename "$$f")"; \
echo " DATA $(INSTALL_YTDLL)/$$(basename "$$f")"; \
done
@for f in $(wildcard local/share/ytdll/lib/*); do \
install -m 644 "$$f" "$(INSTALL_YTDLL)/lib/$$(basename "$$f")"; \
echo " DATA $(INSTALL_YTDLL)/lib/$$(basename "$$f")"; \
done
@path_line='export PATH="$$PATH:$$HOME/.local/bin"'; \
if ! grep -qF "$$path_line" ~/.bashrc 2>/dev/null; then \
echo "$$path_line" >> ~/.bashrc; \
echo " PATH ~/.bashrc ← ~/.local/bin (rechargez votre terminal)"; \
fi
@manpath_line='export MANPATH="$$(manpath):$$HOME/.local/share/man"'; \
if ! grep -qF "$$manpath_line" ~/.bashrc 2>/dev/null; then \
echo "$$manpath_line" >> ~/.bashrc; \
echo " MANPATH ~/.bashrc ← ~/.local/share/man (rechargez votre terminal)"; \
fi
@echo ""
@echo "Installation terminée."
## uninstall : supprime les fichiers installés par 'make install'
uninstall:
@[ -d "local/bin" ] || { echo "Erreur : lancer depuis la racine du projet scripts-bash"; exit 1; }
@for f in $(SCRIPTS_SH); do \
rm -fv "$(INSTALL_BIN)/$$(basename "$${f%.sh}")"; \
done
@for f in $(SCRIPTS_OTHER); do \
rm -fv "$(INSTALL_BIN)/$$(basename "$$f")"; \
done
@for f in $(wildcard local/share/man/man1/*); do \
rm -fv "$(INSTALL_MAN)/$$(basename "$$f")"; \
done
@for f in $(wildcard local/share/doc/scripts-bash/*); do \
rm -fv "$(INSTALL_DOC)/$$(basename "$$f")"; \
done
@rm -rfv "$(INSTALL_YTDLL)"
@echo "Désinstallation terminée."
## clean : supprime les pages man générées (dépôt local uniquement)
clean:
@rm -f $(MAN_PAGES)
@echo "Pages man supprimées."
+38 -19
View File
@@ -1,41 +1,60 @@
# scripts-bash
Quelques scripts Bash
Collection de scripts Bash pour Linux Mint / Debian.
Le script `install.sh` a été conçu pour automatiser le processus de copie de fichiers depuis un dépôt Git local vers un répertoire local.
Le script modifie également le chemin d'accès (PATH) de l'utilisateur ainsi que le chemin d'accès de man (MANPATH) de l'utilisateur.
## Installation
## Liste des scripts
```bash
git clone https://git.abonnel.fr/cedricAbonnel/scripts-bash.git
cd scripts-bash
make install
```
![[liste des scripts.base]]
`make install` copie les scripts dans `~/.local/bin`, les pages man dans `~/.local/share/man/man1`,
et ajoute `~/.local/bin` au `PATH` dans `~/.bashrc` si nécessaire. Rechargez votre terminal après l'installation.
## Utilisation
## Scripts
Pour utiliser ces scripts, suivez ces étapes :
### Documentés
1. Clonez ce dépôt Git.
`git clone https://git.abonnel.fr/cedricAbonnel/scripts-bash.git`
| Commande | Description | Documentation |
|---|---|---|
| `castopod_update` | Mise à jour de CASTOPOD | [castopod_update.1.md](local/share/doc/scripts-bash/castopod_update.1.md) |
| `convertPDF` | Compresse des fichiers PDF et génère un OCR | [convertPDF.1.md](local/share/doc/scripts-bash/convertPDF.1.md) |
| `playlist_gen` | Génère une playlist M3U à partir de fichiers audio | [playlist_gen.1.md](local/share/doc/scripts-bash/playlist_gen.1.md) |
| `play_tophaire` | Jingle et annonce de l'heure via espeak-ng | [play_tophoraire.1.md](local/share/doc/scripts-bash/play_tophoraire.1.md) |
| `random_music_player` | Lecteur de musique aléatoire en ligne de commande | [random_music_player.1.md](local/share/doc/scripts-bash/random_music_player.1.md) |
| `verif-desktop` | Audit des fichiers .desktop — chemins manquants, apps cachées, erreurs de syntaxe | [verif-desktop.1.md](local/share/doc/scripts-bash/verif-desktop.1.md) |
2. Exécutez le script en utilisant la commande `./install.sh`.
Le script copiera les fichiers du programme, les pages d'aide et les paramètres dans votre dossier personnel. Il est possible qu'un compte `sudo `soit requis pour l'installation de binaires externes.
### Autres scripts
Toutes les opérations et les messages d'erreur sont enregistrés dans un fichier journal (`~/.local/state/scripts-bash/a5l-scripts_bash-<date>-<PID>.log`). Le journal inclut la date, l'heure et les détails de chaque opération.
Le chemin complet des fichiers copiés est enregistré de manière unique dans le fichier `~/.local/share/scripts-bash/uninstall-list`.
`check_domain_cert`, `check_sha256`, `check_smart`, `convertMKV`, `generate_playlist_fp`,
`mkv_extract`, `png2jpg`, `podcast_convertImage`, `ssh-add-config`, `sshconnect`,
`trierPhotos`, `update_bullseye2buster`, `updateall`, `ytdll`
## Documentation
Le dossier `local/share/doc` contient la documentation de chaque script.
Une fois installé, chaque script documenté dispose d'une page man :
Le dossier `local/share/man/man1` contient la documentation de chaque script au format MAN.
```bash
man castopod_update
man verif-desktop
# etc.
```
Le fichier [DEVELOPER.md](DEVELOPER.md) contient le guide de développement : workflow, architecture, et conventions du projet.
Le dossier [`local/share/doc/`](local/share/doc/scripts-bash/) contient les sources de documentation au format Markdown.
## Désinstallation
Le script `uninstall.sh` permet de supprimer tous les fichiers précédemment copiés avec le script `install.sh`, en se basant sur le fichier utilisateur `~/.local/share/scripts-bash/uninstall-list`.
```bash
make uninstall
```
# Licence
## Pour les développeurs
Voir [DEVELOPER.md](DEVELOPER.md).
## Licence
Ce projet est distribué sous licence [EUPL v1.2][eupl] (Licence Publique de l'Union européenne) par Cédrix.
-153
View File
@@ -1,153 +0,0 @@
#!/bin/bash
set -uo pipefail
# Script Bash - install.sh
# Auteur : Cédric Abonnel
# Description : Script d'installation des exécutables dans le répertoire '~/.local'
# Vérification du répertoire de travail (sécurité point 3)
[[ ! -d "local/bin" ]] && { echo "Erreur : lancer depuis la racine du projet scripts-bash"; exit 1; }
log_dir="${XDG_STATE_HOME:-$HOME/.local/state}/scripts-bash"
mkdir -p "$log_dir"
log_file="${log_dir}/a5l-scripts_bash-$(date '+%Y%m%d-%H%M%S')-$$.log"
error() {
local msg="$1"
log "ERREUR: $msg"
echo "Erreur: $msg"
exit 1
}
log() {
if [ -n "$1" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - $$ - $1" >> "$log_file"
echo "$1"
fi
}
create_dir() {
log "Tentative de création du dossier $1"
if [ ! -d "$1" ]; then
mkdir -p "$1" || error "Impossible de créer le répertoire $1"
log " _ Le répertoire $1 a été créé."
else
log " _ Le répertoire $1 existe déjà."
fi
}
add_uninstall() {
local uninstall_list="${XDG_DATA_HOME:-$HOME/.local/share}/scripts-bash/uninstall-list"
mkdir -p "$(dirname "$uninstall_list")"
test -f "${uninstall_list}" || touch "${uninstall_list}"
local fichier_a_supprimer="$1"
# -F : chaîne fixe, pas regex — le '.' dans les chemins ne doit pas être un wildcard
if ! grep -qF "$fichier_a_supprimer" "$uninstall_list"; then
echo "$fichier_a_supprimer" >> "$uninstall_list"
log "- Le fichier '$fichier_a_supprimer' ajouté à la liste de fichiers installés"
fi
}
# Idempotent : n'ajoute la ligne dans ~/.bashrc que si elle n'y est pas déjà
add_to_bashrc() {
local line="$1"
if ! grep -qF "$line" ~/.bashrc; then
echo "$line" >> ~/.bashrc
return 0
fi
return 1
}
process_deployment_files() {
local destination="$1"
local source="$2"
local file_desc="$3"
log "### Déploiement des fichiers pour $destination"
create_dir "$destination"
log "Vérification de l'existence de '$file_desc'"
[ ! -e "$file_desc" ] && error "Le fichier '$file_desc' n'existe pas. Votre dépôt Git local n'est pas complet."
log "Copie des fichiers listés dans $file_desc."
mapfile -t fileslist_local < "$file_desc"
for file in "${fileslist_local[@]}"; do
# Rejet des traversées de chemin et noms absolus
[[ "$file" == *"/"* ]] && error "Nom de fichier invalide (chemin interdit) : '$file'"
local file_type file_dest cp_out
file_type=$(file -b "$source/$file")
if [[ "$file_type" == *"Bourne-Again shell script"* ]]; then
log "$file est un fichier Bash."
file_dest="${file%.*}"
log "Nom de fichier sans extension : $file_dest"
else
file_dest="${file}"
fi
# Capture séparée sortie/statut : pas de pipe qui masquerait les erreurs de cp
if ! cp_out=$(cp -v "$source/$file" "$destination/$file_dest" 2>&1); then
error "Échec de la copie de '$file' vers '$destination/$file_dest' : $cp_out"
fi
log "- $cp_out"
add_uninstall "$destination/$file_dest"
done
log "Les fichiers du dépôt Git local ont été copiés vers $destination avec succès."
}
purge_old_logs() {
find "$log_dir" -type f -name "a5l-*.log" -mtime +10 -exec rm {} \;
}
log "Debut du script"
purge_old_logs
declare -a SRCS=(
"local/share/ytdll"
"local/share/ytdll/lib"
"local/share/doc/scripts-bash"
"local/share/man/man1"
"local/bin"
)
declare -a DSTS=(
"$HOME/.local/share/ytdll"
"$HOME/.local/share/ytdll/lib"
"$HOME/.local/share/doc/scripts-bash"
"$HOME/.local/share/man/man1"
"$HOME/.local/bin"
)
declare -a DESCS=(
".config/files_local-share-ytdll"
".config/files_local-share-ytdll-lib"
".config/files_local-share-doc"
".config/files_local-share-man"
".config/files_local-bin"
)
for i in "${!SRCS[@]}"; do
log "## Debut du traitement pour ${DSTS[$i]}"
process_deployment_files "${DSTS[$i]}" "${SRCS[$i]}" "${DESCS[$i]}"
done
# Ajout de ~/.local/share/man au MANPATH (idempotent, sans source inutile)
manpath_parent="$HOME/.local/share/man"
if [[ ! ":$(manpath):" == *":$manpath_parent:"* ]]; then
manpath_line='export MANPATH="$(manpath):'"$manpath_parent"'"'
if add_to_bashrc "$manpath_line"; then
log " $manpath_parent ajouté au MANPATH dans ~/.bashrc. Rechargez votre terminal pour appliquer."
fi
fi
# Ajout de ~/.local/bin au PATH (idempotent, sans source inutile)
bin_dir="$HOME/.local/bin"
if [[ ! ":$PATH:" == *":$bin_dir:"* ]]; then
path_line='export PATH="$PATH:'"$bin_dir"'"'
if add_to_bashrc "$path_line"; then
log " $bin_dir ajouté au PATH dans ~/.bashrc. Rechargez votre terminal pour appliquer."
fi
fi
log "## Fin du script. Bonne continuation."
-94
View File
@@ -1,94 +0,0 @@
#!/bin/bash
set -uo pipefail
# Script Bash - prep.sh
# Auteur : Cédric Abonnel
# Description : Prépare les fichiers de DOC et listing.
# Vérification du répertoire de travail
[[ ! -d "local/bin" ]] && { echo "Erreur : lancer depuis la racine du projet scripts-bash"; exit 1; }
# Point 1 : log_dir créé immédiatement, avant tout appel à log()
log_dir="${XDG_STATE_HOME:-$HOME/.local/state}/scripts-bash"
mkdir -p "$log_dir"
log_file="${log_dir}/a5l-scripts_bash_prep-$(date '+%Y%m%d-%H%M%S')-$$.log"
error() {
local error_message="$1"
log "ERREUR: $error_message"
echo "Erreur: $error_message"
exit 1
}
# Point 2 : garde sur $1 vide
log() {
if [ -n "$1" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - $$ - $1" >> "$log_file"
echo "$1"
fi
}
create_dir() {
log "Tentative de création du dossier $1"
if [ ! -d "$1" ]; then
mkdir -p "$1" || error "Impossible de créer le répertoire $1"
log " _ Le répertoire $1 a été créé."
else
log " _ Le répertoire $1 existe déjà."
fi
}
# Point 3 : find remplace ls (robuste aux espaces et à la locale)
list_files() {
local dir="$1"
local dest="$2"
log "Lister les fichiers présents dans $dir"
find "$dir" -maxdepth 1 -mindepth 1 -type f -exec basename {} \; | sort > "$dest"
}
log "Début du script"
list_files "local/bin" ".config/files_local-bin"
source_dir="local/share/doc/scripts-bash"
destination_dir="local/share/man/man1"
create_dir "$destination_dir"
list_files "$source_dir" ".config/files_local-share-doc"
log "Créer les pages MAN"
if ! command -v pandoc &> /dev/null; then
log "Pandoc n'est pas installé."
if [ -x "$(command -v apt)" ]; then
log "Installation de Pandoc via APT..."
sudo apt update && sudo apt install -y pandoc
elif [ -x "$(command -v dnf)" ]; then
log "Installation de Pandoc via DNF..."
sudo dnf install -y pandoc
elif [ -x "$(command -v yum)" ]; then
log "Installation de Pandoc via YUM..."
sudo yum install -y pandoc
else
error "Gestionnaire de paquets non pris en charge. Installez Pandoc manuellement."
fi
command -v pandoc &> /dev/null || error "L'installation de Pandoc a échoué."
log "Pandoc installé avec succès."
fi
# Points 4 et 5 : lecture directe du fichier généré, erreur si source absente
mapfile -t fileslist_local < ".config/files_local-share-doc"
for file in "${fileslist_local[@]}"; do
new_name="${file%.*}"
[ ! -f "$source_dir/$file" ] && error "Fichier source introuvable : $source_dir/$file"
pandoc -s "$source_dir/$file" -t man -o "$destination_dir/$new_name" \
|| error "Impossible de créer la page man '$destination_dir/$new_name' depuis '$source_dir/$file'"
log "Page MAN créée : $destination_dir/$new_name"
done
list_files "local/share/man/man1" ".config/files_local-share-man"
list_files "local/share/ytdll" ".config/files_local-share-ytdll"
list_files "local/share/ytdll/lib" ".config/files_local-share-ytdll-lib"
log "Fin du script."
-20
View File
@@ -1,20 +0,0 @@
#!/bin/bash
# Chemin du fichier uninstall-list
uninstall_list_file="${XDG_DATA_HOME:-$HOME/.local/share}/scripts-bash/uninstall-list"
# Vérifie si le fichier uninstall-list existe
if [ -e $uninstall_list_file ]; then
# Parcourt le fichier ligne par ligne
while IFS= read -r file; do
if [ -e "$file" ]; then
# Supprime le fichier
rm -v "$file"
fi
done < "$uninstall_list_file"
rm -v "$uninstall_list_file"
else
echo "Le fichier $uninstall_list_file n'existe pas."
fi