diff --git a/README.md b/README.md index b3eda4a..998fc76 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ book shelf add # add a shelf interactively book collection add # add a collection to a shelf book mark add https://example.com # add a bookmark (fetches title) book mark add https://example.com --shelf dev --collection tools --tags go,cli +book shelf list # one name per line; pipe into fzf book mark list --shelf dev --collection tools --format json ``` @@ -72,6 +73,16 @@ go build . 3. **List your bookmarks:** + Plain-text defaults are pipe-friendly and require no flags: + + ```bash + book shelf list + book collection list --shelf dev + book mark list --shelf dev --collection docs + ``` + + Add `--format json` or `--format toml` for structured output: + ```bash book shelf list --format json book collection list --shelf dev --format json @@ -156,7 +167,7 @@ collection_desc = "language and framework docs" | `--theme-file ` | `$XDG_CONFIG_HOME/book/theme.json` | Theme JSON path | | `--template-file ` | `$XDG_CONFIG_HOME/book/template.json` | Template JSON path | | `--catalog-format` | `toml` | Shelf file format (only `toml` supported) | -| `--format ` | — | Output format for `list` commands (`json` or `toml`) | +| `--format ` | — | Opt into structured output for `list` commands (`json` or `toml`; default is one line per item) | ## Configuration diff --git a/VERSION b/VERSION index 79127d8..6a5e98a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.2.0 +v1.2.1 diff --git a/cmd/book/collection.go b/cmd/book/collection.go index 8ffce4e..7096d4d 100644 --- a/cmd/book/collection.go +++ b/cmd/book/collection.go @@ -1,6 +1,8 @@ package cmd import ( + "fmt" + "github.com/polymorcodeus/book/internal/book" "github.com/polymorcodeus/book/internal/model" ) @@ -16,6 +18,12 @@ func collections(bs *book.BookShelves, shelfName string, format string, config * if err != nil { return err } + if format == "" { + for _, name := range names { + fmt.Println(name) + } + return nil + } return book.PrintCatalog(names, format) } diff --git a/cmd/book/main.go b/cmd/book/main.go index fad6cf9..89d98e8 100644 --- a/cmd/book/main.go +++ b/cmd/book/main.go @@ -244,12 +244,6 @@ func Main() { Name: "list", Usage: "list shelves", Aliases: []string{"ls"}, - Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) { - if !config.Interactive && format == "" { - return ctx, cli.Exit(config.StyledError(fmt.Errorf("set --format=[json|toml] to output shelves non-interactively")), 1) - } - return ctx, nil - }, Action: func(ctx context.Context, cmd *cli.Command) error { if err := shelves(&bookShelves, format, config); err != nil { return cli.Exit(config.StyledError(err), 1) @@ -292,12 +286,6 @@ func Main() { Name: "list", Usage: "list collections in shelve", Aliases: []string{"ls"}, - Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) { - if !config.Interactive && format == "" { - return ctx, cli.Exit(config.StyledError(fmt.Errorf("set --format=[json|toml] to output collections non-interactively")), 1) - } - return ctx, nil - }, Action: func(ctx context.Context, cmd *cli.Command) error { if err := collections(&bookShelves, shelf, format, config); err != nil { return cli.Exit(config.StyledError(err), 1) @@ -413,12 +401,6 @@ func Main() { Destination: &trash, }, }, - Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) { - if !config.Interactive && format == "" { - return ctx, cli.Exit(config.StyledError(fmt.Errorf("set --format=[json|toml] to output collections non-interactively")), 1) - } - return ctx, nil - }, Action: func(ctx context.Context, cmd *cli.Command) error { if err := marks(&bookShelves, shelf, collection, format, trash, config); err != nil { return cli.Exit(config.StyledError(err), 1) diff --git a/cmd/book/mark.go b/cmd/book/mark.go index 510b4c7..d99eff5 100644 --- a/cmd/book/mark.go +++ b/cmd/book/mark.go @@ -19,9 +19,6 @@ func mark(bs *book.BookShelves, config *book.Config) error { func marks(bs *book.BookShelves, shelfName string, collectionName string, format string, trash bool, config *book.Config) error { // Trash listing reads the derived index and is always non-interactive. if trash { - if format == "" { - return fmt.Errorf("set --format=[json|toml] to list trashed marks") - } idx, err := syncIndex(config) if err != nil { return err @@ -30,13 +27,20 @@ func marks(bs *book.BookShelves, shelfName string, collectionName string, format if err != nil { return err } - if format == "toml" { + switch format { + case "toml": wrapped := struct { Marks []catalog.SearchResult `toml:"marks"` }{deleted} return book.PrintCatalog(wrapped, format) + case "json": + return book.PrintCatalog(deleted, format) + default: + for _, r := range deleted { + fmt.Printf("%s %s\n", r.Title, r.URL) + } + return nil } - return book.PrintCatalog(deleted, format) } // Non-interactive path: all required flags provided @@ -49,6 +53,15 @@ func marks(bs *book.BookShelves, shelfName string, collectionName string, format if err != nil { return err } + if format == "" { + for _, m := range collection.Marks { + if m.IsDeleted() { + continue + } + fmt.Printf("%s %s\n", m.Name, m.URL) + } + return nil + } return book.PrintCatalog(collection, format) } return runProgram(markRootScreen(bs, &book.Mark{}, "list", config)) diff --git a/cmd/book/shelf.go b/cmd/book/shelf.go index 5bbcbd0..1172b46 100644 --- a/cmd/book/shelf.go +++ b/cmd/book/shelf.go @@ -1,6 +1,8 @@ package cmd import ( + "fmt" + "github.com/polymorcodeus/book/internal/book" "github.com/polymorcodeus/book/internal/model" ) @@ -15,6 +17,12 @@ func shelves(bs *book.BookShelves, format string, config *book.Config) error { if err != nil { return err } + if format == "" { + for _, name := range names { + fmt.Println(name) + } + return nil + } return book.PrintCatalog(names, format) }