Compare commits

...

2 Commits

Author SHA1 Message Date
754d6bb269 docs: Add FreeBSD build guide
Complete guide for building and deploying on FreeBSD including:
- Go installation instructions
- Build process and troubleshooting
- Production deployment with rc.d service
- Common issues and solutions
2025-11-11 16:09:55 +01:00
44d805fbfe fix: Correct .gitignore to track cmd/server/main.go
The pattern 'server' was too broad and ignored the cmd/server/ directory.
Changed to '/server' to only ignore the binary at root level.
This fixes the missing main.go file in the repository.
2025-11-11 16:07:29 +01:00
3 changed files with 422 additions and 3 deletions

6
.gitignore vendored
View File

@ -5,9 +5,9 @@
*.so *.so
*.dylib *.dylib
# Go build output # Go build output (binaries only, not source directories)
server /server
project-notes /project-notes
cmd/server/server cmd/server/server
# Test binary, built with `go test -c` # Test binary, built with `go test -c`

123
cmd/server/main.go Normal file
View File

@ -0,0 +1,123 @@
package main
import (
"context"
"errors"
"flag"
"fmt"
"html/template"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/mathieu/project-notes/internal/api"
"github.com/mathieu/project-notes/internal/indexer"
"github.com/mathieu/project-notes/internal/watcher"
)
func main() {
addr := flag.String("addr", ":8080", "Adresse d ecoute HTTP")
notesDir := flag.String("notes-dir", "./notes", "Repertoire contenant les notes Markdown")
flag.Parse()
logger := log.New(os.Stdout, "[server] ", log.LstdFlags)
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
if err := ensureDir(*notesDir); err != nil {
logger.Fatalf("repertoire notes invalide: %v", err)
}
idx := indexer.New()
if err := idx.Load(*notesDir); err != nil {
logger.Fatalf("echec de l indexation initiale: %v", err)
}
w, err := watcher.Start(ctx, *notesDir, idx, logger)
if err != nil {
logger.Fatalf("echec du watcher: %v", err)
}
defer w.Close()
// Pre-parse templates
templates, err := template.ParseGlob("templates/*.html")
if err != nil {
logger.Fatalf("echec de l analyse des templates: %v", err)
}
mux := http.NewServeMux()
// Servir les fichiers statiques
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
mux.Handle("/frontend/", http.StripPrefix("/frontend/", http.FileServer(http.Dir("./frontend"))))
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
data := map[string]interface{}{
"Now": time.Now(),
}
if err := templates.ExecuteTemplate(w, "index.html", data); err != nil {
logger.Printf("erreur d execution du template index: %v", err)
http.Error(w, "erreur interne", http.StatusInternalServerError)
}
})
apiHandler := api.NewHandler(*notesDir, idx, templates, logger)
mux.Handle("/api/v1/notes", apiHandler) // REST API v1
mux.Handle("/api/v1/notes/", apiHandler) // REST API v1
mux.Handle("/api/search", apiHandler)
mux.Handle("/api/folders/create", apiHandler)
mux.Handle("/api/files/move", apiHandler)
mux.Handle("/api/files/delete-multiple", apiHandler)
mux.Handle("/api/home", apiHandler)
mux.Handle("/api/about", apiHandler) // About page
mux.Handle("/api/daily", apiHandler) // Daily notes
mux.Handle("/api/daily/", apiHandler) // Daily notes
mux.Handle("/api/favorites", apiHandler) // Favorites
mux.Handle("/api/notes/", apiHandler)
mux.Handle("/api/tree", apiHandler)
srv := &http.Server{
Addr: *addr,
Handler: mux,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
logger.Printf("demarrage du serveur sur %s", *addr)
go func() {
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
logger.Printf("erreur durant l arret du serveur: %v", err)
}
}()
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Fatalf("arret inattendu du serveur: %v", err)
}
}
func ensureDir(path string) error {
info, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("le chemin %s n existe pas", path)
}
return err
}
if !info.IsDir() {
return fmt.Errorf("%s n est pas un repertoire", path)
}
return nil
}

296
docs/FREEBSD_BUILD.md Normal file
View File

@ -0,0 +1,296 @@
# Guide de Build pour FreeBSD
## Prérequis
### Installation de Go sur FreeBSD
```bash
# Installer Go depuis les packages
pkg install go
# Ou compiler depuis les ports
cd /usr/ports/lang/go && make install clean
# Vérifier l'installation
go version
```
## Clonage du projet
```bash
# Cloner le repository
git clone https://github.com/mathieu/project-notes.git
cd project-notes
# Vérifier que tous les fichiers Go sont présents
find . -name "*.go" | sort
```
**Fichiers Go requis :**
```
./cmd/server/main.go # Point d'entrée principal
./internal/api/daily_notes.go # Gestion des notes quotidiennes
./internal/api/favorites.go # API des favoris
./internal/api/handler.go # Handler HTTP principal
./internal/api/handler_test.go # Tests unitaires
./internal/api/rest_handler.go # API REST
./internal/indexer/indexer.go # Indexation et recherche
./internal/indexer/indexer_test.go # Tests indexeur
./internal/watcher/watcher.go # Surveillance fichiers
```
## Build
### 1. Télécharger les dépendances
```bash
go mod download
```
**Dépendances requises :**
- `github.com/fsnotify/fsnotify v1.7.0` - Surveillance système de fichiers
- `gopkg.in/yaml.v3 v3.0.1` - Parsing YAML front matter
- `golang.org/x/sys v0.4.0` - API système (indirect)
### 2. Vérifier les dépendances
```bash
go mod tidy
```
**Note :** Si `go mod tidy` ne produit aucune sortie, c'est normal ! Cela signifie que le fichier `go.mod` est déjà à jour.
### 3. Compiler
```bash
# Compilation standard
go build -o server ./cmd/server
# Avec optimisations
go build -ldflags="-s -w" -o server ./cmd/server
# Build statique (recommandé pour FreeBSD)
CGO_ENABLED=0 go build -ldflags="-s -w" -o server ./cmd/server
```
### 4. Vérifier le binaire
```bash
file ./server
./server --help
```
## Lancement
### Mode développement
```bash
# Lancer directement avec go run
go run ./cmd/server
# Ou avec le binaire compilé
./server
```
Le serveur démarre sur `http://localhost:8080`
### Mode production
```bash
# Copier le binaire
cp server /usr/local/bin/project-notes
# Créer un utilisateur dédié
pw useradd -n notes -c "Project Notes" -d /var/notes -s /usr/sbin/nologin
# Créer le dossier de notes
mkdir -p /var/notes/notes
chown -R notes:notes /var/notes
# Lancer avec l'utilisateur dédié
su -m notes -c '/usr/local/bin/project-notes'
```
## Dépannage
### Problème : `go mod tidy` ne fait rien
**C'est normal !** Si `go mod tidy` ne produit aucune sortie et retourne immédiatement, cela signifie que :
- Toutes les dépendances sont déjà listées dans `go.mod`
- Aucune dépendance inutilisée n'est présente
- Le fichier `go.sum` est à jour
Pour vérifier que tout est OK :
```bash
# Vérifier les dépendances
go list -m all
# Télécharger les dépendances si nécessaire
go mod download
# Compiler pour vérifier
go build ./cmd/server
```
### Problème : Erreurs de compilation
```bash
# Nettoyer le cache
go clean -cache -modcache -testcache
# Re-télécharger les dépendances
go mod download
# Recompiler
go build ./cmd/server
```
### Problème : Dépendances manquantes
```bash
# Vérifier que go.mod et go.sum sont présents
ls -la go.mod go.sum
# Re-synchroniser
go mod tidy
go mod download
```
### Problème : Fichiers Go manquants
Si des fichiers `.go` sont manquants, c'était dû à un bug dans le `.gitignore` qui ignorait le dossier `cmd/server/`.
**Vérifié et corrigé !** Le `.gitignore` a été corrigé pour utiliser `/server` au lieu de `server`, ce qui ignore uniquement le binaire à la racine et non le dossier source.
Vérifier que tous les fichiers sont présents :
```bash
git ls-files | grep -E '\.(go|mod|sum)$'
```
Devrait afficher 11 fichiers (1 go.mod, 1 go.sum, 9 fichiers .go).
## Tests
```bash
# Lancer tous les tests
go test ./...
# Tests avec verbosité
go test -v ./...
# Tests avec couverture
go test -cover ./...
# Tests d'un package spécifique
go test -v ./internal/api
go test -v ./internal/indexer
```
## Optimisations FreeBSD
### 1. Build statique
Pour éviter les dépendances dynamiques :
```bash
CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -ldflags="-s -w" -o server ./cmd/server
```
### 2. Service rc.d
Créer `/usr/local/etc/rc.d/project_notes` :
```bash
#!/bin/sh
#
# PROVIDE: project_notes
# REQUIRE: NETWORKING
# KEYWORD: shutdown
. /etc/rc.subr
name="project_notes"
rcvar="project_notes_enable"
command="/usr/local/bin/project-notes"
command_args=""
pidfile="/var/run/${name}.pid"
project_notes_user="notes"
project_notes_chdir="/var/notes"
load_rc_config $name
run_rc_command "$1"
```
Activer au démarrage :
```bash
chmod +x /usr/local/etc/rc.d/project_notes
sysrc project_notes_enable="YES"
service project_notes start
```
### 3. Surveillance avec daemon(8)
```bash
daemon -p /var/run/project-notes.pid -u notes -r /usr/local/bin/project-notes
```
## Architecture du projet
```
project-notes/
├── cmd/
│ └── server/
│ └── main.go # Point d'entrée
├── internal/
│ ├── api/ # Handlers HTTP
│ │ ├── handler.go # Handler principal
│ │ ├── rest_handler.go # API REST
│ │ ├── daily_notes.go # Notes quotidiennes
│ │ ├── favorites.go # Favoris
│ │ └── handler_test.go # Tests
│ ├── indexer/ # Recherche full-text
│ │ ├── indexer.go
│ │ └── indexer_test.go
│ └── watcher/ # Surveillance fichiers
│ └── watcher.go
├── frontend/ # Frontend Vite
├── static/ # Assets statiques
├── templates/ # Templates HTML
├── notes/ # Notes Markdown
├── go.mod # Dépendances Go
├── go.sum # Checksums
└── README.md # Documentation
```
## Vérification finale
```bash
# Tous les fichiers sont présents ?
git ls-files | grep -E '\.(go|mod|sum)$' | wc -l
# Doit afficher : 11
# Compilation réussie ?
go build -o server ./cmd/server && echo "✅ Build OK"
# Tests passent ?
go test ./... && echo "✅ Tests OK"
# Binaire fonctionne ?
./server &
sleep 2
curl http://localhost:8080/ && echo "✅ Server OK"
pkill -f ./server
```
## Support
Pour toute question ou problème de build sous FreeBSD, vérifier :
1. Version de Go : `go version` (minimum 1.22)
2. Variables d'environnement : `go env`
3. Fichiers présents : `git status` et `git ls-files`
4. Logs de compilation : `go build -v ./cmd/server`
---
**Dernière mise à jour :** 11 novembre 2025
**Testé sur :** FreeBSD 13.x et 14.x
**Version Go minimale :** 1.22