diff --git a/backend/.golangci.yml b/backend/.golangci.yml new file mode 100644 index 0000000..5572d24 --- /dev/null +++ b/backend/.golangci.yml @@ -0,0 +1,18 @@ +linters: + enable: + - gofmt + - revive + - govet + - errcheck + - staticcheck + - unused + - gosimple + +issues: + exclude-use-default: false + max-issues-per-linter: 0 + max-same-issues: 0 + +run: + timeout: 5m + tests: true diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 129d8d6..e27f612 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -24,7 +24,11 @@ func main() { if err != nil { log.Fatal(err) } - defer database.Close() + defer func() { + if err := database.Close(); err != nil { + log.Printf("Error closing database: %v", err) + } + }() // Workdir workdir := os.Getenv("NOVAMD_WORKDIR") diff --git a/backend/internal/api/handlers.go b/backend/internal/api/handlers.go index 928670c..16dc7a4 100644 --- a/backend/internal/api/handlers.go +++ b/backend/internal/api/handlers.go @@ -13,7 +13,7 @@ import ( ) func ListFiles(fs *filesystem.FileSystem) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, _ *http.Request) { files, err := fs.ListFilesRecursively() if err != nil { http.Error(w, "Failed to list files", http.StatusInternalServerError) @@ -21,7 +21,9 @@ func ListFiles(fs *filesystem.FileSystem) http.HandlerFunc { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(files) + if err := json.NewEncoder(w).Encode(files); err != nil { + http.Error(w, "Failed to encode response", http.StatusInternalServerError) + } } } @@ -35,7 +37,9 @@ func GetFileContent(fs *filesystem.FileSystem) http.HandlerFunc { } w.Header().Set("Content-Type", "text/plain") - w.Write(content) + if _, err := w.Write(content); err != nil { + http.Error(w, "Failed to write response", http.StatusInternalServerError) + } } } @@ -55,7 +59,9 @@ func SaveFile(fs *filesystem.FileSystem) http.HandlerFunc { } w.WriteHeader(http.StatusOK) - w.Write([]byte("File saved successfully")) + if _, err := w.Write([]byte("File saved successfully")); err != nil { + http.Error(w, "Failed to write response", http.StatusInternalServerError) + } } } @@ -69,7 +75,9 @@ func DeleteFile(fs *filesystem.FileSystem) http.HandlerFunc { } w.WriteHeader(http.StatusOK) - w.Write([]byte("File deleted successfully")) + if _, err := w.Write([]byte("File deleted successfully")); err != nil { + http.Error(w, "Failed to write response", http.StatusInternalServerError) + } } } @@ -90,7 +98,10 @@ func GetSettings(db *db.DB) http.HandlerFunc { settings.SetDefaults() - json.NewEncoder(w).Encode(settings) + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(settings); err != nil { + http.Error(w, "Failed to encode response", http.StatusInternalServerError) + } } } @@ -124,7 +135,9 @@ func UpdateSettings(db *db.DB) http.HandlerFunc { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(savedSettings) + if err := json.NewEncoder(w).Encode(savedSettings); err != nil { + http.Error(w, "Failed to encode response", http.StatusInternalServerError) + } } } @@ -152,12 +165,14 @@ func StageCommitAndPush(fs *filesystem.FileSystem) http.HandlerFunc { } w.WriteHeader(http.StatusOK) - w.Write([]byte("Changes staged, committed, and pushed successfully")) + if _, err := w.Write([]byte("Changes staged, committed, and pushed successfully")); err != nil { + http.Error(w, "Failed to write response", http.StatusInternalServerError) + } } } func PullChanges(fs *filesystem.FileSystem) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, _ *http.Request) { err := fs.Pull() if err != nil { http.Error(w, "Failed to pull changes: "+err.Error(), http.StatusInternalServerError) @@ -165,6 +180,8 @@ func PullChanges(fs *filesystem.FileSystem) http.HandlerFunc { } w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(map[string]string{"message": "Pulled changes from remote"}) + if err := json.NewEncoder(w).Encode(map[string]string{"message": "Pulled changes from remote"}); err != nil { + http.Error(w, "Failed to encode response", http.StatusInternalServerError) + } } } diff --git a/backend/internal/db/migrations.go b/backend/internal/db/migrations.go index d0de616..1973da6 100644 --- a/backend/internal/db/migrations.go +++ b/backend/internal/db/migrations.go @@ -48,13 +48,17 @@ func (db *DB) Migrate() error { _, err = tx.Exec(migration.SQL) if err != nil { - tx.Rollback() + if rbErr := tx.Rollback(); rbErr != nil { + return fmt.Errorf("migration %d failed: %v, rollback failed: %v", migration.Version, err, rbErr) + } return fmt.Errorf("migration %d failed: %v", migration.Version, err) } _, err = tx.Exec("INSERT INTO migrations (version) VALUES (?)", migration.Version) if err != nil { - tx.Rollback() + if rbErr := tx.Rollback(); rbErr != nil { + return fmt.Errorf("failed to update migration version: %v, rollback failed: %v", err, rbErr) + } return fmt.Errorf("failed to update migration version: %v", err) } diff --git a/backend/internal/filesystem/filesystem.go b/backend/internal/filesystem/filesystem.go index 905af1f..3e32482 100644 --- a/backend/internal/filesystem/filesystem.go +++ b/backend/internal/filesystem/filesystem.go @@ -7,8 +7,6 @@ import ( "os" "path/filepath" "strings" - - git "novamd/internal/gitutils" ) type FileSystem struct { @@ -30,7 +28,7 @@ func New(rootDir string, settings *models.Settings) *FileSystem { } if settings.Settings.GitEnabled { - fs.GitRepo = git.New( + fs.GitRepo = gitutils.New( settings.Settings.GitURL, settings.Settings.GitUser, settings.Settings.GitToken,