Fix revive style issues (bd-56)
- Fix 14 unused-parameter warnings (rename to _) - Fix 2 redefines-builtin-id (max→maxCount, min→minInt) - Fix 3 indent-error-flow issues with gofmt - Merged duplicate bd-126 into bd-116
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -177,7 +177,7 @@ func TestLibraryIntegration(t *testing.T) {
|
||||
})
|
||||
|
||||
// Test 2: Get issue
|
||||
t.Run("GetIssue", func(t *testing.T) {
|
||||
t.Run("GetIssue", func(_ *testing.T) {
|
||||
issue := h.createIssue("Get test", beads.TypeBug, 1)
|
||||
retrieved := h.getIssue(issue.ID)
|
||||
h.assertEqual(issue.Title, retrieved.Title, "title")
|
||||
@@ -185,7 +185,7 @@ func TestLibraryIntegration(t *testing.T) {
|
||||
})
|
||||
|
||||
// Test 3: Update issue
|
||||
t.Run("UpdateIssue", func(t *testing.T) {
|
||||
t.Run("UpdateIssue", func(_ *testing.T) {
|
||||
issue := h.createIssue("Update test", beads.TypeTask, 2)
|
||||
updates := map[string]interface{}{"status": beads.StatusInProgress, "assignee": "test-user"}
|
||||
h.updateIssue(issue.ID, updates)
|
||||
@@ -195,7 +195,7 @@ func TestLibraryIntegration(t *testing.T) {
|
||||
})
|
||||
|
||||
// Test 4: Add dependency
|
||||
t.Run("AddDependency", func(t *testing.T) {
|
||||
t.Run("AddDependency", func(_ *testing.T) {
|
||||
issue1 := h.createIssue("Parent task", beads.TypeTask, 1)
|
||||
issue2 := h.createIssue("Child task", beads.TypeTask, 1)
|
||||
h.addDependency(issue1.ID, issue2.ID)
|
||||
|
||||
@@ -42,7 +42,7 @@ Examples:
|
||||
bd compact --id bd-42 --force # Force compact (bypass checks)
|
||||
bd compact --stats # Show statistics
|
||||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
ctx := context.Background()
|
||||
|
||||
// Handle compact stats first
|
||||
@@ -404,7 +404,7 @@ func progressBar(current, total int) string {
|
||||
}
|
||||
|
||||
//nolint:unparam // ctx may be used in future for cancellation
|
||||
func runCompactRPC(ctx context.Context) {
|
||||
func runCompactRPC(_ context.Context) {
|
||||
if compactID != "" && compactAll {
|
||||
fmt.Fprintf(os.Stderr, "Error: cannot use --id and --all together\n")
|
||||
os.Exit(1)
|
||||
|
||||
@@ -34,7 +34,7 @@ var configSetCmd = &cobra.Command{
|
||||
Use: "set <key> <value>",
|
||||
Short: "Set a configuration value",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
// Config operations work in direct mode only
|
||||
if err := ensureDirectMode("config set requires direct database access"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
|
||||
@@ -564,47 +564,48 @@ func migrateToGlobalDaemon() {
|
||||
}
|
||||
|
||||
func stopDaemon(pidFile string) {
|
||||
if isRunning, pid := isDaemonRunning(pidFile); !isRunning {
|
||||
isRunning, pid := isDaemonRunning(pidFile)
|
||||
if !isRunning {
|
||||
fmt.Println("Daemon is not running")
|
||||
return
|
||||
} else {
|
||||
fmt.Printf("Stopping daemon (PID %d)...\n", pid)
|
||||
}
|
||||
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error finding process: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Stopping daemon (PID %d)...\n", pid)
|
||||
|
||||
if err := sendStopSignal(process); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error signaling daemon: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error finding process: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if isRunning, _ := isDaemonRunning(pidFile); !isRunning {
|
||||
fmt.Println("Daemon stopped")
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := sendStopSignal(process); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error signaling daemon: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Warning: daemon did not stop after 5 seconds, forcing termination\n")
|
||||
|
||||
// Check one more time before killing the process to avoid a race.
|
||||
for i := 0; i < 50; i++ {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if isRunning, _ := isDaemonRunning(pidFile); !isRunning {
|
||||
fmt.Println("Daemon stopped")
|
||||
return
|
||||
}
|
||||
if err := process.Kill(); err != nil {
|
||||
// Ignore "process already finished" errors
|
||||
if !strings.Contains(err.Error(), "process already finished") {
|
||||
fmt.Fprintf(os.Stderr, "Error killing process: %v\n", err)
|
||||
}
|
||||
}
|
||||
_ = os.Remove(pidFile)
|
||||
fmt.Println("Daemon killed")
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Warning: daemon did not stop after 5 seconds, forcing termination\n")
|
||||
|
||||
// Check one more time before killing the process to avoid a race.
|
||||
if isRunning, _ := isDaemonRunning(pidFile); !isRunning {
|
||||
fmt.Println("Daemon stopped")
|
||||
return
|
||||
}
|
||||
if err := process.Kill(); err != nil {
|
||||
// Ignore "process already finished" errors
|
||||
if !strings.Contains(err.Error(), "process already finished") {
|
||||
fmt.Fprintf(os.Stderr, "Error killing process: %v\n", err)
|
||||
}
|
||||
}
|
||||
_ = os.Remove(pidFile)
|
||||
fmt.Println("Daemon killed")
|
||||
}
|
||||
|
||||
func startDaemon(interval time.Duration, autoCommit, autoPush bool, logFile, pidFile string, global bool) {
|
||||
|
||||
@@ -375,7 +375,7 @@ func removeIssueFromJSONL(issueID string) error {
|
||||
|
||||
// deleteBatch handles deletion of multiple issues
|
||||
//nolint:unparam // cmd parameter required for potential future use
|
||||
func deleteBatch(cmd *cobra.Command, issueIDs []string, force bool, dryRun bool, cascade bool) {
|
||||
func deleteBatch(_ *cobra.Command, issueIDs []string, force bool, dryRun bool, cascade bool) {
|
||||
// Ensure we have a direct store when daemon lacks delete support
|
||||
if daemonClient != nil {
|
||||
if err := ensureDirectMode("daemon does not support delete command"); err != nil {
|
||||
|
||||
@@ -28,7 +28,7 @@ Example:
|
||||
bd duplicates # Show all duplicate groups
|
||||
bd duplicates --auto-merge # Automatically merge all duplicates
|
||||
bd duplicates --dry-run # Show what would be merged`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(cmd *cobra.Command, _ []string) {
|
||||
// Check daemon mode - not supported yet (merge command limitation)
|
||||
if daemonClient != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: duplicates command not yet supported in daemon mode (see bd-190)\n")
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
// Phase 1: Get or create SQLite store for import
|
||||
func getOrCreateStore(ctx context.Context, dbPath string, store storage.Storage) (*sqlite.SQLiteStorage, bool, error) {
|
||||
func getOrCreateStore(_ context.Context, dbPath string, store storage.Storage) (*sqlite.SQLiteStorage, bool, error) {
|
||||
var sqliteStore *sqlite.SQLiteStorage
|
||||
var needCloseStore bool
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ var initCmd = &cobra.Command{
|
||||
Short: "Initialize bd in the current directory",
|
||||
Long: `Initialize bd in the current directory by creating a .beads/ directory
|
||||
and database file. Optionally specify a custom issue prefix.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(cmd *cobra.Command, _ []string) {
|
||||
prefix, _ := cmd.Flags().GetString("prefix")
|
||||
quiet, _ := cmd.Flags().GetBool("quiet")
|
||||
|
||||
|
||||
@@ -84,9 +84,9 @@ func (h *listTestHelper) assertEqual(expected, actual interface{}, field string)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *listTestHelper) assertAtMost(count, max int, desc string) {
|
||||
if count > max {
|
||||
h.t.Errorf("Expected at most %d %s, got %d", max, desc, count)
|
||||
func (h *listTestHelper) assertAtMost(count, maxCount int, desc string) {
|
||||
if count > maxCount {
|
||||
h.t.Errorf("Expected at most %d %s, got %d", maxCount, desc, count)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,14 +73,14 @@ Example:
|
||||
|
||||
if jsonOutput {
|
||||
output := map[string]interface{}{
|
||||
"target_id": targetID,
|
||||
"source_ids": sourceIDs,
|
||||
"merged": len(sourceIDs),
|
||||
"dependencies_added": result.depsAdded,
|
||||
"target_id": targetID,
|
||||
"source_ids": sourceIDs,
|
||||
"merged": len(sourceIDs),
|
||||
"dependencies_added": result.depsAdded,
|
||||
"dependencies_skipped": result.depsSkipped,
|
||||
"text_references": result.textRefCount,
|
||||
"issues_closed": result.issuesClosed,
|
||||
"issues_skipped": result.issuesSkipped,
|
||||
"text_references": result.textRefCount,
|
||||
"issues_closed": result.issuesClosed,
|
||||
"issues_skipped": result.issuesSkipped,
|
||||
}
|
||||
outputJSON(output)
|
||||
} else {
|
||||
@@ -216,9 +216,8 @@ func performMerge(ctx context.Context, targetID string, sourceIDs []string) (*me
|
||||
// Ignore if dependency already exists
|
||||
if !strings.Contains(err.Error(), "UNIQUE constraint failed") {
|
||||
return nil, fmt.Errorf("failed to add dependency %s -> %s: %w", issueID, targetID, err)
|
||||
} else {
|
||||
result.depsSkipped++
|
||||
}
|
||||
result.depsSkipped++
|
||||
} else {
|
||||
result.depsAdded++
|
||||
}
|
||||
@@ -294,43 +293,43 @@ func updateMergeTextReferences(ctx context.Context, sourceIDs []string, targetID
|
||||
|
||||
// Update description
|
||||
if issue.Description != "" && re.MatchString(issue.Description) {
|
||||
if _, exists := updates["description"]; !exists {
|
||||
updates["description"] = issue.Description
|
||||
if _, exists := updates["description"]; !exists {
|
||||
updates["description"] = issue.Description
|
||||
}
|
||||
if desc, ok := updates["description"].(string); ok {
|
||||
updates["description"] = re.ReplaceAllString(desc, replacementText)
|
||||
}
|
||||
}
|
||||
if desc, ok := updates["description"].(string); ok {
|
||||
updates["description"] = re.ReplaceAllString(desc, replacementText)
|
||||
}
|
||||
}
|
||||
|
||||
// Update notes
|
||||
if issue.Notes != "" && re.MatchString(issue.Notes) {
|
||||
if _, exists := updates["notes"]; !exists {
|
||||
updates["notes"] = issue.Notes
|
||||
}
|
||||
if notes, ok := updates["notes"].(string); ok {
|
||||
updates["notes"] = re.ReplaceAllString(notes, replacementText)
|
||||
}
|
||||
if _, exists := updates["notes"]; !exists {
|
||||
updates["notes"] = issue.Notes
|
||||
}
|
||||
if notes, ok := updates["notes"].(string); ok {
|
||||
updates["notes"] = re.ReplaceAllString(notes, replacementText)
|
||||
}
|
||||
}
|
||||
|
||||
// Update design
|
||||
if issue.Design != "" && re.MatchString(issue.Design) {
|
||||
if _, exists := updates["design"]; !exists {
|
||||
updates["design"] = issue.Design
|
||||
}
|
||||
if design, ok := updates["design"].(string); ok {
|
||||
updates["design"] = re.ReplaceAllString(design, replacementText)
|
||||
}
|
||||
if _, exists := updates["design"]; !exists {
|
||||
updates["design"] = issue.Design
|
||||
}
|
||||
if design, ok := updates["design"].(string); ok {
|
||||
updates["design"] = re.ReplaceAllString(design, replacementText)
|
||||
}
|
||||
}
|
||||
|
||||
// Update acceptance criteria
|
||||
if issue.AcceptanceCriteria != "" && re.MatchString(issue.AcceptanceCriteria) {
|
||||
if _, exists := updates["acceptance_criteria"]; !exists {
|
||||
updates["acceptance_criteria"] = issue.AcceptanceCriteria
|
||||
if _, exists := updates["acceptance_criteria"]; !exists {
|
||||
updates["acceptance_criteria"] = issue.AcceptanceCriteria
|
||||
}
|
||||
if ac, ok := updates["acceptance_criteria"].(string); ok {
|
||||
updates["acceptance_criteria"] = re.ReplaceAllString(ac, replacementText)
|
||||
}
|
||||
}
|
||||
if ac, ok := updates["acceptance_criteria"].(string); ok {
|
||||
updates["acceptance_criteria"] = re.ReplaceAllString(ac, replacementText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply updates if any
|
||||
|
||||
@@ -282,13 +282,14 @@ func releaseStaleIssues(staleIssues []*StaleIssueInfo) (int, error) {
|
||||
func formatDuration(d time.Duration) string {
|
||||
if d < time.Minute {
|
||||
return fmt.Sprintf("%.0f seconds", d.Seconds())
|
||||
} else if d < time.Hour {
|
||||
return fmt.Sprintf("%.0f minutes", d.Minutes())
|
||||
} else if d < 24*time.Hour {
|
||||
return fmt.Sprintf("%.1f hours", d.Hours())
|
||||
} else {
|
||||
return fmt.Sprintf("%.1f days", d.Hours()/24)
|
||||
}
|
||||
if d < time.Hour {
|
||||
return fmt.Sprintf("%.0f minutes", d.Minutes())
|
||||
}
|
||||
if d < 24*time.Hour {
|
||||
return fmt.Sprintf("%.1f hours", d.Hours())
|
||||
}
|
||||
return fmt.Sprintf("%.1f days", d.Hours()/24)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -29,7 +29,7 @@ var syncCmd = &cobra.Command{
|
||||
This command wraps the entire git-based sync workflow for multi-device use.
|
||||
|
||||
Use --flush-only to just export pending changes to JSONL (useful for pre-commit hooks).`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(cmd *cobra.Command, _ []string) {
|
||||
ctx := context.Background()
|
||||
|
||||
message, _ := cmd.Flags().GetString("message")
|
||||
|
||||
@@ -225,9 +225,9 @@ func calculateLatencyStats(samples []time.Duration) LatencyStats {
|
||||
|
||||
n := len(sorted)
|
||||
// Calculate percentiles with defensive clamping
|
||||
p50Idx := min(n-1, n*50/100)
|
||||
p95Idx := min(n-1, n*95/100)
|
||||
p99Idx := min(n-1, n*99/100)
|
||||
p50Idx := minInt(n-1, n*50/100)
|
||||
p95Idx := minInt(n-1, n*95/100)
|
||||
p99Idx := minInt(n-1, n*99/100)
|
||||
|
||||
// Calculate average
|
||||
var sum time.Duration
|
||||
@@ -251,7 +251,7 @@ func calculateLatencyStats(samples []time.Duration) LatencyStats {
|
||||
}
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
func minInt(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ func NewServer(socketPath string, store storage.Storage) *Server {
|
||||
}
|
||||
|
||||
// Start starts the RPC server and listens for connections
|
||||
func (s *Server) Start(ctx context.Context) error {
|
||||
func (s *Server) Start(_ context.Context) error {
|
||||
if err := s.ensureSocketDir(); err != nil {
|
||||
return fmt.Errorf("failed to ensure socket directory: %w", err)
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ func deduplicateIncomingIssues(issues []*types.Issue) []*types.Issue {
|
||||
// If an error occurs partway through, some issues may be created without their references
|
||||
// being updated. This is a known limitation that requires storage layer refactoring to fix.
|
||||
// See issue bd-25 for transaction support.
|
||||
func RemapCollisions(ctx context.Context, s *SQLiteStorage, collisions []*CollisionDetail, allIssues []*types.Issue) (map[string]string, error) {
|
||||
func RemapCollisions(ctx context.Context, s *SQLiteStorage, collisions []*CollisionDetail, _ []*types.Issue) (map[string]string, error) {
|
||||
idMapping := make(map[string]string)
|
||||
|
||||
// Sync counters before remapping to avoid ID collisions
|
||||
|
||||
@@ -1524,7 +1524,7 @@ func (s *SQLiteStorage) resolveDeleteSet(ctx context.Context, tx *sql.Tx, ids []
|
||||
return ids, s.trackOrphanedIssues(ctx, tx, ids, idSet, result)
|
||||
}
|
||||
|
||||
func (s *SQLiteStorage) expandWithDependents(ctx context.Context, tx *sql.Tx, ids []string, idSet map[string]bool) ([]string, error) {
|
||||
func (s *SQLiteStorage) expandWithDependents(ctx context.Context, tx *sql.Tx, ids []string, _ map[string]bool) ([]string, error) {
|
||||
allToDelete, err := s.findAllDependentsRecursive(ctx, tx, ids)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find dependents: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user