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 ## 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 ### Ajouter un nouveau script
1. Placer le script dans `local/bin/<nom>.sh` 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) 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/` 3. Lancer `make build` — génère la page man dans `local/share/man/man1/<nom>.1` via Pandoc
4. Committer les trois fichiers + les fichiers `.config/` mis à jour 4. Committer les trois fichiers (`local/bin/`, `local/share/doc/`, `local/share/man/`)
5. Pousser avec le remote HTTPS qui embarque le token Gitea dans l'URL 5. Pousser
### Commandes principales ### Commandes
```bash ```bash
bash prep.sh # Génère les pages man (Pandoc) et met à jour les listes .config/ make build # Développeur : génère les pages man depuis les .1.md (nécessite Pandoc)
bash install.sh # Déploie tout dans ~/.local/{bin,share/...} make install # Utilisateur : déploie tout dans ~/.local/
bash uninstall.sh # Supprime les fichiers déployés via ~/.config/a5l_scripts-bash_uninstall-list make uninstall # Supprime les fichiers installés
make clean # Supprime les pages man générées localement
``` ```
## Architecture ## 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/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 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 ecoleA/ → scripts d'administration pour déploiements école
servers/linux/ → scripts serveur Linux 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 ### 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 ### 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."
+39 -20
View File
@@ -1,42 +1,61 @@
# scripts-bash # 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. ## Installation
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.
## 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. | Commande | Description | Documentation |
`git clone https://git.abonnel.fr/cedricAbonnel/scripts-bash.git` |---|---|---|
| `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`. ### Autres scripts
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.
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. `check_domain_cert`, `check_sha256`, `check_smart`, `convertMKV`, `generate_playlist_fp`,
`mkv_extract`, `png2jpg`, `podcast_convertImage`, `ssh-add-config`, `sshconnect`,
Le chemin complet des fichiers copiés est enregistré de manière unique dans le fichier `~/.local/share/scripts-bash/uninstall-list`. `trierPhotos`, `update_bullseye2buster`, `updateall`, `ytdll`
## Documentation ## 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 ## 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. Ce projet est distribué sous licence [EUPL v1.2][eupl] (Licence Publique de l'Union européenne) par Cédrix.
[eupl]: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 [eupl]: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
-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