-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs/howto: place data using the Go API
This adds a guide demonstrating how to replicate the effect of the cue command's --path flag using the Go API. Preview-Path: /docs/howto/place-data-go-api/ Signed-off-by: Paul Jolly <[email protected]> Change-Id: I0e5618207da2bc78cff9df715b1a4827503142dd Reviewed-on: https://review.gerrithub.io/c/cue-lang/cuelang.org/+/1199814 TryBot-Result: CUEcueckoo <[email protected]>
- Loading branch information
1 parent
6acf2a6
commit cf1dd51
Showing
4 changed files
with
365 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
--- | ||
title: Placing data using the Go API | ||
tags: [go api] | ||
authors: [myitcv,jpluscplusm] | ||
toc_hide: true | ||
--- | ||
|
||
{{{with _script_ "en" "set caches to speed up re-running"}}} | ||
export GOMODCACHE=/caches/gomodcache | ||
export GOCACHE=/caches/gobuild | ||
{{{end}}} | ||
|
||
The `cue` command allows non-CUE data to be "placed" at a specific location in | ||
its evaluation with the `--path`/`-l` flag. | ||
This guide demonstrates how to achieve the same result using the Go API. | ||
|
||
## Set up the environment | ||
|
||
{{{with step}}} | ||
If you don't already have CUE or Go modules, initialize them: | ||
|
||
{{{with script "en" "start modules"}}} | ||
cue mod init cue.example | ||
#ellipsis 0 | ||
go mod init go.example | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
## Create some data files | ||
|
||
{{{with step}}} | ||
Write some CUE code and JSON data | ||
(if you don't already have some code that you want to update and use): | ||
|
||
{{{with upload "en" "initial cue code"}}} | ||
#location left right | ||
-- some.cue -- | ||
package example | ||
|
||
// The data will be placed at this location. | ||
input: { | ||
name!: string | ||
location: *"your part of the world" | string | ||
} | ||
|
||
output: """ | ||
Hello, \(input.name)! | ||
How's the weather in \(input.location)? | ||
""" | ||
-- input.json -- | ||
{ | ||
"name": "Charlie" | ||
} | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Check that the data file can be combined successfully with the CUE: | ||
|
||
{{{with script "en" "test cue"}}} | ||
cue export . input.json --path input: -e output --out text | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
## Write some Go | ||
|
||
{{{with step}}} | ||
Write a Go program that places the data in the `input.json` file at a specific | ||
location within its CUE evaluation | ||
(or adapt your existing code to do the same): | ||
|
||
{{{with upload "en" "go program"}}} | ||
#location top-left | ||
-- main.go -- | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os" | ||
|
||
"cuelang.org/go/cue" | ||
"cuelang.org/go/cue/cuecontext" | ||
"cuelang.org/go/cue/load" | ||
"cuelang.org/go/encoding/json" | ||
) | ||
|
||
func main() { | ||
ctx := cuecontext.New() | ||
// Load the package in the current directory. | ||
bis := load.Instances([]string{"."}, nil) | ||
v := ctx.BuildInstance(bis[0]) | ||
|
||
// Load the input data. | ||
jsonBytes, err := os.ReadFile("input.json") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Parse the input data to a CUE expression. | ||
jsonData, err := json.Extract("input.json", jsonBytes) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Place the parsed data as the value of the "input" field. | ||
complete := v.FillPath(cue.ParsePath("input"), jsonData) | ||
|
||
// Extract the string value of the "output" field and print it. | ||
output := complete.LookupPath(cue.ParsePath("output")) | ||
msg, _ := output.String() // We know that "output" is a string type. | ||
fmt.Printf("%v\n", msg) | ||
} | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
## Run the program | ||
|
||
{{{with step}}} | ||
Add a dependency on `cuelang.org/go` and ensure the Go module is tidy: | ||
|
||
{{{with script "en" "go test"}}} | ||
#ellipsis 0 | ||
go get cuelang.org/go@$CUELANG_CUE_LATEST | ||
#ellipsis 0 | ||
go mod tidy | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Run the program, | ||
printing the same multi-line string value that `cue` produced earlier: | ||
|
||
{{{with script "en" "go run"}}} | ||
go run . | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
## Related content | ||
|
||
- {{< linkto/related/concept "how-cue-works-with-go" >}} | ||
- All pages tagged with {{< tag "go api" >}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package site | ||
{ | ||
content: { | ||
docs: { | ||
howto: { | ||
"place-data-go-api": { | ||
page: { | ||
cache: { | ||
upload: { | ||
"initial cue code": "cCDR5sNYSrEu2VXlWD62h3u6GdC/q2rCqvM8RQbYLl8=" | ||
"go program": "Gzyh+JVAzI2GEWyf7DIg6z9AwsBNbpQwZIkHwJ3lyMM=" | ||
} | ||
multi_step: { | ||
hash: "EU18HI7QMRIP19IS6GQ5IVJ8OIHKKKHASQ9BAP8DIUJCAE6864L0====" | ||
scriptHash: "B2ACPKB2I7S9HP09ENHJFI1UHG1SO348DOOJ6DIDMB2U9GAQLNBG====" | ||
steps: [{ | ||
doc: "" | ||
cmd: "export GOMODCACHE=/caches/gomodcache" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "export GOCACHE=/caches/gobuild" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "cue mod init cue.example" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "#ellipsis 0" | ||
cmd: "go mod init go.example" | ||
exitCode: 0 | ||
output: """ | ||
... | ||
""" | ||
}, { | ||
doc: "" | ||
cmd: "cue export . input.json --path input: -e output --out text" | ||
exitCode: 0 | ||
output: """ | ||
Hello, Charlie! | ||
How's the weather in your part of the world? | ||
""" | ||
}, { | ||
doc: "#ellipsis 0" | ||
cmd: "go get cuelang.org/[email protected]" | ||
exitCode: 0 | ||
output: """ | ||
... | ||
""" | ||
}, { | ||
doc: "#ellipsis 0" | ||
cmd: "go mod tidy" | ||
exitCode: 0 | ||
output: """ | ||
... | ||
""" | ||
}, { | ||
doc: "" | ||
cmd: "go run ." | ||
exitCode: 0 | ||
output: """ | ||
Hello, Charlie! | ||
How's the weather in your part of the world? | ||
""" | ||
}] | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package site | ||
|
||
content: docs: howto: "place-data-go-api": page: _ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
--- | ||
title: Placing data using the Go API | ||
tags: [go api] | ||
authors: [myitcv,jpluscplusm] | ||
toc_hide: true | ||
--- | ||
|
||
The `cue` command allows non-CUE data to be "placed" at a specific location in | ||
its evaluation with the `--path`/`-l` flag. | ||
This guide demonstrates how to achieve the same result using the Go API. | ||
|
||
## Set up the environment | ||
|
||
{{< step stepNumber="1" >}} | ||
If you don't already have CUE or Go modules, initialize them: | ||
|
||
```text { title="TERMINAL" type="terminal" codeToCopy="Y3VlIG1vZCBpbml0IGN1ZS5leGFtcGxlCmdvIG1vZCBpbml0IGdvLmV4YW1wbGU=" } | ||
$ cue mod init cue.example | ||
$ go mod init go.example | ||
... | ||
``` | ||
{{< /step >}} | ||
|
||
## Create some data files | ||
|
||
{{< step stepNumber="2" >}} | ||
Write some CUE code and JSON data | ||
(if you don't already have some code that you want to update and use): | ||
|
||
{{< code-tabs >}} | ||
{{< code-tab name="some.cue" language="cue" area="left" >}} | ||
package example | ||
|
||
// The data will be placed at this location. | ||
input: { | ||
name!: string | ||
location: *"your part of the world" | string | ||
} | ||
|
||
output: """ | ||
Hello, \(input.name)! | ||
How's the weather in \(input.location)? | ||
""" | ||
{{< /code-tab >}}{{< code-tab name="input.json" language="json" area="right" >}} | ||
{ | ||
"name": "Charlie" | ||
} | ||
{{< /code-tab >}}{{< /code-tabs >}} | ||
{{< /step >}} | ||
|
||
{{< step stepNumber="3" >}} | ||
Check that the data file can be combined successfully with the CUE: | ||
|
||
```text { title="TERMINAL" type="terminal" codeToCopy="Y3VlIGV4cG9ydCAuIGlucHV0Lmpzb24gLS1wYXRoIGlucHV0OiAtZSBvdXRwdXQgLS1vdXQgdGV4dA==" } | ||
$ cue export . input.json --path input: -e output --out text | ||
Hello, Charlie! | ||
How's the weather in your part of the world? | ||
``` | ||
{{< /step >}} | ||
|
||
## Write some Go | ||
|
||
{{< step stepNumber="4" >}} | ||
Write a Go program that places the data in the `input.json` file at a specific | ||
location within its CUE evaluation | ||
(or adapt your existing code to do the same): | ||
|
||
{{< code-tabs >}} | ||
{{< code-tab name="main.go" language="go" area="top-left" >}} | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os" | ||
|
||
"cuelang.org/go/cue" | ||
"cuelang.org/go/cue/cuecontext" | ||
"cuelang.org/go/cue/load" | ||
"cuelang.org/go/encoding/json" | ||
) | ||
|
||
func main() { | ||
ctx := cuecontext.New() | ||
// Load the package in the current directory. | ||
bis := load.Instances([]string{"."}, nil) | ||
v := ctx.BuildInstance(bis[0]) | ||
|
||
// Load the input data. | ||
jsonBytes, err := os.ReadFile("input.json") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Parse the input data to a CUE expression. | ||
jsonData, err := json.Extract("input.json", jsonBytes) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Place the parsed data as the value of the "input" field. | ||
complete := v.FillPath(cue.ParsePath("input"), jsonData) | ||
|
||
// Extract the string value of the "output" field and print it. | ||
output := complete.LookupPath(cue.ParsePath("output")) | ||
msg, _ := output.String() // We know that "output" is a string type. | ||
fmt.Printf("%v\n", msg) | ||
} | ||
{{< /code-tab >}}{{< /code-tabs >}} | ||
{{< /step >}} | ||
|
||
## Run the program | ||
|
||
{{< step stepNumber="5" >}} | ||
Add a dependency on `cuelang.org/go` and ensure the Go module is tidy: | ||
|
||
```text { title="TERMINAL" type="terminal" codeToCopy="Z28gZ2V0IGN1ZWxhbmcub3JnL2dvQHYwLjEwLjAKZ28gbW9kIHRpZHk=" } | ||
$ go get cuelang.org/[email protected] | ||
... | ||
$ go mod tidy | ||
... | ||
``` | ||
{{< /step >}} | ||
|
||
{{< step stepNumber="6" >}} | ||
Run the program, | ||
printing the same multi-line string value that `cue` produced earlier: | ||
|
||
```text { title="TERMINAL" type="terminal" codeToCopy="Z28gcnVuIC4=" } | ||
$ go run . | ||
Hello, Charlie! | ||
How's the weather in your part of the world? | ||
``` | ||
{{< /step >}} | ||
|
||
## Related content | ||
|
||
- {{< linkto/related/concept "how-cue-works-with-go" >}} | ||
- All pages tagged with {{< tag "go api" >}} |