Skip to content

Commit 91140df

Browse files
Minor improvements - normalize error strings and remove dead code (#27)
* chore: error-string normalization, boundary wrapping, dead code, TOML dedup * chore: version bump
1 parent b9d8ba4 commit 91140df

6 files changed

Lines changed: 18 additions & 49 deletions

File tree

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.3.0
1+
v1.3.1

cmd/book/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ func Main() {
388388
Before: func(ctx context.Context, c *cli.Command) (context.Context, error) {
389389
if c.Args().First() != "" && markURL != "" {
390390
return ctx, cli.Exit(config.StyledError(
391-
fmt.Errorf("cannot pass URL as both --url and a positional argument")), 1)
391+
fmt.Errorf("cannot pass url as both --url and a positional argument")), 1)
392392
}
393393

394394
// use positional argument to populate markURL if flag not used
@@ -397,7 +397,7 @@ func Main() {
397397
}
398398
if markURL == "" {
399399
return ctx, cli.Exit(config.StyledError(
400-
fmt.Errorf("must pass URL as --url or argument")), 1)
400+
fmt.Errorf("must pass url as --url or argument")), 1)
401401
}
402402
return ctx, nil
403403
},

cmd/book/mark.go

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ func marks(bs *book.BookShelves, shelfName string, collectionName string, format
5151
}
5252
switch format {
5353
case "toml":
54-
wrapped := struct {
55-
Marks []catalog.SearchResult `toml:"marks"`
56-
}{deleted}
57-
return book.PrintCatalog(wrapped, format)
54+
return book.PrintCatalog(catalog.SearchResultList{Marks: deleted}, format)
5855
case "json":
5956
return book.PrintCatalog(deleted, format)
6057
default:
@@ -111,7 +108,7 @@ func editMark(bs *book.BookShelves, id, title, tags, url string, config *book.Co
111108
return err
112109
}
113110
if err := bs.VerifyUniqueURL(book.GenerateID(url), target); err != nil {
114-
return err
111+
return fmt.Errorf("verify unique url: %w", err)
115112
}
116113
}
117114

@@ -142,11 +139,7 @@ func searchMarks(query string, tags string, shelfName string, collectionName str
142139
case "json":
143140
return book.PrintCatalog(results, format)
144141
case "toml":
145-
// TOML requires a top-level map or struct, so wrap the slice.
146-
wrapped := struct {
147-
Marks []catalog.SearchResult `toml:"marks"`
148-
}{results}
149-
return book.PrintCatalog(wrapped, format)
142+
return book.PrintCatalog(catalog.SearchResultList{Marks: results}, format)
150143
default:
151144
for _, r := range results {
152145
fmt.Printf("%s %s\n", r.Title, r.URL)
@@ -163,7 +156,7 @@ func addMark(bs *book.BookShelves, URL string, tags string, shelfName string, co
163156

164157
// Ensure URL hash not in bookshelves
165158
if err := bs.VerifyUniqueURL(mark.ID, nil); err != nil {
166-
return err
159+
return fmt.Errorf("verify unique url: %w", err)
167160
}
168161

169162
// Use provided title or fetch from URL
@@ -172,7 +165,7 @@ func addMark(bs *book.BookShelves, URL string, tags string, shelfName string, co
172165
fetchedTitle, err := web.LoadWebsite(mark.URL)
173166
if err != nil {
174167
if !errors.Is(err, web.ErrTitleUnavailable) {
175-
return err
168+
return fmt.Errorf("load website: %w", err)
176169
}
177170
fetched.Unavailable = true
178171
} else {

internal/book/templates.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -96,33 +96,3 @@ var DefaultViewTemplates = map[string]ViewTemplate{
9696
"mark-get": markTemplate("To open mark:"),
9797
"mark-delete": markTemplate("To delete mark:"),
9898
}
99-
100-
// UserViewTemplates holds user-defined template overrides loaded at runtime.
101-
var UserViewTemplates = map[string]ViewTemplate{}
102-
103-
// GetTemplate merges user overrides over the default for a given key.
104-
func GetTemplate(key string) ViewTemplate {
105-
def, hasDef := DefaultViewTemplates[key]
106-
user, hasUser := UserViewTemplates[key]
107-
108-
switch {
109-
case !hasDef && !hasUser:
110-
return ViewTemplate{}
111-
case !hasUser:
112-
return def
113-
case !hasDef:
114-
return user
115-
}
116-
117-
// Overlay: user field non-empty → override default.
118-
if user.PrimaryTitle != "" {
119-
def.PrimaryTitle = user.PrimaryTitle
120-
}
121-
if user.SecondaryTitle != "" {
122-
def.SecondaryTitle = user.SecondaryTitle
123-
}
124-
if user.ListTitle != "" {
125-
def.ListTitle = user.ListTitle
126-
}
127-
return def
128-
}

internal/book/types.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ func (bs *BookShelves) VerifyUniqueURL(id string, exclude *Mark) error {
177177
continue
178178
}
179179
if m.IsDeleted() {
180-
return fmt.Errorf("URL already trashed!\n\n%s\n\nrestore it with:\nbook mark restore --shelf %s --collection %s --url %s",
180+
return fmt.Errorf("url already trashed\n\n%s\n\nrestore it with:\nbook mark restore --shelf %s --collection %s --url %s",
181181
m.FullDetail(), m.Shelf.Name, m.Collection.Name, m.URL)
182182
}
183-
return fmt.Errorf("duplicate URL Found!\n\n%s", m.FullDetail())
183+
return fmt.Errorf("duplicate url found\n\n%s", m.FullDetail())
184184
}
185185
}
186186
}
@@ -582,10 +582,10 @@ func ResolveMarkTitle(providedTitle, url string, fetched TitleFetchResult, inter
582582
// ValidateNewShelfName returns an error if name is empty or already in use.
583583
func (bs *BookShelves) ValidateNewShelfName(name string) error {
584584
if name == "" {
585-
return fmt.Errorf("HARD requirement")
585+
return fmt.Errorf("shelf name is required")
586586
}
587587
if slices.Contains(bs.ShelfNames(), name) {
588-
return fmt.Errorf("womp womp, shelf already exists")
588+
return fmt.Errorf("shelf already exists")
589589
}
590590
return nil
591591
}

internal/catalog/index.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ type SearchResult struct {
417417
Tags []string `json:"tags" toml:"tags"`
418418
}
419419

420+
// SearchResultList wraps a slice of search results so it can be serialized as
421+
// TOML, which requires a top-level map or struct.
422+
type SearchResultList struct {
423+
Marks []SearchResult `toml:"marks" json:"marks"`
424+
}
425+
420426
// Search runs an FTS5 query over mark titles and URLs, excluding soft-deleted
421427
// marks. The query string uses FTS5 match syntax and may be empty to search by
422428
// filters alone. tagClauses filters results to marks matching every clause

0 commit comments

Comments
 (0)