Skip to content

Commit e090943

Browse files
committed
fix
1 parent 653219a commit e090943

File tree

2 files changed

+85
-62
lines changed

2 files changed

+85
-62
lines changed

tools/flakeguard/cmd/create_jira_tickets.go

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ import (
1818
)
1919

2020
var (
21-
csvPath string
22-
dryRun bool
23-
jiraProject string
24-
jiraIssueType string
25-
jiraSearchLabel string // defaults to "flaky_test" if empty
21+
csvPath string
22+
dryRun bool
23+
jiraProject string
24+
jiraIssueType string
25+
jiraSearchLabel string // defaults to "flaky_test" if empty
26+
flakyTestJSONDBPath string
2627
)
2728

2829
// CreateTicketsCmd is the Cobra command that runs a Bubble Tea TUI for CSV data,
@@ -60,7 +61,7 @@ ticket in a text-based UI. Press 'y' to confirm creation, 'n' to skip,
6061
}
6162

6263
// 2) Load local DB (test -> known Jira ticket)
63-
db, err := localdb.LoadDB()
64+
db, err := localdb.LoadDBWithPath(flakyTestJSONDBPath)
6465
if err != nil {
6566
log.Warn().Err(err).Msg("Failed to load local DB; continuing with empty DB.")
6667
db = localdb.NewDB()
@@ -149,11 +150,11 @@ ticket in a text-based UI. Press 'y' to confirm creation, 'n' to skip,
149150
fm := finalModel.(model)
150151

151152
// 9) Save local DB with any new knowledge
152-
if err := localdb.SaveDB(fm.LocalDB); err != nil {
153+
if err := fm.LocalDB.Save(); err != nil {
153154
log.Error().Err(err).Msg("Failed to save local DB")
154155
} else {
155156
// Let the user know we updated it
156-
fmt.Printf("Local DB has been updated at: %s\n", localdb.FilePath())
157+
fmt.Printf("Local DB has been updated at: %s\n", fm.LocalDB.FilePath())
157158
}
158159

159160
// 10) Write remaining CSV
@@ -174,6 +175,7 @@ func init() {
174175
CreateTicketsCmd.Flags().StringVar(&jiraProject, "jira-project", "", "Jira project key (or env JIRA_PROJECT_KEY)")
175176
CreateTicketsCmd.Flags().StringVar(&jiraIssueType, "jira-issue-type", "Task", "Type of Jira issue (Task, Bug, etc.)")
176177
CreateTicketsCmd.Flags().StringVar(&jiraSearchLabel, "jira-search-label", "", "Jira label to filter existing tickets (default: flaky_test)")
178+
CreateTicketsCmd.Flags().StringVar(&flakyTestJSONDBPath, "flaky-test-json-db-path", "", "Path to the flaky test JSON database (default: ~/.flaky_tes_db.json)")
177179
}
178180

179181
// -------------------------------------------------------------------------------------
@@ -346,34 +348,29 @@ func updateNormalMode(m model, msg tea.KeyMsg) (tea.Model, tea.Cmd) {
346348
}
347349
t := m.tickets[m.index]
348350

351+
// Always allow 'q' (quit) and 'e' (enter existing ticket)
349352
switch msg.String() {
350353
case "q", "esc", "ctrl+c":
351354
return updateQuit(m)
355+
case "e":
356+
m.mode = "promptExisting"
357+
m.inputValue = ""
358+
return m, nil
352359
}
353360

354-
// If invalid, we cannot create a new ticket, so no 'y' prompt:
355-
if !t.Valid {
356-
// Let user skip or do other actions
361+
// If ticket is valid, allow create ('c') and skip ('n')
362+
if t.Valid {
357363
switch msg.String() {
358-
// user might press anything => skip
359-
default:
364+
case "c":
365+
return updateConfirm(m)
366+
case "n":
360367
return updateSkip(m)
361368
}
362-
}
363-
364-
// If valid, handle normal flow
365-
switch msg.String() {
366-
case "y":
367-
return updateConfirm(m)
368-
case "n":
369-
return updateSkip(m)
370-
case "e":
371-
// always prompt to enter or overwrite
372-
m.mode = "promptExisting"
373-
m.inputValue = ""
374369
return m, nil
375370
}
376-
return m, nil
371+
372+
// For invalid tickets, default to skipping if any other key is pressed.
373+
return updateSkip(m)
377374
}
378375

379376
func updatePromptExisting(m model, msg tea.KeyMsg) (tea.Model, tea.Cmd) {
@@ -491,8 +488,9 @@ func (m model) View() string {
491488
}
492489

493490
// 2) Summary & Description
494-
sum := summaryStyle.Render("Summary:\n") + t.Summary
495-
descHeader := descHeaderStyle.Render("\nDescription:\n")
491+
sum := summaryStyle.Render("Summary:")
492+
sumBody := descBodyStyle.Render(t.Summary)
493+
descHeader := descHeaderStyle.Render("\nDescription:")
496494
descBody := descBodyStyle.Render(t.Description)
497495

498496
// 3) Existing ticket line
@@ -527,39 +525,40 @@ func (m model) View() string {
527525
helpLine := ""
528526
// Cases:
529527
// A) If invalid:
530-
// B) If valid & there's an existing ticket => [n] to next, [e] to update existing ticket ID, [q] to quit.
531-
// C) If valid & no existing => [y] to confirm, [n] to skip, [e] to enter existing ticket, [q] to quit (with DRY RUN text if needed).
528+
// B) If valid & there's an existing ticket => [n] to next, [e] to update ticket id, [q] to quit.
529+
// C) If valid & no existing => [c] to create ticket, [n] to skip, [e] to enter existing ticket, [q] to quit (with DRY RUN text if needed).
532530
if !t.Valid {
533531
if t.ExistingJiraKey != "" {
534-
helpLine = faintStyle.Render("\n[n] to next, [e] to update existing ticket ID, [q] to quit.")
532+
helpLine = faintStyle.Render("\n[n] to next, [e] to update ticket id, [q] to quit.")
535533
} else {
536534
helpLine = faintStyle.Render("\n[n] to next, [e] to add existing ticket ID, [q] to quit.")
537535
}
538536
} else {
539537
if t.ExistingJiraKey != "" {
540-
helpLine = faintStyle.Render("\n[n] to next, [e] to update existing ticket ID, [q] to quit.")
538+
helpLine = faintStyle.Render("\n[n] to next, [e] to update ticket id, [q] to quit.")
541539
} else {
542540
// if no existing ticket, the normal prompt
543541
dryRunLabel := ""
544542
if m.DryRun || m.JiraClient == nil {
545543
dryRunLabel = " (DRY RUN)"
546544
}
547545
helpLine = faintStyle.Render(
548-
fmt.Sprintf("\nPress [y] to confirm%s, [n] to skip, [e] to enter existing ticket, [q] to quit.",
546+
fmt.Sprintf("\nPress [c] to create ticket%s, [n] to skip, [e] to enter existing ticket, [q] to quit.",
549547
dryRunLabel),
550548
)
551549
}
552550
}
553551

554552
return fmt.Sprintf(
555-
"%s\n\n%s\n%s%s%s%s\n%s\n",
553+
"%s\n%s\n%s\n%s%s%s%s\n%s\n",
556554
header,
557555
sum,
556+
sumBody,
558557
descHeader,
559558
descBody,
560559
existingLine, // e.g. "Existing ticket found in jira: https://..."
561560
invalidLine, // e.g. "Cannot create ticket: Missing required..."
562-
helpLine, // e.g. "[n] to next, [e]... or "[y] to confirm..."
561+
helpLine, // e.g. "[n] to next, [e]... or "[c] to create ticket..."
563562
)
564563
}
565564

tools/flakeguard/localdb/localdb.go

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
9+
"github.com/rs/zerolog/log"
810
)
911

1012
const defaultDBFileName = ".flaky_test_db.json"
@@ -16,70 +18,91 @@ type Entry struct {
1618
JiraTicket string `json:"jira_ticket"`
1719
}
1820

19-
// DB is a simple in-memory map keyed by "pkg::testName" => Entry
21+
// DB is a simple in-memory map keyed by "pkg::testName" => Entry,
22+
// and it contains the file path used for persistence.
2023
type DB struct {
2124
data map[string]Entry
25+
path string
2226
}
2327

24-
// NewDB returns a new, empty DB.
28+
// NewDB creates a new, empty DB using the default file path.
2529
func NewDB() DB {
2630
return DB{
2731
data: make(map[string]Entry),
32+
path: getDefaultDBPath(),
33+
}
34+
}
35+
36+
// NewDBWithPath creates a new, empty DB using the provided path.
37+
// If the provided path is empty, the default path is used.
38+
func NewDBWithPath(path string) DB {
39+
if path == "" {
40+
path = getDefaultDBPath()
41+
}
42+
return DB{
43+
data: make(map[string]Entry),
44+
path: path,
2845
}
2946
}
3047

31-
// LoadDB loads the JSON file at ~/.flaky_test_db.json into a DB.
48+
// LoadDB loads the JSON file from the default path into a DB.
3249
// If the file does not exist, an empty DB is returned.
3350
func LoadDB() (DB, error) {
34-
path := getDBPath()
51+
return LoadDBWithPath("")
52+
}
53+
54+
// LoadDBWithPath loads the JSON file from the specified path into a DB.
55+
// If path is empty, the default path is used.
56+
func LoadDBWithPath(path string) (DB, error) {
57+
if path == "" {
58+
path = getDefaultDBPath()
59+
}
60+
db := DB{
61+
data: make(map[string]Entry),
62+
path: path,
63+
}
3564
if _, err := os.Stat(path); os.IsNotExist(err) {
36-
// File doesn't exist => return empty DB
37-
return NewDB(), nil
65+
// File doesn't exist => return empty DB.
66+
return db, nil
3867
}
39-
4068
f, err := os.Open(path)
4169
if err != nil {
42-
return DB{}, fmt.Errorf("failed to open local DB file: %w", err)
70+
return db, fmt.Errorf("failed to open local DB file: %w", err)
4371
}
4472
defer f.Close()
4573

46-
db := NewDB()
4774
if err := json.NewDecoder(f).Decode(&db.data); err != nil {
48-
return DB{}, fmt.Errorf("failed to decode local DB JSON: %w", err)
75+
return db, fmt.Errorf("failed to decode local DB JSON: %w", err)
4976
}
5077
return db, nil
5178
}
5279

53-
// SaveDB writes the DB contents to ~/.flaky_test_db.json in JSON format.
54-
func SaveDB(db DB) error {
55-
path := getDBPath()
56-
f, err := os.Create(path)
80+
// Save persists the DB contents to its file path in JSON format.
81+
func (db *DB) Save() error {
82+
f, err := os.Create(db.path)
5783
if err != nil {
5884
return fmt.Errorf("failed to create local DB file: %w", err)
5985
}
6086
defer f.Close()
6187

6288
enc := json.NewEncoder(f)
63-
enc.SetIndent("", " ") // optional prettify
89+
enc.SetIndent("", " ") // Optional: prettify the JSON.
6490
if err := enc.Encode(db.data); err != nil {
6591
return fmt.Errorf("failed to encode local DB to JSON: %w", err)
6692
}
6793
return nil
6894
}
6995

70-
// FilePath returns the path where the local DB is stored (e.g. ~/.flaky_test_db.json).
71-
func FilePath() string {
72-
return getDBPath()
96+
// FilePath returns the file path where the DB is stored.
97+
func (db *DB) FilePath() string {
98+
return db.path
7399
}
74100

75101
// Get retrieves the Jira ticket ID for (testPackage, testName), if it exists.
76102
func (db *DB) Get(testPackage, testName string) (string, bool) {
77103
key := makeKey(testPackage, testName)
78-
e, ok := db.data[key]
79-
if !ok {
80-
return "", false
81-
}
82-
return e.JiraTicket, true
104+
entry, exists := db.data[key]
105+
return entry.JiraTicket, exists
83106
}
84107

85108
// Set updates or inserts a record for (testPackage, testName) => jiraTicket.
@@ -92,17 +115,18 @@ func (db *DB) Set(testPackage, testName, jiraTicket string) {
92115
}
93116
}
94117

95-
// getDBPath returns the path to the local DB file in the user's home directory.
96-
func getDBPath() string {
118+
// getDefaultDBPath returns the default DB file path in the user's home directory.
119+
// If the user's home directory cannot be determined, it falls back to the current directory.
120+
func getDefaultDBPath() string {
97121
home, err := os.UserHomeDir()
98122
if err != nil {
99-
// Fallback to current dir if we cannot get home
123+
log.Warn().Msg("Failed to get user home directory; using current directory for local DB.")
100124
home = "."
101125
}
102126
return filepath.Join(home, defaultDBFileName)
103127
}
104128

105-
// makeKey is a helper to combine package+testName into a single map key.
129+
// makeKey is a helper to combine the package and test name into a single map key.
106130
func makeKey(pkg, testName string) string {
107131
return pkg + "::" + testName
108132
}

0 commit comments

Comments
 (0)