Skip to content

Commit

Permalink
Add support for double-star globs
Browse files Browse the repository at this point in the history
It's really quite reasonable to want this to work -- you want to say to
look for queries in `pkg/**/*.graphql`, or `**/queries/*.graphql`, or
whatever. Now it does. I picked `doublestar` because it seemed a
reasonable combination of popular and well-documented.
  • Loading branch information
benjaminjkraft committed Apr 5, 2024
1 parent 8dc7103 commit 24232f8
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 7 deletions.
10 changes: 7 additions & 3 deletions docs/genqlient.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@

# The filename with the GraphQL schema (in SDL format), relative to
# genqlient.yaml.
# This can also be a list of filenames, such as:
# This can also be a glob-pattern, or a list of filenames or globs, such as:
# schema:
# - user.graphql
# - ./schema/*.graphql
# - ./another_directory/*/*.graphql
# - ./*/*.graphql # matches ./a/b.graphql, but not ./a/b/c.graphql
# - ./**/*.graphql # matches ./a.graphql, ./a/b/c.graphql, etc.
# The glob-pattern "**" is interpreted by github.com/bmatcuk/doublestar/v4, and
# matches zero or more path components (so you want **/*.graphql, not
# **.graphql). Each pattern must match at least one file, to avoid mistakes.
schema: schema.graphql

# Filename(s) or globs with the operations for which to generate code, relative
Expand All @@ -20,7 +24,7 @@ schema: schema.graphql
# Go files, in which case any string-literal starting with (optional
# whitespace and) the string "# @genqlient" will be extracted as a query.
#
# Like schema, this may be a single file or a list.
# Like schema, this may be a single filename or glob, or a list of those.
operations:
- genqlient.graphql
- "pkg/*.go"
Expand Down
9 changes: 7 additions & 2 deletions generate/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
goParser "go/parser"
goToken "go/token"
"os"
"path"
"path/filepath"
"strconv"
"strings"

"github.com/bmatcuk/doublestar/v4"

Check failure on line 14 in generate/parse.go

View workflow job for this annotation

GitHub Actions / Lint

import 'github.com/bmatcuk/doublestar/v4' is not allowed from list 'main' (depguard)
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/parser"
"github.com/vektah/gqlparser/v2/validator"
Expand Down Expand Up @@ -87,15 +89,18 @@ func getAndValidateQueries(basedir string, filenames StringList, schema *ast.Sch
func expandFilenames(globs []string) ([]string, error) {
uniqFilenames := make(map[string]bool, len(globs))
for _, glob := range globs {
matches, err := filepath.Glob(glob)
// SplitPattern in case the path is absolute or something; a valid path
// isn't necessarily a valid glob-pattern.
base, pattern := doublestar.SplitPattern(glob)
matches, err := doublestar.Glob(os.DirFS(base), pattern, doublestar.WithFilesOnly())
if err != nil {
return nil, errorf(nil, "can't expand file-glob %v: %v", glob, err)
}
if len(matches) == 0 {
return nil, errorf(nil, "%v did not match any files", glob)
}
for _, match := range matches {
uniqFilenames[match] = true
uniqFilenames[path.Join(base, match)] = true
}
}
filenames := make([]string, 0, len(uniqFilenames))
Expand Down
44 changes: 42 additions & 2 deletions generate/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/vektah/gqlparser/v2/ast"
)

var (
parseDataDir = "testdata/parsing"
parseErrorsDir = "testdata/parsing-errors"
parseDataDir = "testdata/parsing"
parseErrorsDir = "testdata/parsing-errors"
expandFilenamesDir = "testdata/expandFilenames"
)

func sortQueries(queryDoc *ast.QueryDocument) {
Expand Down Expand Up @@ -80,6 +82,44 @@ func removeComments(gotWithComments string) string {
return got
}

func filepathJoinAll(a string, bs []string) []string {
ret := make([]string, len(bs))
for i, b := range bs {
ret[i] = filepath.Join(a, b)
}
return ret
}

func TestExpandFilenames(t *testing.T) {
tests := []struct {
name string
globs []string
files []string
err bool
}{
{"SingleFile", []string{"a/b/c"}, []string{"a/b/c"}, false},
{"OneStar", []string{"a/*/c"}, []string{"a/b/c"}, false},
{"StarExt", []string{"a/b/*"}, []string{"a/b/c", "a/b/c.d"}, false},
{"TwoStar", []string{"**/c"}, []string{"a/b/c"}, false},
{"TwoStarSuffix", []string{"**/*"}, []string{"a/b/c", "a/b/c.d"}, false},
{"Repeated", []string{"a/b/c", "a/b/*"}, []string{"a/b/c", "a/b/c.d"}, false},
{"Empty", []string{"bogus/*"}, nil, true},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
files, err := expandFilenames(filepathJoinAll(expandFilenamesDir, test.globs))
if test.err && err == nil {
t.Errorf("got %v, wanted error", files)
} else if !test.err && err != nil {
t.Errorf("got error %v, wanted %v", err, test.files)
} else {
assert.ElementsMatch(t, filepathJoinAll(expandFilenamesDir, test.files), files)
}
})
}
}

// TestParseErrors tests that query-extraction from different language source files
// produces appropriate errors if your query is invalid.
func TestParseErrors(t *testing.T) {
Expand Down
Empty file.
Empty file.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
require (
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/alexflint/go-scalar v1.0.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 24232f8

Please sign in to comment.