Fix linter issues and test failures
- Fix spelling: cancelled → canceled, cancelling → canceling - Remove unused error return from performFlush() function - Check cmd.Help() error return in search.go - Fix file permissions in gitignore.go (0644 → 0600) - Update tests to match performFlush signature change - Remove unused os import from flush_manager.go
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -165,7 +165,7 @@ func applyFixes(result doctorResult) {
|
|||||||
|
|
||||||
response = strings.TrimSpace(strings.ToLower(response))
|
response = strings.TrimSpace(strings.ToLower(response))
|
||||||
if response != "" && response != "y" && response != "yes" {
|
if response != "" && response != "y" && response != "yes" {
|
||||||
fmt.Println("Fix cancelled.")
|
fmt.Println("Fix canceled.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ func CheckGitignore() DoctorCheck {
|
|||||||
func FixGitignore() error {
|
func FixGitignore() error {
|
||||||
gitignorePath := filepath.Join(".beads", ".gitignore")
|
gitignorePath := filepath.Join(".beads", ".gitignore")
|
||||||
|
|
||||||
// Write canonical template with standard git file permissions (world-readable)
|
// Write canonical template with secure file permissions
|
||||||
if err := os.WriteFile(gitignorePath, []byte(GitignoreTemplate), 0644); err != nil {
|
if err := os.WriteFile(gitignorePath, []byte(GitignoreTemplate), 0600); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -136,7 +135,7 @@ func (fm *FlushManager) Shutdown() error {
|
|||||||
var shutdownErr error
|
var shutdownErr error
|
||||||
|
|
||||||
fm.shutdownOnce.Do(func() {
|
fm.shutdownOnce.Do(func() {
|
||||||
// Send shutdown request FIRST (before cancelling context)
|
// Send shutdown request FIRST (before canceling context)
|
||||||
// This ensures the run() loop processes the shutdown request
|
// This ensures the run() loop processes the shutdown request
|
||||||
responseCh := make(chan error, 1)
|
responseCh := make(chan error, 1)
|
||||||
select {
|
select {
|
||||||
@@ -209,16 +208,11 @@ func (fm *FlushManager) run() {
|
|||||||
case <-fm.timerFiredCh:
|
case <-fm.timerFiredCh:
|
||||||
// Debounce timer fired - flush if dirty
|
// Debounce timer fired - flush if dirty
|
||||||
if isDirty {
|
if isDirty {
|
||||||
err := fm.performFlush(needsFullExport)
|
fm.performFlush(needsFullExport)
|
||||||
if err != nil {
|
// Clear dirty flags after flush
|
||||||
// Log error from timer-triggered flush
|
|
||||||
fmt.Fprintf(os.Stderr, "Warning: auto-flush timer failed: %v\n", err)
|
|
||||||
} else {
|
|
||||||
// Clear dirty flags after successful flush
|
|
||||||
isDirty = false
|
isDirty = false
|
||||||
needsFullExport = false
|
needsFullExport = false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
case responseCh := <-fm.flushNowCh:
|
case responseCh := <-fm.flushNowCh:
|
||||||
// Immediate flush requested
|
// Immediate flush requested
|
||||||
@@ -234,13 +228,11 @@ func (fm *FlushManager) run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform the flush
|
// Perform the flush
|
||||||
err := fm.performFlush(needsFullExport)
|
fm.performFlush(needsFullExport)
|
||||||
if err == nil {
|
// Clear dirty flags
|
||||||
// Success - clear dirty flags
|
|
||||||
isDirty = false
|
isDirty = false
|
||||||
needsFullExport = false
|
needsFullExport = false
|
||||||
}
|
responseCh <- nil
|
||||||
responseCh <- err
|
|
||||||
|
|
||||||
case req := <-fm.shutdownCh:
|
case req := <-fm.shutdownCh:
|
||||||
// Shutdown requested
|
// Shutdown requested
|
||||||
@@ -249,16 +241,15 @@ func (fm *FlushManager) run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform final flush if dirty
|
// Perform final flush if dirty
|
||||||
var err error
|
|
||||||
if isDirty {
|
if isDirty {
|
||||||
err = fm.performFlush(needsFullExport)
|
fm.performFlush(needsFullExport)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.responseCh <- err
|
req.responseCh <- nil
|
||||||
return // Exit goroutine
|
return // Exit goroutine
|
||||||
|
|
||||||
case <-fm.ctx.Done():
|
case <-fm.ctx.Done():
|
||||||
// Context cancelled (shouldn't normally happen)
|
// Context canceled (shouldn't normally happen)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,12 +257,12 @@ func (fm *FlushManager) run() {
|
|||||||
|
|
||||||
// performFlush executes the actual flush operation.
|
// performFlush executes the actual flush operation.
|
||||||
// Called only from the run() goroutine, so no concurrency issues.
|
// Called only from the run() goroutine, so no concurrency issues.
|
||||||
func (fm *FlushManager) performFlush(fullExport bool) error {
|
func (fm *FlushManager) performFlush(fullExport bool) {
|
||||||
// Check if store is still active
|
// Check if store is still active
|
||||||
storeMutex.Lock()
|
storeMutex.Lock()
|
||||||
if !storeActive {
|
if !storeActive {
|
||||||
storeMutex.Unlock()
|
storeMutex.Unlock()
|
||||||
return nil // Store closed, nothing to do
|
return // Store closed, nothing to do
|
||||||
}
|
}
|
||||||
storeMutex.Unlock()
|
storeMutex.Unlock()
|
||||||
|
|
||||||
@@ -281,6 +272,4 @@ func (fm *FlushManager) performFlush(fullExport bool) error {
|
|||||||
forceDirty: true, // We know we're dirty (we wouldn't be here otherwise)
|
forceDirty: true, // We know we're dirty (we wouldn't be here otherwise)
|
||||||
forceFullExport: fullExport,
|
forceFullExport: fullExport,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,15 +437,12 @@ func TestPerformFlushErrorHandling(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// performFlush with inactive store should return nil (graceful degradation)
|
// performFlush with inactive store should handle gracefully (no return value)
|
||||||
storeMutex.Lock()
|
storeMutex.Lock()
|
||||||
storeActive = false
|
storeActive = false
|
||||||
storeMutex.Unlock()
|
storeMutex.Unlock()
|
||||||
|
|
||||||
err := fm.performFlush(false)
|
fm.performFlush(false) // Should not panic
|
||||||
if err != nil {
|
|
||||||
t.Errorf("performFlush should return nil when store inactive, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore store for cleanup
|
// Restore store for cleanup
|
||||||
storeMutex.Lock()
|
storeMutex.Lock()
|
||||||
@@ -470,16 +467,10 @@ func TestPerformFlushStoreInactive(t *testing.T) {
|
|||||||
storeActive = false
|
storeActive = false
|
||||||
storeMutex.Unlock()
|
storeMutex.Unlock()
|
||||||
|
|
||||||
// performFlush should handle this gracefully
|
// performFlush should handle this gracefully (no return value)
|
||||||
err := fm.performFlush(false)
|
fm.performFlush(false) // Should not panic
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Expected performFlush to handle inactive store gracefully, got error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = fm.performFlush(true) // Try full export too
|
fm.performFlush(true) // Try full export too - should not panic
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Expected performFlush (full) to handle inactive store gracefully, got error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore store for cleanup
|
// Restore store for cleanup
|
||||||
storeMutex.Lock()
|
storeMutex.Lock()
|
||||||
|
|||||||
@@ -41,10 +41,9 @@ Examples:
|
|||||||
// If no query provided, show help
|
// If no query provided, show help
|
||||||
if query == "" {
|
if query == "" {
|
||||||
fmt.Fprintf(os.Stderr, "Error: search query is required\n")
|
fmt.Fprintf(os.Stderr, "Error: search query is required\n")
|
||||||
// #nosec G104 -- cmd.Help() error intentionally ignored. We're already in an
|
if err := cmd.Help(); err != nil {
|
||||||
// error path (missing query) and will exit(1) regardless. Help() errors are
|
fmt.Fprintf(os.Stderr, "Error displaying help: %v\n", err)
|
||||||
// rare (I/O failures) and don't affect the outcome. See TestSearchCommand_HelpErrorHandling
|
}
|
||||||
cmd.Help()
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user