cue-lang / cue

The home of the CUE language! Validate and define text-based and dynamic configuration
https://cuelang.org
Apache License 2.0
5.03k stars 287 forks source link

cmd/cue: eval of non-CUE files with explicit -p has no effect #1191

Open jpluscplusm opened 3 years ago

jpluscplusm commented 3 years ago

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

$ cue version
cue version 0.4.0 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

$ cat template.cue 
package config
foo: {
        a_value: true
        name:    user.name
}

$ cat input.cue 
package config
user: {
        name: "name-from-cue"
}

$ cat input.yml 
---
user:
  name: name-from-yaml

$ cue eval template.cue input.cue 
foo: {
    a_value: true
    name:    "name-from-cue"
}
user: {
    name: "name-from-cue"
}

# Expected reference failure
$ cue eval template.cue input.yml 
foo.name: reference "user" not found:
    ./template.cue:5:11

# Unexpected reference failure
$ cue eval template.cue input.yml --package config
foo.name: reference "user" not found:
    ./template.cue:5:11

What did you expect to see?

$ cue eval template.cue input.yml --package config
foo: {
    a_value: true
    name:    "name-from-yaml"
}
user: {
    name: "name-from-yaml"
}

What did you see instead?

$ cue eval template.cue input.yml --package config
foo.name: reference "user" not found:
    ./template.cue:5:11

# tried moving --package's position, just in case ...
$ cue eval  --package config template.cue input.yml
foo.name: reference "user" not found:
    ./template.cue:5:11
verdverm commented 3 years ago

There is some definite weirdness here, even without the user reference

$ cue def 1191.cue 1191.yaml --package config
package config

user: name: "name-from-yaml"

$ cue eval 1191.cue 1191.yaml 
user: {
    name: "name-from-yaml"
}
foo: {
    a_value: true
    name:    "name-in-cue"
}

$ cue eval 1191.cue 1191.yaml --package config
user: {
    name: "name-from-yaml"
}
foo: {
    a_value: true
    name:    "name-in-cue"
}

$ cue export 1191.cue 1191.yaml 
{
    "user": {
        "name": "name-from-yaml"
    },
    "foo": {
        "a_value": true,
        "name": "name-in-cue"
    }
}

cue def has unexpected output even without the package declaration in the cue file and command line

$ cue def 1191.cue 1191.yaml
user: name: "name-from-yaml"

foo seems to be missing

myitcv commented 3 years ago

https://github.com/cue-lang/cue/issues/736 provides some context here, as does https://github.com/cue-lang/cue/commit/5c2b2815953fffc86242a68275cc90fe09d43d77 that fixed that issue. Therefore, in terms of references working/not working this is working as intended.

But note that the test associated with #736 does not include a variant for -p. Indeed all the tests associated with -p refer to use with cue import. But I can see the logic in -p being used as you have done here, @jpluscplusm, to effectively obviate the need for a cue import -p step before the cue (eval|export|...)

Will discuss with @mpvl, but on the face of things this feels like something we should support.

myitcv commented 3 years ago

A testscript reproducer of the expected behaviour for good measure:

# Referencing within the same CUE package is fine
exec cue eval template.cue input.cue
cmp stdout stdout.allcue.golden

# Referencing from CUE -> Yaml will fail
! exec cue eval template.cue input.yml
cmp stderr stderr.ymlcue.golden

# Using -p to specify the package of a non-CUE
# file feels like it should work?
exec cue eval -p config template.cue input.yml
cmp stdout stdout.allcue.golden

-- input.cue --
package config

user: {
    name: "name-from-cue"
}
-- input.yml --
---
user:
  name: name-from-yaml
-- template.cue --
package config

foo: {
    a_value: true
    name:    user.name
}
-- stdout.allcue.golden --
foo: {
    a_value: true
    name:    "name-from-cue"
}
user: {
    name: "name-from-cue"
}
-- stderr.ymlcue.golden --
foo.name: reference "user" not found:
    ./template.cue:5:11

Currently gives:

# Referencing within the same CUE package is fine (0.025s)
> exec cue eval template.cue input.cue
[stdout]
foo: {
    a_value: true
    name:    "name-from-cue"
}
user: {
    name: "name-from-cue"
}
> cmp stdout stdout.allcue.golden
# Referencing from CUE -> Yaml will fail (0.030s)
> ! exec cue eval template.cue input.yml
[stderr]
foo.name: reference "user" not found:
    ./template.cue:5:11
[exit status 1]
> cmp stderr stderr.ymlcue.golden
# Using -p to specify the package of a non-CUE
# file feels like it should work? (0.028s)
> exec cue eval -p config template.cue input.yml
[stderr]
foo.name: reference "user" not found:
    ./template.cue:5:11
[exit status 1]
FAIL: /tmp/testscript779220448/repro.txt/script.txt:11: unexpected command failure

with 0f53054d.

jpluscplusm commented 3 years ago

Thanks, @myitcv. For now, I'll jam an import step in my process.

this feels like something we should support

For clarity, I don't think I simply YOLO'd the -p in there to try and avoid an import ... I picked it up from the CLI help :-)

$ cue version
cue version 0.4.0 linux/amd64
$ cue eval --help | grep -- --package
  -p, --package string           package name for non-CUE files
myitcv commented 3 years ago

I picked it up from the CLI help :-)

Indeed, and I think that's not only a reasonable interpretation from the docs, but also something we should explicitly support. This might have worked in the past, I'm not sure. But we definitely don't have a test for it today, so all bets are off on it working by accident!