Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow absolute paths in schema files. #192

Merged
merged 3 commits into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ When releasing a new version:
- genqlient can now run as a portable binary (i.e. without a local checkout of the repository or `go run`).
- You can now enable `use_extensions` in the configuration file, to receive extensions returned by the GraphQL API server. Generated functions will return extensions as `map[string]interface{}`, if enabled.
- You can now use `graphql.NewClientUsingGet` to create a client that uses query parameters to pass the query to the GraphQL API server.
- In config files, `schema`, `operations`, and `generated` can now be absolute paths.

### Bug fixes:

Expand Down
20 changes: 15 additions & 5 deletions generate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ type TypeBinding struct {
Unmarshaler string `yaml:"unmarshaler"`
}

// pathJoin is like filepath.Join but 1) it only takes two argsuments,
// and b) if the second argument is an absolute path the first argument
// is ignored (similar to how python's os.path.join() works).
func pathJoin(a, b string) string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest a more accurate name such as func abs(basedir, path string) string {
This is then similar to the stdlib's filepath.Abs but allows you to specify the base directory instead of using the current working directory.

func Abs
func Abs(path string) (string, error)
Abs returns an absolute representation of path. If the path is not absolute it will be joined with the current working directory to turn it into an absolute path. The absolute path name for a given file is not guaranteed to be unique. Abs calls Clean on the result.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

abs isn't very accurate because there's no requirement that a be an absolute path. I really see this as a "proper" path-join (and the default go implementation as not-proper). But ymmv.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unexported helper, so you do you.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the name isn't ideal, but I don't have a better idea, so I'm fine with this. (Closest thing I can think of in the stdlib is net/url.ResolveReference which I don't think is the greatest name either.)

if filepath.IsAbs(b) {
return b
}
return filepath.Join(a, b)
}

// ValidateAndFillDefaults ensures that the configuration is valid, and fills
// in any options that were unspecified.
//
Expand All @@ -59,14 +69,14 @@ type TypeBinding struct {
func (c *Config) ValidateAndFillDefaults(baseDir string) error {
c.baseDir = baseDir
for i := range c.Schema {
c.Schema[i] = filepath.Join(baseDir, c.Schema[i])
c.Schema[i] = pathJoin(baseDir, c.Schema[i])
}
for i := range c.Operations {
c.Operations[i] = filepath.Join(baseDir, c.Operations[i])
c.Operations[i] = pathJoin(baseDir, c.Operations[i])
}
c.Generated = filepath.Join(baseDir, c.Generated)
c.Generated = pathJoin(baseDir, c.Generated)
if c.ExportOperations != "" {
c.ExportOperations = filepath.Join(baseDir, c.ExportOperations)
c.ExportOperations = pathJoin(baseDir, c.ExportOperations)
}

if c.ContextType == "" {
Expand Down Expand Up @@ -154,7 +164,7 @@ func findCfg() (string, error) {

func findCfgInDir(dir string) string {
for _, cfgName := range cfgFilenames {
path := filepath.Join(dir, cfgName)
path := pathJoin(dir, cfgName)
if _, err := os.Stat(path); err == nil {
return path
}
Expand Down
18 changes: 18 additions & 0 deletions generate/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,21 @@ func TestFindCfgInDir(t *testing.T) {
})
}
}

func TestAbsoluteAndRelativePathsInConfigFiles(t *testing.T) {
cwd, err := os.Getwd()
require.NoError(t, err)

config, err := ReadAndValidateConfig(
cwd + "/testdata/find-config/current/genqlient.yaml")
require.NoError(t, err)

require.Equal(t, 1, len(config.Schema))
require.Equal(
t,
cwd+"/testdata/find-config/current/schema.graphql",
config.Schema[0],
)
require.Equal(t, 1, len(config.Operations))
require.Equal(t, "/tmp/genqlient.graphql", config.Operations[0])
}
3 changes: 2 additions & 1 deletion generate/testdata/find-config/current/genqlient.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
# https://github.com/Khan/genqlient/blob/main/docs/genqlient.yaml
schema: schema.graphql
operations:
- genqlient.graphql
# Also use this config to test absolute paths in config files.
- /tmp/genqlient.graphql
generated: generated.go