Repository: Khan/genqlient
Pull request #192 (2022-05-10 21:42:54)

Allow absolute paths in schema files.
Thsi is useful for some out-of-tree testing I want to do.  It's
unfortunate (imo) that filepath.join doesn't have this behavior by
default.

Test plan:
go test ./...

<!--
Thanks for your contribution! Check out the
[contributing docs](https://github.com/Khan/genqlient/blob/main/docs/CONTRIBUTING.md)
for more on contributing to genqlient.
-->



I have:
- [x] Written a clear PR title and description (above)
- [x] Signed the [Khan Academy CLA](https://www.khanacademy.org/r/cla)
- [x] Added tests covering my changes, if applicable
- [x] Included a link to the issue fixed, if applicable
- [x] Included documentation, for new features
- [x] Added an entry to the changelog



Patch:
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 6e0bd6b..5f62915 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -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:
 
diff --git a/generate/config.go b/generate/config.go
index 5f019c3..0654a33 100644
--- a/generate/config.go
+++ b/generate/config.go
@@ -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 {
+	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.
 //
@@ -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 == "" {
@@ -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
 		}


Test patch:
diff --git a/generate/config_test.go b/generate/config_test.go
index c69f623..3568a72 100644
--- a/generate/config_test.go
+++ b/generate/config_test.go
@@ -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])
+}
diff --git a/generate/testdata/find-config/current/genqlient.yaml b/generate/testdata/find-config/current/genqlient.yaml
index bfc5f26..4e080ce 100644
--- a/generate/testdata/find-config/current/genqlient.yaml
+++ b/generate/testdata/find-config/current/genqlient.yaml
@@ -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