diff --git a/README.md b/README.md index 279b8b8..2fb0fb7 100644 --- a/README.md +++ b/README.md @@ -23,19 +23,49 @@ In the `~/.config/logbook/config.yaml` file it can be configured what directorie The following snippet shows the configuration options with their default values: ```yaml -# The directory where new log entries are added. +# The directory where new logbook entries are added. logDirectory: ~/Logs -# The directory where log entries are moved when they are archived. +# The directory where logbook entries are moved when they are archived. archiveDirectory: ~/Archive ``` ## Usage -### Search log entries +### Add logbook entry ```sh -logbook2 search $SEARCH_TERM +# Add logbook entry +logbook2 add "${TITLE}" + +# Add logbook entry and open its root directory in a text editor +${EDITOR} $(logbook2 add "${TITLE}") +``` + +### Search logbook entries + +```sh +logbook2 search "${SEARCH_TERM}" +``` + +### Archive logbook entries + +```sh +# Archive single logbook entry +logbook2 archive "${PATH}" + +# Archive multiple logbook entries +logbook2 archive $(logbook2 search --output-format list "${SEARCH_TERM}") +``` + +### Remove logbook entries + +```sh +# Remove single logbook entry +logbook2 remove "${PATH}" + +# Remove multiple logbook entries +logbook2 remove $(logbook2 search --output-format list "${SEARCH_TERM}") ``` ## Testing diff --git a/cmd/choice_value.go b/cmd/choice_value.go new file mode 100644 index 0000000..04674f5 --- /dev/null +++ b/cmd/choice_value.go @@ -0,0 +1,34 @@ +// Package cmd see https://github.com/spf13/pflag/issues/236#issuecomment-3098646174 +package cmd + +import "fmt" + +type ChoiceValue struct { + value string + validate func(string) error +} + +func (f *ChoiceValue) Set(s string) error { + err := f.validate(s) + if err != nil { + return err + } + + f.value = s + return nil +} +func (f *ChoiceValue) Type() string { return "string" } +func (f *ChoiceValue) String() string { return f.value } + +func StringChoice(choices []string) *ChoiceValue { + return &ChoiceValue{ + validate: func(s string) error { + for _, choice := range choices { + if s == choice { + return nil + } + } + return fmt.Errorf("must be one of %v", choices) + }, + } +} diff --git a/cmd/search.go b/cmd/search.go index a047a39..77c909a 100644 --- a/cmd/search.go +++ b/cmd/search.go @@ -1,6 +1,8 @@ package cmd import ( + "encoding/json" + "fmt" "os" "strings" @@ -21,16 +23,45 @@ var searchCmd = &cobra.Command{ } logEntries := core.Search(configuration.LogDirectory, searchTerm) - t := table.New(os.Stdout) - t.SetHeaders("Date / Time", "Title", "Path") - for _, entry := range logEntries { - title := entry.Title - if len(title) > 50 { - title = title[:50] - title += " (...)" + outputFormat, err := cmd.Flags().GetString("output-format") + if err != nil { + panic(err) + } + + switch outputFormat { + default: + { + t := table.New(os.Stdout) + t.SetHeaders("Date / Time", "Title", "Path") + for _, entry := range logEntries { + title := entry.Title + if len(title) > 50 { + title = title[:50] + title += " (...)" + } + t.AddRow(strings.Replace(entry.DateTime, "T", " ", 1), title, entry.Directory) + } + t.Render() + } + case "list": + { + for _, entry := range logEntries { + fmt.Println(entry.Directory) + } } - t.AddRow(strings.Replace(entry.DateTime, "T", " ", 1), title, entry.Directory) + case "json": + b, err := json.MarshalIndent(logEntries, "", " ") + if err != nil { + panic(err) + } + fmt.Println(string(b)) } - t.Render() }, } + +func init() { + flags := searchCmd.Flags() + flags.VarP(StringChoice([]string{ + "table", "list", "json", + }), "output-format", "o", "The format in which the log entries are printed to the terminal.\n[table (default), list, json]") +} diff --git a/core/domain.go b/core/domain.go index 47b868a..22a8482 100644 --- a/core/domain.go +++ b/core/domain.go @@ -1,7 +1,7 @@ package core type LogbookEntry struct { - DateTime string - Title string - Directory string + DateTime string `json:"dateTime"` + Title string `json:"title"` + Directory string `json:"directory"` }