Distribuer l'outil comme un binaire Go autonome
serve.py supposait Python installé et une commande tapée dans un terminal depuis le dossier du dépôt. L'objectif ici : poser l'exécutable et son planning dans un dossier synchronisé, et les retrouver sur n'importe quelle machine sans rien installer. Le binaire embarque l'interface, expose les mêmes routes sur le même format, et cherche son projets.json à côté de lui. Compilé avec CGO_ENABLED=0, il ne dépend d'aucune bibliothèque système, pas même de la glibc ; build.sh produit les cinq plateformes depuis une seule machine. Le front est inchangé : les modules ES sont embarqués et servis tels quels, et --dev les sert depuis le disque pour développer sans recompiler. Deux ajustements dictés par le double-clic, où aucun drapeau ne peut être passé : le port se cherche à partir de 8000 s'il est occupé, et le fichier de données est résolu depuis l'exécutable et non depuis le répertoire courant. La décision 3 est rectifiée au passage : elle affirmait à tort que la File System Access API ne fonctionne pas depuis file://. Vérification faite, c'est CORS sur les modules ES qui ferme cette voie, pas la sécurité de l'API. serve.py est supprimé, le binaire l'ayant remplacé en usage réel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
84
README.md
84
README.md
@@ -9,26 +9,63 @@ checklists. Une phase représente plusieurs semaines ou plusieurs mois de travai
|
||||
|
||||
## Démarrer
|
||||
|
||||
Récupérer le binaire de sa plateforme, le poser dans un dossier avec son planning, et le
|
||||
lancer — par un double-clic ou en ligne de commande :
|
||||
|
||||
```sh
|
||||
python3 serve.py
|
||||
./frise
|
||||
```
|
||||
|
||||
Puis ouvrir <http://localhost:8000>. Aucune installation, aucune dépendance, aucune étape de
|
||||
compilation — ni côté Python (bibliothèque standard uniquement) ni côté navigateur (JavaScript
|
||||
vanilla en modules ES natifs).
|
||||
Le navigateur s'ouvre tout seul. **Rien à installer** : l'interface est embarquée dans
|
||||
l'exécutable, qui ne dépend d'aucune bibliothèque système — pas même de la glibc. Il tourne tel
|
||||
quel sur n'importe quelle distribution, et sur une machine sans Python ni Node.
|
||||
|
||||
Par défaut, le planning est le fichier `projets.json` **posé à côté de l'exécutable**. C'est ce
|
||||
qui permet de déposer les deux dans un dossier synchronisé (Dropbox, Nextcloud, Syncthing) et de
|
||||
retrouver son outil et ses données sur n'importe quelle machine.
|
||||
|
||||
```
|
||||
📁 Mon dossier synchronisé
|
||||
├── frise ← l'exécutable
|
||||
└── projets.json ← le planning
|
||||
```
|
||||
|
||||
Options :
|
||||
|
||||
```sh
|
||||
python3 serve.py --port 9000 # changer le port
|
||||
python3 serve.py --data data/exemple.json # ouvrir un autre fichier de données
|
||||
./frise --port 9000 # imposer un port (sinon : le premier libre à partir de 8000)
|
||||
./frise --data ~/plannings/2027.json # ouvrir un autre fichier
|
||||
./frise --no-browser # ne pas ouvrir le navigateur
|
||||
```
|
||||
|
||||
Au premier lancement, le planning est vide. Pour découvrir l'outil sur des données
|
||||
réalistes :
|
||||
Au premier lancement, le planning est vide et aucun fichier n'est créé tant qu'on n'a rien
|
||||
saisi. Pour découvrir l'outil sur des données réalistes, copier `data/exemple.json` en
|
||||
`projets.json` à côté de l'exécutable.
|
||||
|
||||
### Compiler soi-même
|
||||
|
||||
```sh
|
||||
cp data/exemple.json data/projets.json
|
||||
./build.sh # les cinq plateformes, dans dist/
|
||||
./build.sh local # seulement la machine courante
|
||||
```
|
||||
|
||||
Il faut [Go](https://go.dev) 1.22 ou plus récent, et rien d'autre : aucune dépendance externe,
|
||||
aucun `vendor/`. Les binaires des trois systèmes se produisent depuis une seule machine, sans
|
||||
intégration continue ni SDK tiers.
|
||||
|
||||
### Développer
|
||||
|
||||
```sh
|
||||
go run . --dev
|
||||
```
|
||||
|
||||
Le mode `--dev` sert `index.html`, `css/` et `js/` **depuis le disque** plutôt que depuis le
|
||||
binaire : un simple rafraîchissement suffit à voir ses modifications, sans recompiler. Il lit
|
||||
alors `data/projets.json`, comme avant.
|
||||
|
||||
```sh
|
||||
go test ./... # le serveur
|
||||
node --test tests/ # le modèle métier
|
||||
```
|
||||
|
||||
## Prise en main
|
||||
@@ -131,14 +168,20 @@ Tout tient dans un fichier JSON, `data/projets.json`, décrit dans
|
||||
parlants (`site-web`, `cadrage`) plutôt que des UUID : il reste éditable à la main et lisible dans un
|
||||
diff git.
|
||||
|
||||
À chaque sauvegarde, le serveur copie la version précédente dans `data/backups/`, horodatée.
|
||||
À chaque sauvegarde, le serveur copie la version précédente dans un dossier `backups/` voisin du
|
||||
planning, horodatée.
|
||||
|
||||
Le planning n'est **pas versionné** : `.gitignore` exclut `data/projets.json`, ce dépôt ne contenant
|
||||
Le planning n'est **pas versionné** : `.gitignore` exclut `projets.json`, ce dépôt ne contenant
|
||||
que le code. Seul `data/exemple.json` y figure, comme jeu de démonstration.
|
||||
|
||||
**Pour synchroniser plusieurs machines**, placer le dossier du projet dans un espace synchronisé
|
||||
(Syncthing, Drive). L'option `--data` ne permet pas de pointer ailleurs : le serveur refuse un
|
||||
fichier situé hors de son propre dossier.
|
||||
**Pour synchroniser plusieurs machines**, déposer l'exécutable et son `projets.json` dans un
|
||||
espace synchronisé. L'option `--data` accepte n'importe quel chemin, le planning peut donc aussi
|
||||
vivre ailleurs que le binaire.
|
||||
|
||||
Deux frictions propres à ce mode de distribution, qui touchent tout exécutable et pas seulement
|
||||
celui-ci : le bit d'exécution n'est pas toujours préservé par la synchronisation (`chmod +x frise`
|
||||
une fois par machine), et un binaire non signé déclenche un avertissement au premier lancement —
|
||||
SmartScreen sous Windows, Gatekeeper sous macOS.
|
||||
|
||||
L'outil ne gère pas les conflits — si deux machines modifient le planning en même temps, la dernière
|
||||
écriture l'emporte. Les sauvegardes horodatées de `data/backups/` sont le filet de sécurité.
|
||||
@@ -146,18 +189,21 @@ L'outil ne gère pas les conflits — si deux machines modifient le planning en
|
||||
## Tests
|
||||
|
||||
```sh
|
||||
node --test
|
||||
node --test # la logique métier
|
||||
go test ./... # le serveur
|
||||
```
|
||||
|
||||
Couvre la logique métier : validation des dates, bornes d'un projet, calcul de dérive, génération des
|
||||
identifiants, normalisation et filtrage des tags. Aucune dépendance, le lanceur de tests intégré à
|
||||
Node suffit.
|
||||
Côté navigateur : validation des dates, bornes d'un projet, calcul de dérive, génération des
|
||||
identifiants, normalisation et filtrage des tags. Côté serveur : lecture et écriture du planning,
|
||||
refus des corps invalides, rotation des sauvegardes, écriture atomique, résolution du chemin de
|
||||
données. Aucune dépendance de part ni d'autre, les lanceurs intégrés à Node et à Go suffisent.
|
||||
|
||||
## Organisation du code
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---|---|
|
||||
| `serve.py` | Sert les fichiers statiques, expose `GET`/`PUT` sur `/api/data`, écrit les sauvegardes |
|
||||
| `main.go` | Sert l'interface embarquée, expose `GET`/`PUT` sur `/api/data`, écrit les sauvegardes |
|
||||
| `build.sh` | Compile les binaires des cinq plateformes dans `dist/` |
|
||||
| `js/model.js` | Données et règles métier : CRUD, validation, bornes, référence, dérive, tags |
|
||||
| `js/storage.js` | Dialogue avec le serveur, sauvegarde debouncée, indicateur d'état |
|
||||
| `js/timeline.js` | Rendu de la frise : échelle, couloirs, barres, jalons, pli/dépli |
|
||||
|
||||
Reference in New Issue
Block a user