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  }