Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

load: AllCueFiles parameter is ignored in 0.11.2 but it works in 0.8.2 #3700

Open
sahroshan opened this issue Jan 24, 2025 · 1 comment
Open
Labels
NeedsInvestigation Triage Requires triage/attention

Comments

@sahroshan
Copy link

What version of CUE are you using (cue version)?

$ cue version
0.11.2

Does this issue reproduce with the latest stable release?

yes

What did you do?

I found a regression in load behavior between 0.8.2 and 0.11.2. In 0.11.2, the AllCUEFiles: true setting is ignored. This setting was respected in 0.8.2.

Description:

If there is a package that is dependent on another package having @if then in 0.8.2 the load return the cue value but 0.11.2 raises error.

In below example:

package core is dependent on dummy package.
the dummy package is dependent on workspace/output package. But the workspace/output package has 2 files starting with @if .
How can I evaluate core package without knowing all the @if tags used in the module?

package main

import (
	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/load"
	"path"

	"fmt"
)

var packageFiles = map[string][]byte{
	"cue.mod/module.cue": []byte(`
module: "test.org"
language: version: "v0.11.1"
`),

	"core/core.cue": []byte(`
package core
import "test.org/dummy"
name: dummy.name
cloud_kind: string @tag(cloud_kind)
configs: {
	dummy: {
		package_path: "dummy"
        extension: ".yaml"
		tags: {
			cloud_kind: string @tag(cloud_kind)
		}
		if_tags: [cloud_kind]
	}
}
`),

	"dummy/dummy.cue": []byte(`
package dummy
import "strings"
import "test.org/workspace/output"
name: string
ws_region: output.region
ws_name: strings.ToUpper(name)
cloud_kind: string @tag(cloud_kind)
`),

	"workspace/output/aws.cue": []byte(`
@if(aws)
package output
name: string
region: string
`),

	"workspace/output/gcp.cue": []byte(`
@if(gcp)
package output
name: string
zone: string
`),
}

func main() {
	cuectx := cuecontext.New()
	tags := map[string]string{
		"cloud_kind": "aws",
	}
	val, err := aload(cuectx, tags, nil, packageFiles, []string{"./core/core.cue"})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(val)
}

func aload(cuectx *cue.Context, tags map[string]string, ifTags []string, cueFiles map[string][]byte, entryPoints []string) (cue.Value, error) {
	var cueTags []string
	if tags != nil {
		for key, value := range tags {
			cueTags = append(cueTags, fmt.Sprintf("%s=%s", key, value))
		}
	}
	if ifTags != nil {
		cueTags = append(cueTags, ifTags...)
	}
	rootDir := "/tmp/cues"
	conf := load.Config{
		Dir:         rootDir,
		Tags:        cueTags,
		Overlay:     make(map[string]load.Source),
		AllCUEFiles: true,
	}
	for filename, data := range cueFiles {
		conf.Overlay[path.Join(rootDir, filename)] = load.FromBytes(data)
	}
	var instancesToLoad []string
	for _, filename := range entryPoints {
		instancesToLoad = append(instancesToLoad, path.Join(rootDir, filename))
	}
	var val cue.Value
	insts := load.Instances(instancesToLoad, &conf)
	for _, inst := range insts {
		if inst.Err != nil {
			return val, inst.Err
		}
		val = cuectx.BuildInstance(inst)
	}
	if val.Err() != nil {
		er := errors.Details(val.Err(), &errors.Config{Cwd: rootDir})
		return val, errors.New(er)
	}
	return val, nil
} 

What did you expect to see?

output in 0.8.2

{
	name:       string
	cloud_kind: "aws"
	configs: {
		dummy: {
			package_path: "dummy"
			extension:    ".yaml"
			tags: {
				cloud_kind: "aws"
			}
			if_tags: ["aws"]
		}
	}
}

What did you see instead?

output in 0.11.2

import failed: import failed: /tmp/cues/dummy/dummy.cue:4:8: cannot find package "test.org/workspace/output": no files in package directory with package name "output" (2 files were excluded)
@sahroshan sahroshan added NeedsInvestigation Triage Requires triage/attention labels Jan 24, 2025
@myitcv
Copy link
Member

myitcv commented Feb 4, 2025

This is a change that was introduced in v0.10.0, and documented at https://cuelang.org/docs/concept/faq/new-modules-vs-old-modules/#what-about-tag-injection

This bisects to 79c1739. cc @rogpeppe for comments on that change with respect to the code in this repro.

@sahroshan - you clearly relied on this behaviour before. Please can you help understand your use case a bit more if this is a breaking change for you?

Rewriting the repro slightly to make bisecting easier:

go mod tidy
go run .
cmp stdout stdout.golden

-- go.mod --
module mod.example

go 1.22.0

require cuelang.org/go v0.8.2

-- main.go --
package main

import (
	"path"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/load"

	"fmt"
)

var packageFiles = map[string][]byte{
	"cue.mod/module.cue": []byte(`
module: "test.org"
language: version: "v0.8.2"
`),

	"core/core.cue": []byte(`
package core
import "test.org/dummy"
name: dummy.name
cloud_kind: string @tag(cloud_kind)
configs: {
	dummy: {
		package_path: "dummy"
        extension: ".yaml"
		tags: {
			cloud_kind: string @tag(cloud_kind)
		}
		if_tags: [cloud_kind]
	}
}
`),

	"dummy/dummy.cue": []byte(`
package dummy
import "strings"
import "test.org/workspace/output"
name: string
ws_region: output.region
ws_name: strings.ToUpper(name)
cloud_kind: string @tag(cloud_kind)
`),

	"workspace/output/aws.cue": []byte(`
@if(aws)
package output
name: string
region: string
`),

	"workspace/output/gcp.cue": []byte(`
@if(gcp)
package output
name: string
zone: string
`),
}

func main() {
	cuectx := cuecontext.New()
	tags := map[string]string{
		"cloud_kind": "aws",
	}
	val, err := aload(cuectx, tags, nil, packageFiles, []string{"./core/core.cue"})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(val)
}

func aload(cuectx *cue.Context, tags map[string]string, ifTags []string, cueFiles map[string][]byte, entryPoints []string) (cue.Value, error) {
	var cueTags []string
	if tags != nil {
		for key, value := range tags {
			cueTags = append(cueTags, fmt.Sprintf("%s=%s", key, value))
		}
	}
	if ifTags != nil {
		cueTags = append(cueTags, ifTags...)
	}
	rootDir := "/tmp/cues"
	conf := load.Config{
		Dir:         rootDir,
		Tags:        cueTags,
		Overlay:     make(map[string]load.Source),
		AllCUEFiles: true,
	}
	for filename, data := range cueFiles {
		conf.Overlay[path.Join(rootDir, filename)] = load.FromBytes(data)
	}
	var instancesToLoad []string
	for _, filename := range entryPoints {
		instancesToLoad = append(instancesToLoad, path.Join(rootDir, filename))
	}
	var val cue.Value
	insts := load.Instances(instancesToLoad, &conf)
	for _, inst := range insts {
		if inst.Err != nil {
			return val, inst.Err
		}
		val = cuectx.BuildInstance(inst)
	}
	if val.Err() != nil {
		er := errors.Details(val.Err(), &errors.Config{Cwd: rootDir})
		return val, errors.New(er)
	}
	return val, nil
}
-- stdout.golden --
{
	name:       string
	cloud_kind: "aws"
	configs: {
		dummy: {
			package_path: "dummy"
			extension:    ".yaml"
			tags: {
				cloud_kind: "aws"
			}
			if_tags: ["aws"]
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Triage Requires triage/attention
Projects
None yet
Development

No branches or pull requests

2 participants