...

Source file src/cuelang.org/go/cue/load/example_test.go

Documentation: cuelang.org/go/cue/load

     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  	"cuelang.org/go/internal/txtarfs"
    30  )
    31  
    32  // Note that these examples may not be runnable on pkg.go.dev,
    33  // as they expect files to be present inside testdata.
    34  // Using cue/load with real files on disk keeps the example realistic
    35  // and enables the user to easily tweak the code to their needs.
    36  
    37  func Example() {
    38  	// Load the package "example" relative to the directory testdata/testmod.
    39  	// Akin to loading via: cd testdata/testmod && cue export ./example
    40  	insts := load.Instances([]string{"./example"}, &load.Config{
    41  		Dir: filepath.Join("testdata", "testmod"),
    42  		Env: []string{}, // or nil to use os.Environ
    43  	})
    44  
    45  	// testdata/testmod/example just has one file without any build tags,
    46  	// so we get a single instance as a result.
    47  	fmt.Println("Number of instances:", len(insts))
    48  	inst := insts[0]
    49  	if err := inst.Err; err != nil {
    50  		fmt.Println(err)
    51  		return
    52  	}
    53  	fmt.Println("Instance module:", inst.Module)
    54  	fmt.Println("Instance import path:", inst.ImportPath)
    55  	fmt.Println()
    56  
    57  	// Inspect the syntax trees.
    58  	fmt.Println("Source files:")
    59  	for _, file := range inst.Files {
    60  		fmt.Println(filepath.Base(file.Filename), "with", len(file.Decls), "declarations")
    61  	}
    62  	fmt.Println()
    63  
    64  	// Build the instance into a value.
    65  	// We can also use BuildInstances for many instances at once.
    66  	ctx := cuecontext.New()
    67  	val := ctx.BuildInstance(inst)
    68  	if err := val.Err(); err != nil {
    69  		fmt.Println(err)
    70  		return
    71  	}
    72  
    73  	// Inspect the contents of the value, such as one string field.
    74  	fieldStr, err := val.LookupPath(cue.MakePath(cue.Str("output"))).String()
    75  	if err != nil {
    76  		fmt.Println(err)
    77  		return
    78  	}
    79  	fmt.Println("Field string:", fieldStr)
    80  
    81  	// Output:
    82  	// Number of instances: 1
    83  	// Instance module: mod.test/test
    84  	// Instance import path: mod.test/test/example
    85  	//
    86  	// Source files:
    87  	// example.cue with 3 declarations
    88  	//
    89  	// Field string: Hello Joe
    90  }
    91  
    92  func Example_externalModules() {
    93  	// setUpModulesExample starts a temporary in-memory registry,
    94  	// populates it with an example module, and sets CUE_REGISTRY
    95  	// to refer to it
    96  	env, cleanup := setUpModulesExample()
    97  	defer cleanup()
    98  
    99  	insts := load.Instances([]string{"."}, &load.Config{
   100  		Dir: filepath.Join("testdata", "testmod-external"),
   101  		Env: env, // or nil to use os.Environ
   102  	})
   103  	inst := insts[0]
   104  	if err := inst.Err; err != nil {
   105  		fmt.Println(err)
   106  		return
   107  	}
   108  	ctx := cuecontext.New()
   109  	val := ctx.BuildInstance(inst)
   110  	if err := val.Err(); err != nil {
   111  		fmt.Println(err)
   112  		return
   113  	}
   114  
   115  	// Inspect the contents of the value, such as one string field.
   116  	fieldStr, err := val.LookupPath(cue.MakePath(cue.Str("output"))).String()
   117  	if err != nil {
   118  		fmt.Println(err)
   119  		return
   120  	}
   121  	fmt.Println("Field string:", fieldStr)
   122  	// Output:
   123  	// Field string: hello, world
   124  }
   125  
   126  func setUpModulesExample() (env []string, cleanup func()) {
   127  	registryArchive := txtar.Parse([]byte(`
   128  -- foo.example_v0.0.1/cue.mod/module.cue --
   129  module: "foo.example@v0"
   130  -- foo.example_v0.0.1/bar/bar.cue --
   131  package bar
   132  
   133  value: "world"
   134  `))
   135  
   136  	registry, err := registrytest.New(txtarfs.FS(registryArchive), "")
   137  	if err != nil {
   138  		panic(err)
   139  	}
   140  	cleanups := []func(){registry.Close}
   141  	env = append(env, "CUE_REGISTRY="+registry.Host()+"+insecure")
   142  	dir, err := os.MkdirTemp("", "")
   143  	if err != nil {
   144  		panic(err)
   145  	}
   146  	env = append(env, "CUE_CACHE_DIR="+dir)
   147  	oldModulesExperiment := cueexperiment.Flags.Modules
   148  	cueexperiment.Flags.Modules = true
   149  	cleanups = append(cleanups, func() {
   150  		cueexperiment.Flags.Modules = oldModulesExperiment
   151  	})
   152  	return env, func() {
   153  		for i := len(cleanups) - 1; i >= 0; i-- {
   154  			cleanups[i]()
   155  		}
   156  	}
   157  }
   158  

View as plain text