From dbb9526b247f1d197ec9a524e34f6ca4c25cdd4a Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 22 Nov 2020 22:15:51 +0100 Subject: commands: add a command to export bugs as raw operations (NDJSON) --- commands/export.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ commands/root.go | 14 ++++++++ doc/man/git-bug-export.1 | 77 ++++++++++++++++++++++++++++++++++++++++ doc/man/git-bug.1 | 2 +- doc/md/git-bug.md | 25 +++++++++---- doc/md/git-bug_export.md | 39 ++++++++++++++++++++ go.sum | 13 +++++-- 7 files changed, 252 insertions(+), 10 deletions(-) create mode 100644 commands/export.go create mode 100644 doc/man/git-bug-export.1 create mode 100644 doc/md/git-bug_export.md diff --git a/commands/export.go b/commands/export.go new file mode 100644 index 00000000..8a770fc1 --- /dev/null +++ b/commands/export.go @@ -0,0 +1,92 @@ +package commands + +import ( + "encoding/json" + + "github.com/spf13/cobra" + + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/entity" +) + +type exportOptions struct { + queryOptions +} + +func newExportCommand() *cobra.Command { + env := newEnv() + options := exportOptions{} + + cmd := &cobra.Command{ + Use: "export [QUERY]", + Short: "Export bugs as a series of operations.", + Long: `Export bugs as a series of operations. + +The output format is NDJSON (Newline delimited JSON). + +You can pass an additional query to filter and order the list. This query can be expressed either with a simple query language, flags, a natural language full text search, or a combination of the aforementioned.`, + Example: `See ls`, + PreRunE: loadBackend(env), + PostRunE: closeBackend(env), + RunE: func(cmd *cobra.Command, args []string) error { + return runExport(env, options, args) + }, + } + + flags := cmd.Flags() + flags.SortFlags = false + + flags.StringSliceVarP(&options.statusQuery, "status", "s", nil, + "Filter by status. Valid values are [open,closed]") + flags.StringSliceVarP(&options.authorQuery, "author", "a", nil, + "Filter by author") + flags.StringSliceVarP(&options.participantQuery, "participant", "p", nil, + "Filter by participant") + flags.StringSliceVarP(&options.actorQuery, "actor", "A", nil, + "Filter by actor") + flags.StringSliceVarP(&options.labelQuery, "label", "l", nil, + "Filter by label") + flags.StringSliceVarP(&options.titleQuery, "title", "t", nil, + "Filter by title") + flags.StringSliceVarP(&options.noQuery, "no", "n", nil, + "Filter by absence of something. Valid values are [label]") + flags.StringVarP(&options.sortBy, "by", "b", "creation", + "Sort the results by a characteristic. Valid values are [id,creation,edit]") + flags.StringVarP(&options.sortDirection, "direction", "d", "asc", + "Select the sorting direction. Valid values are [asc,desc]") + + return cmd +} + +func runExport(env *Env, opts exportOptions, args []string) error { + q, err := makeQuery(args, &opts.queryOptions) + if err != nil { + return err + } + + allIds := env.backend.QueryBugs(q) + + out := json.NewEncoder(env.out) + + for _, id := range allIds { + b, err := env.backend.ResolveBug(id) + if err != nil { + return err + } + + wrapper := struct { + Id entity.Id `json:"id"` + Operations []bug.Operation `json:"operations"` + }{ + Id: id, + Operations: b.Snapshot().Operations, + } + + err = out.Encode(wrapper) + if err != nil { + return err + } + } + + return nil +} diff --git a/commands/root.go b/commands/root.go index e966751c..3cda27b5 100644 --- a/commands/root.go +++ b/commands/root.go @@ -79,6 +79,20 @@ the same git remote you are already using to collaborate with other people. cmd.AddCommand(newVersionCommand(env)) cmd.AddCommand(newWipeCommand(env)) + // Added with export NDJSON + cmd.AddCommand(newAddCommand(env)) + cmd.AddCommand(newCommentCommand(env)) + cmd.AddCommand(newDeselectCommand(env)) + cmd.AddCommand(newExportCommand(env)) + cmd.AddCommand(newLsCommand(env)) + cmd.AddCommand(newLsIdCommand(env)) + cmd.AddCommand(newLsLabelCommand(env)) + cmd.AddCommand(newRmCommand(env)) + cmd.AddCommand(newSelectCommand(env)) + cmd.AddCommand(newShowCommand(env)) + cmd.AddCommand(newStatusCommand(env)) + cmd.AddCommand(newTitleCommand(env)) + return cmd } diff --git a/doc/man/git-bug-export.1 b/doc/man/git-bug-export.1 new file mode 100644 index 00000000..a6c1b1c5 --- /dev/null +++ b/doc/man/git-bug-export.1 @@ -0,0 +1,77 @@ +.nh +.TH "GIT\-BUG" "1" "Apr 2019" "Generated from git\-bug's source code" "" + +.SH NAME +.PP +git\-bug\-export \- Export bugs as a series of operations. + + +.SH SYNOPSIS +.PP +\fBgit\-bug export [QUERY] [flags]\fP + + +.SH DESCRIPTION +.PP +Export bugs as a series of operations. + +.PP +You can pass an additional query to filter and order the list. This query can be expressed either with a simple query language, flags, a natural language full text search, or a combination of the aforementioned. + + +.SH OPTIONS +.PP +\fB\-s\fP, \fB\-\-status\fP=[] + Filter by status. Valid values are [open,closed] + +.PP +\fB\-a\fP, \fB\-\-author\fP=[] + Filter by author + +.PP +\fB\-p\fP, \fB\-\-participant\fP=[] + Filter by participant + +.PP +\fB\-A\fP, \fB\-\-actor\fP=[] + Filter by actor + +.PP +\fB\-l\fP, \fB\-\-label\fP=[] + Filter by label + +.PP +\fB\-t\fP, \fB\-\-title\fP=[] + Filter by title + +.PP +\fB\-n\fP, \fB\-\-no\fP=[] + Filter by absence of something. Valid values are [label] + +.PP +\fB\-b\fP, \fB\-\-by\fP="creation" + Sort the results by a characteristic. Valid values are [id,creation,edit] + +.PP +\fB\-d\fP, \fB\-\-direction\fP="asc" + Select the sorting direction. Valid values are [asc,desc] + +.PP +\fB\-h\fP, \fB\-\-help\fP[=false] + help for export + + +.SH EXAMPLE +.PP +.RS + +.nf +See ls + +.fi +.RE + + +.SH SEE ALSO +.PP +\fBgit\-bug(1)\fP diff --git a/doc/man/git-bug.1 b/doc/man/git-bug.1 index 9bf59164..1599d8b4 100644 --- a/doc/man/git-bug.1 +++ b/doc/man/git-bug.1 @@ -29,4 +29,4 @@ the same git remote you are already using to collaborate with other people. .SH SEE ALSO .PP -\fBgit-bug-bridge(1)\fP, \fBgit-bug-bug(1)\fP, \fBgit-bug-commands(1)\fP, \fBgit-bug-label(1)\fP, \fBgit-bug-pull(1)\fP, \fBgit-bug-push(1)\fP, \fBgit-bug-termui(1)\fP, \fBgit-bug-user(1)\fP, \fBgit-bug-version(1)\fP, \fBgit-bug-webui(1)\fP, \fBgit-bug-wipe(1)\fP +\fBgit\-bug\-add(1)\fP, \fBgit\-bug\-bridge(1)\fP, \fBgit\-bug\-commands(1)\fP, \fBgit\-bug\-comment(1)\fP, \fBgit\-bug\-deselect(1)\fP, \fBgit\-bug\-export(1)\fP, \fBgit\-bug\-label(1)\fP, \fBgit\-bug\-ls(1)\fP, \fBgit\-bug\-ls\-id(1)\fP, \fBgit\-bug\-ls\-label(1)\fP, \fBgit\-bug\-pull(1)\fP, \fBgit\-bug\-push(1)\fP, \fBgit\-bug\-rm(1)\fP, \fBgit\-bug\-select(1)\fP, \fBgit\-bug\-show(1)\fP, \fBgit\-bug\-status(1)\fP, \fBgit\-bug\-termui(1)\fP, \fBgit\-bug\-title(1)\fP, \fBgit\-bug\-user(1)\fP, \fBgit\-bug\-version(1)\fP, \fBgit\-bug\-webui(1)\fP, \fBgit-bug-wipe(1)\fP diff --git a/doc/md/git-bug.md b/doc/md/git-bug.md index a71d6dfb..5a55485c 100644 --- a/doc/md/git-bug.md +++ b/doc/md/git-bug.md @@ -27,12 +27,23 @@ git-bug [flags] * [git-bug bridge](git-bug_bridge.md) - List bridges to other bug trackers * [git-bug bug](git-bug_bug.md) - List bugs * [git-bug commands](git-bug_commands.md) - Display available commands. -* [git-bug label](git-bug_label.md) - List valid labels -* [git-bug pull](git-bug_pull.md) - Pull updates from a git remote -* [git-bug push](git-bug_push.md) - Push updates to a git remote -* [git-bug termui](git-bug_termui.md) - Launch the terminal UI -* [git-bug user](git-bug_user.md) - List identities -* [git-bug version](git-bug_version.md) - Show git-bug version information -* [git-bug webui](git-bug_webui.md) - Launch the web UI +* [git-bug comment](git-bug_comment.md) - Display or add comments to a bug. +* [git-bug deselect](git-bug_deselect.md) - Clear the implicitly selected bug. +* [git-bug export](git-bug_export.md) - Export bugs as a series of operations. +* [git-bug label](git-bug_label.md) - Display, add or remove labels to/from a bug. +* [git-bug ls](git-bug_ls.md) - List bugs. +* [git-bug ls-id](git-bug_ls-id.md) - List bug identifiers. +* [git-bug ls-label](git-bug_ls-label.md) - List valid labels. +* [git-bug pull](git-bug_pull.md) - Pull bugs update from a git remote. +* [git-bug push](git-bug_push.md) - Push bugs update to a git remote. +* [git-bug rm](git-bug_rm.md) - Remove an existing bug. +* [git-bug select](git-bug_select.md) - Select a bug for implicit use in future commands. +* [git-bug show](git-bug_show.md) - Display the details of a bug. +* [git-bug status](git-bug_status.md) - Display or change a bug status. +* [git-bug termui](git-bug_termui.md) - Launch the terminal UI. +* [git-bug title](git-bug_title.md) - Display or change a title of a bug. +* [git-bug user](git-bug_user.md) - Display or change the user identity. +* [git-bug version](git-bug_version.md) - Show git-bug version information. * [git-bug wipe](git-bug_wipe.md) - Wipe git-bug from the git repository +* [git-bug webui](git-bug_webui.md) - Launch the web UI. diff --git a/doc/md/git-bug_export.md b/doc/md/git-bug_export.md new file mode 100644 index 00000000..df9c9a9b --- /dev/null +++ b/doc/md/git-bug_export.md @@ -0,0 +1,39 @@ +## git-bug export + +Export bugs as a series of operations. + +### Synopsis + +Export bugs as a series of operations. + +You can pass an additional query to filter and order the list. This query can be expressed either with a simple query language, flags, a natural language full text search, or a combination of the aforementioned. + +``` +git-bug export [QUERY] [flags] +``` + +### Examples + +``` +See ls +``` + +### Options + +``` + -s, --status strings Filter by status. Valid values are [open,closed] + -a, --author strings Filter by author + -p, --participant strings Filter by participant + -A, --actor strings Filter by actor + -l, --label strings Filter by label + -t, --title strings Filter by title + -n, --no strings Filter by absence of something. Valid values are [label] + -b, --by string Sort the results by a characteristic. Valid values are [id,creation,edit] (default "creation") + -d, --direction string Select the sorting direction. Valid values are [asc,desc] (default "asc") + -h, --help help for export +``` + +### SEE ALSO + +* [git-bug](git-bug.md) - A bug tracker embedded in Git. + diff --git a/go.sum b/go.sum index 7f27d834..dfe8538f 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,6 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdK github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/awesome-gocui/gocui v1.1.0 h1:db2j7yFEoHZjpQFeE2xqiatS8bm1lO3THeLwE6MzOII= -github.com/awesome-gocui/gocui v1.1.0/go.mod h1:M2BXkrp7PR97CKnPRT7Rk0+rtswChPtksw/vRAESGpg= github.com/bits-and-blooms/bitset v1.1.11 h1:12SusVDSQ/iJ9qaeM3yTcLLdEyqtpl35b80STAj06Fg= github.com/bits-and-blooms/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= @@ -53,6 +51,17 @@ github.com/blevesearch/bleve v1.0.14/go.mod h1:e/LJTr+E7EaoVdkQZTfoz7dt4KoDNvDbL github.com/blevesearch/blevex v1.0.0 h1:pnilj2Qi3YSEGdWgLj1Pn9Io7ukfXPoQcpAI1Bv8n/o= github.com/blevesearch/blevex v1.0.0/go.mod h1:2rNVqoG2BZI8t1/P1awgTKnGlx5MP9ZbtEciQaNhswc= github.com/blevesearch/cld2 v0.0.0-20200327141045-8b5f551d37f5/go.mod h1:PN0QNTLs9+j1bKy3d/GB/59wsNBFC4sWLWG3k69lWbc= +github.com/awesome-gocui/gocui v0.6.1-0.20191115151952-a34ffb055986 h1:QvIfX96O11qjX1Zr3hKkG0dI12JBRBGABWffyZ1GI60= +github.com/awesome-gocui/gocui v0.6.1-0.20191115151952-a34ffb055986/go.mod h1:1QikxFaPhe2frKeKvEwZEIGia3haiOxOUXKinrv17mA= +github.com/awesome-gocui/termbox-go v0.0.0-20190427202837-c0aef3d18bcc h1:wGNpKcHU8Aadr9yOzsT3GEsFLS7HQu8HxQIomnekqf0= +github.com/awesome-gocui/termbox-go v0.0.0-20190427202837-c0aef3d18bcc/go.mod h1:tOy3o5Nf1bA17mnK4W41gD7PS3u4Cv0P0pqFcoWMy8s= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA= -- cgit