-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs/tutorial: using modules with the Go API
This adds a tutorial on using the Go API in modules-aware mode. Closes cue-lang/docs-and-content#94 Preview-Path: /docs/tutorial/using-modules-with-go-api/ Signed-off-by: Paul Jolly <paul@myitcv.io> Change-Id: I17a67855b3c7487f2f67943aae2b6d4c497f6eed Reviewed-on: https://review.gerrithub.io/c/cue-lang/cuelang.org/+/1189727 TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
- Loading branch information
1 parent
bcf703c
commit 1067927
Showing
4 changed files
with
606 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,241 @@ | ||
--- | ||
title: Using modules with the Go API | ||
authors: | ||
- myitcv | ||
- jpluscplusm | ||
tags: | ||
- go api | ||
- modules | ||
- tooling | ||
toc_hide: true | ||
--- | ||
|
||
{{{with _script_ "en" "HIDDEN set caches to speed up re-running"}}} | ||
export GOMODCACHE=/caches/gomodcache | ||
export GOCACHE=/caches/gobuild | ||
{{{end}}} | ||
|
||
{{{with _script_ "en" "HIDDEN use non-prerelease cue command to mirror API use"}}} | ||
export PATH=/cues/$CUELANG_CUE_LATEST:$PATH | ||
{{{end}}} | ||
|
||
{{{with _script_ "en" "HIDDEN setup auth"}}} | ||
mkdir -p $HOME/.config/cue | ||
cat <<EOD > $HOME/.config/cue/logins.json | ||
{"registries":{"registry.cue.works":{"access_token":"${TEST_USER_AUTHN_CUE_USER_NEW}","token_type":"Bearer"}}} | ||
EOD | ||
{{{end}}} | ||
|
||
## Introduction | ||
|
||
In this tutorial you will | ||
use CUE's Go API to work with a CUE module dependency fetched from the Central Registry. | ||
|
||
Along the way you will: | ||
|
||
- Login to the Central Registry, and authenticate the `cue` command | ||
- Create a CUE module that depends on an existing, well-known module | ||
- Use `cue mod tidy` to fetch and organise your module's dependencies | ||
- Load your CUE using the Go API working in a modules-aware mode | ||
|
||
{{< info >}} | ||
This tutorial describes an experimental feature whose details are subject to change. | ||
{{< /info >}} | ||
|
||
## Prerequisites | ||
|
||
- **Access to the [Central Registry](https://registry.cue.works)** -- if you | ||
need to practise using the Central Registry, then first follow the | ||
tutorial: [Working with the Central Registry]({{< relref "docs/tutorial/working-with-the-central-registry" >}}) | ||
- **A tool to edit text files** -- any text editor you have will be fine; | ||
for example: [VSCode](https://code.visualstudio.com/) or [Vim](https://neovim.io/) | ||
- **A command terminal** -- the `cue` command works on all platforms; | ||
use any terminal on Linux or macOS, or PowerShell, `cmd.exe` or | ||
[WSL](https://learn.microsoft.com/en-us/windows/wsl/install) on Windows. | ||
- **An installed `go` binary** -- [installation details](https://go.dev/doc/install) | ||
- **An installed `cue` binary** -- [installation details]({{< relref "/docs/introduction/installation" >}}) | ||
|
||
## Set up the `cue` command | ||
|
||
{{{with step}}} | ||
Enable the modules experiment: | ||
|
||
{{{with script "en" "enable modules"}}} | ||
export CUE_EXPERIMENT=modules | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Authenticate the `cue` command with the Central Registry: | ||
|
||
{{{with script "en" "#norun cue login"}}} | ||
#norun | ||
cue login | ||
{{{end}}} | ||
|
||
Later in this tutorial the `cue` command will fetch a well-known module from | ||
the Central Registry, which requires authentication. | ||
{{{end}}} | ||
|
||
## Create a CUE module | ||
|
||
{{{with step}}} | ||
Initialize a new main CUE module in an empty directory: | ||
|
||
{{{with script "en" "cue mod init"}}} | ||
cue mod init an.example/config@v0 | ||
{{{end}}} | ||
|
||
You won't publish this module, so the name you give it is unimportant. | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Create the file `main.cue`, holding the code for the main module: | ||
|
||
{{{with upload "en" "initial main.cue"}}} | ||
-- main.cue -- | ||
package config | ||
|
||
import "github.com/cue-labs/examples/frostyconfig@v0" | ||
|
||
config: frostyconfig.#Config & { | ||
appName: "alpha" | ||
port: 80 | ||
features: logging: true | ||
} | ||
{{{end}}} | ||
|
||
Your main module defines some concrete values for a configuration, | ||
constrained by the `frostyconfig.#Config` schema. | ||
{{{end}}} | ||
|
||
{{< info >}} | ||
Your module imports and uses the `frostyconfig` package first introduced in the tutorial: | ||
[Working with a custom registry]({{< relref "docs/tutorial/working-with-a-custom-module-registry" >}}). | ||
You don't need to follow that tutorial right now - it's only mentioned for context. | ||
{{< /info >}} | ||
|
||
{{{with step}}} | ||
Ensure the CUE module is tidy: | ||
|
||
{{{with script "en" "initial cue mod tidy"}}} | ||
cue mod tidy | ||
{{{end}}} | ||
|
||
This fetches the `frostyconfig` module (and any dependencies it might have) | ||
from the Central Registry. | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Export the configuration from your CUE module: | ||
|
||
{{{with script "en" "first export"}}} | ||
cue export | ||
{{{end}}} | ||
|
||
This export shows that your CUE is valid and you can successfully use a | ||
dependency from the Central Registry. | ||
{{{end}}} | ||
|
||
## Create a Go module and program | ||
|
||
{{{with _script_ "en" "HIDDEN unset CUE_EXPERIMENT so Go code's behaviour can't rely on it"}}} | ||
unset CUE_EXPERIMENT | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Initialize a Go module for your program: | ||
|
||
{{{with script "en" "go mod init"}}} | ||
#ellipsis 0 | ||
go mod init an.example/config | ||
{{{end}}} | ||
|
||
You won't publish this module, so the name you give it is unimportant. | ||
{{{end}}} | ||
|
||
{{{with step}}} | ||
Create the file `main.go` containing this Go program: | ||
|
||
{{{with upload "en" "initial go code"}}} | ||
-- main.go -- | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"cuelang.org/go/cue" | ||
"cuelang.org/go/cue/cuecontext" | ||
"cuelang.org/go/cue/load" | ||
"cuelang.org/go/mod/modconfig" | ||
) | ||
|
||
func main() { | ||
ctx := cuecontext.New() | ||
|
||
// Create a registry client. Passing a nil config | ||
// will give us client that behaves like the cue command. | ||
reg, err := modconfig.NewRegistry(nil) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Load the package from the current directory. | ||
// We don't need to specify a Config in this example. | ||
insts := load.Instances([]string{"."}, &load.Config{ | ||
Registry: reg, | ||
}) | ||
|
||
// The current directory just has one file without any build tags, | ||
// and that file belongs to the example package, so we get a single | ||
// instance as a result. | ||
v := ctx.BuildInstance(insts[0]) | ||
if err := v.Err(); err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Lookup the 'config' field and print it out | ||
config := v.LookupPath(cue.ParsePath("config")) | ||
fmt.Println(config) | ||
} | ||
{{{end}}} | ||
|
||
This program loads the CUE package in the current directory, | ||
and then prints a message based on the `config` field. | ||
{{{end}}} | ||
|
||
{{{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}}} | ||
|
||
You can use `@latest` in place of the specific version mentioned here. | ||
{{{end}}} | ||
|
||
## Run the Go program | ||
|
||
{{{with step}}} | ||
Run the Go program: | ||
|
||
{{{with script "en" "go run"}}} | ||
go run . | ||
{{{end}}} | ||
{{{end}}} | ||
|
||
## Summary | ||
|
||
Well done - you've finished this tutorial! In completing it, you: | ||
|
||
- **created a main module** that depends on a well-known module from the Central Registry, and | ||
- **used the Go API to load the main module**, transparently using the module's dependencies. | ||
|
||
## Related content | ||
|
||
- {{< linkto/related/reference "modules" >}} | ||
- {{< linkto/related/tutorial "working-with-a-custom-module-registry" >}} |
127 changes: 127 additions & 0 deletions
127
content/docs/tutorial/using-modules-with-go-api/gen_cache.cue
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,127 @@ | ||
package site | ||
{ | ||
content: { | ||
docs: { | ||
tutorial: { | ||
"using-modules-with-go-api": { | ||
page: { | ||
cache: { | ||
upload: { | ||
"initial main.cue": "LqMDMqBvt0Ctp5zTY2qrIb7JMj7m+v2m4Mt9Oq+4ZPw=" | ||
"initial go code": "nzL9ZkY5KwTMIqy4Iuwpt37CQL7aKRI+huoSixMTqEk=" | ||
} | ||
multi_step: { | ||
hash: "EC6V042M6UT9TPSI408P8HKJELI13N2KUU56B67IKTUVSUFRJKB0====" | ||
scriptHash: "RFAN5OA0N7FHCG58RI26POLSG0QQMN9PS72O0V65QH0EA4FU1G00====" | ||
steps: [{ | ||
doc: "" | ||
cmd: "export GOMODCACHE=/caches/gomodcache" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "export GOCACHE=/caches/gobuild" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "export PATH=/cues/v0.8.2:$PATH" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "mkdir -p $HOME/.config/cue" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: """ | ||
cat <<EOD >$HOME/.config/cue/logins.json | ||
{"registries":{"registry.cue.works":{"access_token":"${TEST_USER_AUTHN_CUE_USER_NEW}","token_type":"Bearer"}}} | ||
EOD | ||
""" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "export CUE_EXPERIMENT=modules" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "cue mod init an.example/config@v0" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "cue mod tidy" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "" | ||
cmd: "cue export" | ||
exitCode: 0 | ||
output: """ | ||
{ | ||
"config": { | ||
"appName": "alpha", | ||
"port": 80, | ||
"features": { | ||
"logging": true | ||
} | ||
} | ||
} | ||
""" | ||
}, { | ||
doc: "" | ||
cmd: "unset CUE_EXPERIMENT" | ||
exitCode: 0 | ||
output: "" | ||
}, { | ||
doc: "#ellipsis 0" | ||
cmd: "go mod init an.example/config" | ||
exitCode: 0 | ||
output: """ | ||
... | ||
""" | ||
}, { | ||
doc: "#ellipsis 0" | ||
cmd: "go get cuelang.org/go@v0.8.2" | ||
exitCode: 0 | ||
output: """ | ||
... | ||
""" | ||
}, { | ||
doc: "#ellipsis 0" | ||
cmd: "go mod tidy" | ||
exitCode: 0 | ||
output: """ | ||
... | ||
""" | ||
}, { | ||
doc: "" | ||
cmd: "go run ." | ||
exitCode: 0 | ||
output: """ | ||
{ | ||
\tappName: "alpha" | ||
\tport: 80 | ||
\tfeatures: { | ||
\t\tlogging: true | ||
\t} | ||
} | ||
""" | ||
}] | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
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,5 @@ | ||
package site | ||
|
||
content: docs: tutorial: "using-modules-with-go-api": page: { | ||
testUserAuthn: ["cue-user-new"] | ||
} |
Oops, something went wrong.