diff options
-rw-r--r-- | cache/filter.go | 6 | ||||
-rw-r--r-- | cache/repo_cache.go | 22 | ||||
-rw-r--r-- | commands/ls.go | 76 | ||||
-rw-r--r-- | graphql/resolvers/repo.go | 5 | ||||
-rw-r--r-- | query/parser.go | 35 | ||||
-rw-r--r-- | query/parser_test.go | 59 | ||||
-rw-r--r-- | query/query.go (renamed from query/ast/ast.go) | 6 | ||||
-rw-r--r-- | termui/bug_table.go | 3 |
8 files changed, 96 insertions, 116 deletions
diff --git a/cache/filter.go b/cache/filter.go index 021962a7e..166cd48db 100644 --- a/cache/filter.go +++ b/cache/filter.go @@ -5,7 +5,7 @@ import ( "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/entity" - "github.com/MichaelMure/git-bug/query/ast" + "github.com/MichaelMure/git-bug/query" ) // resolver has the resolving functions needed by filters. @@ -123,9 +123,9 @@ type Matcher struct { NoFilters []Filter } -// compileMatcher transform an ast.Filters into a specialized matcher +// compileMatcher transform a query.Filters into a specialized matcher // for the cache. -func compileMatcher(filters ast.Filters) *Matcher { +func compileMatcher(filters query.Filters) *Matcher { result := &Matcher{} for _, value := range filters.Status { diff --git a/cache/repo_cache.go b/cache/repo_cache.go index 6546b15e6..f2e1c7d07 100644 --- a/cache/repo_cache.go +++ b/cache/repo_cache.go @@ -18,7 +18,7 @@ import ( "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/identity" - "github.com/MichaelMure/git-bug/query/ast" + "github.com/MichaelMure/git-bug/query" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/git" "github.com/MichaelMure/git-bug/util/process" @@ -526,15 +526,15 @@ func (c *RepoCache) resolveBugMatcher(f func(*BugExcerpt) bool) (entity.Id, erro } // QueryBugs return the id of all Bug matching the given Query -func (c *RepoCache) QueryBugs(query *ast.Query) []entity.Id { +func (c *RepoCache) QueryBugs(q *query.Query) []entity.Id { c.muBug.RLock() defer c.muBug.RUnlock() - if query == nil { + if q == nil { return c.AllBugsIds() } - matcher := compileMatcher(query.Filters) + matcher := compileMatcher(q.Filters) var filtered []*BugExcerpt @@ -546,21 +546,21 @@ func (c *RepoCache) QueryBugs(query *ast.Query) []entity.Id { var sorter sort.Interface - switch query.OrderBy { - case ast.OrderById: + switch q.OrderBy { + case query.OrderById: sorter = BugsById(filtered) - case ast.OrderByCreation: + case query.OrderByCreation: sorter = BugsByCreationTime(filtered) - case ast.OrderByEdit: + case query.OrderByEdit: sorter = BugsByEditTime(filtered) default: panic("missing sort type") } - switch query.OrderDirection { - case ast.OrderAscending: + switch q.OrderDirection { + case query.OrderAscending: // Nothing to do - case ast.OrderDescending: + case query.OrderDescending: sorter = sort.Reverse(sorter) default: panic("missing sort direction") diff --git a/commands/ls.go b/commands/ls.go index aff56f616..f125d916e 100644 --- a/commands/ls.go +++ b/commands/ls.go @@ -10,21 +10,17 @@ import ( "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/query" - "github.com/MichaelMure/git-bug/query/ast" "github.com/MichaelMure/git-bug/util/colors" "github.com/MichaelMure/git-bug/util/interrupt" ) var ( - lsStatusQuery []string - lsAuthorQuery []string - lsParticipantQuery []string - lsLabelQuery []string - lsTitleQuery []string - lsActorQuery []string - lsNoQuery []string - lsSortBy string - lsSortDirection string + lsQuery query.Query + + lsStatusQuery []string + lsNoQuery []string + lsSortBy string + lsSortDirection string ) func runLsBug(cmd *cobra.Command, args []string) error { @@ -35,7 +31,7 @@ func runLsBug(cmd *cobra.Command, args []string) error { defer backend.Close() interrupt.RegisterCleaner(backend.Close) - var q *ast.Query + var q *query.Query if len(args) >= 1 { q, err = query.Parse(strings.Join(args, " ")) @@ -43,10 +39,11 @@ func runLsBug(cmd *cobra.Command, args []string) error { return err } } else { - q, err = lsQueryFromFlags() + err = completeQuery() if err != nil { return err } + q = &lsQuery } allIds := backend.QueryBugs(q) @@ -99,63 +96,46 @@ func runLsBug(cmd *cobra.Command, args []string) error { return nil } -// Transform the command flags into an ast.Query -func lsQueryFromFlags() (*ast.Query, error) { - q := ast.NewQuery() - +// Finish the command flags transformation into the query.Query +func completeQuery() error { for _, str := range lsStatusQuery { status, err := bug.StatusFromString(str) if err != nil { - return nil, err + return err } - q.Status = append(q.Status, status) - } - for _, title := range lsTitleQuery { - q.Title = append(q.Title, title) - } - for _, author := range lsAuthorQuery { - q.Author = append(q.Author, author) - } - for _, actor := range lsActorQuery { - q.Actor = append(q.Actor, actor) - } - for _, participant := range lsParticipantQuery { - q.Participant = append(q.Participant, participant) - } - for _, label := range lsLabelQuery { - q.Label = append(q.Label, label) + lsQuery.Status = append(lsQuery.Status, status) } for _, no := range lsNoQuery { switch no { case "label": - q.NoLabel = true + lsQuery.NoLabel = true default: - return nil, fmt.Errorf("unknown \"no\" filter %s", no) + return fmt.Errorf("unknown \"no\" filter %s", no) } } switch lsSortBy { case "id": - q.OrderBy = ast.OrderById + lsQuery.OrderBy = query.OrderById case "creation": - q.OrderBy = ast.OrderByCreation + lsQuery.OrderBy = query.OrderByCreation case "edit": - q.OrderBy = ast.OrderByEdit + lsQuery.OrderBy = query.OrderByEdit default: - return nil, fmt.Errorf("unknown sort flag %s", lsSortBy) + return fmt.Errorf("unknown sort flag %s", lsSortBy) } switch lsSortDirection { case "asc": - q.OrderDirection = ast.OrderAscending + lsQuery.OrderDirection = query.OrderAscending case "desc": - q.OrderDirection = ast.OrderDescending + lsQuery.OrderDirection = query.OrderDescending default: - return nil, fmt.Errorf("unknown sort direction %s", lsSortDirection) + return fmt.Errorf("unknown sort direction %s", lsSortDirection) } - return q, nil + return nil } var lsCmd = &cobra.Command{ @@ -181,15 +161,15 @@ func init() { lsCmd.Flags().StringSliceVarP(&lsStatusQuery, "status", "s", nil, "Filter by status. Valid values are [open,closed]") - lsCmd.Flags().StringSliceVarP(&lsAuthorQuery, "author", "a", nil, + lsCmd.Flags().StringSliceVarP(&lsQuery.Author, "author", "a", nil, "Filter by author") - lsCmd.Flags().StringSliceVarP(&lsParticipantQuery, "participant", "p", nil, + lsCmd.Flags().StringSliceVarP(&lsQuery.Participant, "participant", "p", nil, "Filter by participant") - lsCmd.Flags().StringSliceVarP(&lsActorQuery, "actor", "A", nil, + lsCmd.Flags().StringSliceVarP(&lsQuery.Actor, "actor", "A", nil, "Filter by actor") - lsCmd.Flags().StringSliceVarP(&lsLabelQuery, "label", "l", nil, + lsCmd.Flags().StringSliceVarP(&lsQuery.Label, "label", "l", nil, "Filter by label") - lsCmd.Flags().StringSliceVarP(&lsTitleQuery, "title", "t", nil, + lsCmd.Flags().StringSliceVarP(&lsQuery.Title, "title", "t", nil, "Filter by title") lsCmd.Flags().StringSliceVarP(&lsNoQuery, "no", "n", nil, "Filter by absence of something. Valid values are [label]") diff --git a/graphql/resolvers/repo.go b/graphql/resolvers/repo.go index dde1dcf66..639e8f90d 100644 --- a/graphql/resolvers/repo.go +++ b/graphql/resolvers/repo.go @@ -9,7 +9,6 @@ import ( "github.com/MichaelMure/git-bug/graphql/graph" "github.com/MichaelMure/git-bug/graphql/models" "github.com/MichaelMure/git-bug/query" - "github.com/MichaelMure/git-bug/query/ast" ) var _ graph.RepositoryResolver = &repoResolver{} @@ -29,7 +28,7 @@ func (repoResolver) AllBugs(_ context.Context, obj *models.Repository, after *st Last: last, } - var q *ast.Query + var q *query.Query if queryStr != nil { query2, err := query.Parse(*queryStr) if err != nil { @@ -37,7 +36,7 @@ func (repoResolver) AllBugs(_ context.Context, obj *models.Repository, after *st } q = query2 } else { - q = ast.NewQuery() + q = query.NewQuery() } // Simply pass a []string with the ids to the pagination algorithm diff --git a/query/parser.go b/query/parser.go index 89893b60b..a379f7501 100644 --- a/query/parser.go +++ b/query/parser.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/MichaelMure/git-bug/bug" - "github.com/MichaelMure/git-bug/query/ast" ) // Parse parse a query DSL @@ -12,15 +11,15 @@ import ( // Ex: "status:open author:descartes sort:edit-asc" // // Supported filter qualifiers and syntax are described in docs/queries.md -func Parse(query string) (*ast.Query, error) { +func Parse(query string) (*Query, error) { tokens, err := tokenize(query) if err != nil { return nil, err } - q := &ast.Query{ - OrderBy: ast.OrderByCreation, - OrderDirection: ast.OrderDescending, + q := &Query{ + OrderBy: OrderByCreation, + OrderDirection: OrderDescending, } sortingDone := false @@ -66,31 +65,31 @@ func Parse(query string) (*ast.Query, error) { return q, nil } -func parseSorting(q *ast.Query, value string) error { +func parseSorting(q *Query, value string) error { switch value { // default ASC case "id-desc": - q.OrderBy = ast.OrderById - q.OrderDirection = ast.OrderDescending + q.OrderBy = OrderById + q.OrderDirection = OrderDescending case "id", "id-asc": - q.OrderBy = ast.OrderById - q.OrderDirection = ast.OrderAscending + q.OrderBy = OrderById + q.OrderDirection = OrderAscending // default DESC case "creation", "creation-desc": - q.OrderBy = ast.OrderByCreation - q.OrderDirection = ast.OrderDescending + q.OrderBy = OrderByCreation + q.OrderDirection = OrderDescending case "creation-asc": - q.OrderBy = ast.OrderByCreation - q.OrderDirection = ast.OrderAscending + q.OrderBy = OrderByCreation + q.OrderDirection = OrderAscending // default DESC case "edit", "edit-desc": - q.OrderBy = ast.OrderByEdit - q.OrderDirection = ast.OrderDescending + q.OrderBy = OrderByEdit + q.OrderDirection = OrderDescending case "edit-asc": - q.OrderBy = ast.OrderByEdit - q.OrderDirection = ast.OrderAscending + q.OrderBy = OrderByEdit + q.OrderDirection = OrderAscending default: return fmt.Errorf("unknown sorting %s", value) diff --git a/query/parser_test.go b/query/parser_test.go index 065e647a9..6a509adb7 100644 --- a/query/parser_test.go +++ b/query/parser_test.go @@ -6,73 +6,72 @@ import ( "github.com/stretchr/testify/assert" "github.com/MichaelMure/git-bug/bug" - "github.com/MichaelMure/git-bug/query/ast" ) func TestParse(t *testing.T) { var tests = []struct { input string - output *ast.Query + output *Query }{ {"gibberish", nil}, {"status:", nil}, {":value", nil}, - {"status:open", &ast.Query{ - Filters: ast.Filters{Status: []bug.Status{bug.OpenStatus}}, + {"status:open", &Query{ + Filters: Filters{Status: []bug.Status{bug.OpenStatus}}, }}, - {"status:closed", &ast.Query{ - Filters: ast.Filters{Status: []bug.Status{bug.ClosedStatus}}, + {"status:closed", &Query{ + Filters: Filters{Status: []bug.Status{bug.ClosedStatus}}, }}, {"status:unknown", nil}, - {"author:rene", &ast.Query{ - Filters: ast.Filters{Author: []string{"rene"}}, + {"author:rene", &Query{ + Filters: Filters{Author: []string{"rene"}}, }}, - {`author:"René Descartes"`, &ast.Query{ - Filters: ast.Filters{Author: []string{"René Descartes"}}, + {`author:"René Descartes"`, &Query{ + Filters: Filters{Author: []string{"René Descartes"}}, }}, - {"actor:bernhard", &ast.Query{ - Filters: ast.Filters{Actor: []string{"bernhard"}}, + {"actor:bernhard", &Query{ + Filters: Filters{Actor: []string{"bernhard"}}, }}, - {"participant:leonhard", &ast.Query{ - Filters: ast.Filters{Participant: []string{"leonhard"}}, + {"participant:leonhard", &Query{ + Filters: Filters{Participant: []string{"leonhard"}}, }}, - {"label:hello", &ast.Query{ - Filters: ast.Filters{Label: []string{"hello"}}, + {"label:hello", &Query{ + Filters: Filters{Label: []string{"hello"}}, }}, - {`label:"Good first issue"`, &ast.Query{ - Filters: ast.Filters{Label: []string{"Good first issue"}}, + {`label:"Good first issue"`, &Query{ + Filters: Filters{Label: []string{"Good first issue"}}, }}, - {"title:titleOne", &ast.Query{ - Filters: ast.Filters{Title: []string{"titleOne"}}, + {"title:titleOne", &Query{ + Filters: Filters{Title: []string{"titleOne"}}, }}, - {`title:"Bug titleTwo"`, &ast.Query{ - Filters: ast.Filters{Title: []string{"Bug titleTwo"}}, + {`title:"Bug titleTwo"`, &Query{ + Filters: Filters{Title: []string{"Bug titleTwo"}}, }}, - {"no:label", &ast.Query{ - Filters: ast.Filters{NoLabel: true}, + {"no:label", &Query{ + Filters: Filters{NoLabel: true}, }}, - {"sort:edit", &ast.Query{ - OrderBy: ast.OrderByEdit, + {"sort:edit", &Query{ + OrderBy: OrderByEdit, }}, {"sort:unknown", nil}, {`status:open author:"René Descartes" participant:leonhard label:hello label:"Good first issue" sort:edit-desc`, - &ast.Query{ - Filters: ast.Filters{ + &Query{ + Filters: Filters{ Status: []bug.Status{bug.OpenStatus}, Author: []string{"René Descartes"}, Participant: []string{"leonhard"}, Label: []string{"hello", "Good first issue"}, }, - OrderBy: ast.OrderByEdit, - OrderDirection: ast.OrderDescending, + OrderBy: OrderByEdit, + OrderDirection: OrderDescending, }, }, } diff --git a/query/ast/ast.go b/query/query.go index fe77abf9f..a499ad382 100644 --- a/query/ast/ast.go +++ b/query/query.go @@ -1,7 +1,11 @@ -package ast +package query import "github.com/MichaelMure/git-bug/bug" +// Query is the intermediary representation of a Bug's query. It is either +// produced by parsing a query string (ex: "status:open author:rene") or created +// manually. This query doesn't do anything by itself and need to be interpreted +// for the specific domain of application. type Query struct { Filters OrderBy diff --git a/termui/bug_table.go b/termui/bug_table.go index 74f928266..80d5ebcba 100644 --- a/termui/bug_table.go +++ b/termui/bug_table.go @@ -13,7 +13,6 @@ import ( "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/query" - "github.com/MichaelMure/git-bug/query/ast" "github.com/MichaelMure/git-bug/util/colors" ) @@ -28,7 +27,7 @@ const defaultQuery = "status:open" type bugTable struct { repo *cache.RepoCache queryStr string - query *ast.Query + query *query.Query allIds []entity.Id excerpts []*cache.BugExcerpt pageCursor int |