cuelang.org/go@v0.10.1/cue/load/example_test.go (about) 1 // Copyright 2023 The CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package load_test 16 17 import ( 18 "fmt" 19 "os" 20 "path/filepath" 21 22 "golang.org/x/tools/txtar" 23 24 "cuelang.org/go/cue" 25 "cuelang.org/go/cue/cuecontext" 26 "cuelang.org/go/cue/load" 27 "cuelang.org/go/internal/cueexperiment" 28 "cuelang.org/go/internal/registrytest" 29 ) 30 31 // Note that these examples may not be runnable on pkg.go.dev, 32 // as they expect files to be present inside testdata. 33 // Using cue/load with real files on disk keeps the example realistic 34 // and enables the user to easily tweak the code to their needs. 35 36 func Example() { 37 // Load the package "example" relative to the directory testdata/testmod. 38 // Akin to loading via: cd testdata/testmod && cue export ./example 39 insts := load.Instances([]string{"./example"}, &load.Config{ 40 Dir: filepath.Join("testdata", "testmod"), 41 Env: []string{}, // or nil to use os.Environ 42 }) 43 44 // testdata/testmod/example just has one file without any build tags, 45 // so we get a single instance as a result. 46 fmt.Println("Number of instances:", len(insts)) 47 inst := insts[0] 48 if err := inst.Err; err != nil { 49 fmt.Println(err) 50 return 51 } 52 fmt.Println("Instance module:", inst.Module) 53 fmt.Println("Instance import path:", inst.ImportPath) 54 fmt.Println() 55 56 // Inspect the syntax trees. 57 fmt.Println("Source files:") 58 for _, file := range inst.Files { 59 fmt.Println(filepath.Base(file.Filename), "with", len(file.Decls), "declarations") 60 } 61 fmt.Println() 62 63 // Build the instance into a value. 64 // We can also use BuildInstances for many instances at once. 65 ctx := cuecontext.New() 66 val := ctx.BuildInstance(inst) 67 if err := val.Err(); err != nil { 68 fmt.Println(err) 69 return 70 } 71 72 // Inspect the contents of the value, such as one string field. 73 fieldStr, err := val.LookupPath(cue.MakePath(cue.Str("output"))).String() 74 if err != nil { 75 fmt.Println(err) 76 return 77 } 78 fmt.Println("Field string:", fieldStr) 79 80 // Output: 81 // Number of instances: 1 82 // Instance module: mod.test/test@v0 83 // Instance import path: mod.test/test/example@v0 84 // 85 // Source files: 86 // example.cue with 3 declarations 87 // 88 // Field string: Hello Joe 89 } 90 91 func Example_externalModules() { 92 // setUpModulesExample starts a temporary in-memory registry, 93 // populates it with an example module, and sets CUE_REGISTRY 94 // to refer to it 95 env, cleanup := setUpModulesExample() 96 defer cleanup() 97 98 insts := load.Instances([]string{"."}, &load.Config{ 99 Dir: filepath.Join("testdata", "testmod-external"), 100 Env: env, // or nil to use os.Environ 101 }) 102 inst := insts[0] 103 if err := inst.Err; err != nil { 104 fmt.Println(err) 105 return 106 } 107 ctx := cuecontext.New() 108 val := ctx.BuildInstance(inst) 109 if err := val.Err(); err != nil { 110 fmt.Println(err) 111 return 112 } 113 114 // Inspect the contents of the value, such as one string field. 115 fieldStr, err := val.LookupPath(cue.MakePath(cue.Str("output"))).String() 116 if err != nil { 117 fmt.Println(err) 118 return 119 } 120 fmt.Println("Field string:", fieldStr) 121 // Output: 122 // Field string: hello, world 123 } 124 125 func setUpModulesExample() (env []string, cleanup func()) { 126 registryFS, err := txtar.FS(txtar.Parse([]byte(` 127 -- foo.example_v0.0.1/cue.mod/module.cue -- 128 module: "foo.example@v0" 129 language: version: "v0.8.0" 130 -- foo.example_v0.0.1/bar/bar.cue -- 131 package bar 132 133 value: "world" 134 `))) 135 if err != nil { 136 panic(err) 137 } 138 registry, err := registrytest.New(registryFS, "") 139 if err != nil { 140 panic(err) 141 } 142 cleanups := []func(){registry.Close} 143 env = append(env, "CUE_REGISTRY="+registry.Host()+"+insecure") 144 dir, err := os.MkdirTemp("", "") 145 if err != nil { 146 panic(err) 147 } 148 env = append(env, "CUE_CACHE_DIR="+dir) 149 oldModulesExperiment := cueexperiment.Flags.Modules 150 cueexperiment.Flags.Modules = true 151 cleanups = append(cleanups, func() { 152 cueexperiment.Flags.Modules = oldModulesExperiment 153 }) 154 return env, func() { 155 for i := len(cleanups) - 1; i >= 0; i-- { 156 cleanups[i]() 157 } 158 } 159 }