Closed
Description
What version of CUE are you using (cue version
)?
Originally v0.4.1 darwin/amd64
, but tested all versions back to a known working version (v0.3.2 darwin/amd64
).
Specifically, this seems to be a regression since #9366, which was released in the 0.4.0-alpha.1
release.
Does this issue reproduce with the latest release?
Yes.
What did you do?
Given this CUE file:
import (
"list"
)
#Check: {
ok: true
...
}
#Role: "EM" | "IC" | "TL"
#Team: {
members: [Username=string]: #TeamMember & {email: string | *"\(Username)@acme.com"}
}
#TeamMember: {
email: string & !=""
role: [...#Role] | *["IC"]
}
checks: [string]: #Check
team: #Team
checks: {
enoughMembers: {
ok: len(team.members) >= 1
}
hasManager: {
ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) >= 1
}
}
and data from this JSON file:
{
"team": {
"members": {
"alice": {
"email": "[email protected]",
"role": ["EM"]
},
"bob": {
"role": ["TL"]
},
"clyde": {}
}
}
}
I ran:
cue eval team.cue team.json -e checks
What did you expect to see?
I expect this to evaluate to:
enoughMembers: {
ok: true
}
hasManager: {
ok: true
}
As the number of team members correctly evaluates to three:
$ cue eval team.cue team.json -e 'len(team.members)'
3
as does the length of managers, to one:
$ cue eval team.cue team.json -e 'len([for m in team.members if list.Contains(m.role, "EM") {m}])'
1
Both of which are obviously >= 1
.
What did you see instead?
When unifying the result of this expression with #Check.ok
(true
), a conflict occurs:
checks.enoughMembers.ok: conflicting values true and false:
./team.cue:6:6
./team.cue:21:19
./team.cue:27:7
checks.hasManager.ok: conflicting values true and false:
./team.cue:6:6
./team.cue:21:19
./team.cue:31:7
I found that this works:
checks: {
enoughMembers: {
ok: len(team.members) >= 0
}
hasManager: {
ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) >= 0
}
}
It is expected that one of the following evaluates correctly, given that >= 0
works, but neither of these work:
checks: {
enoughMembers: {
ok: len(team.members) == 0
}
hasManager: {
ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) == 0
}
}
checks: {
enoughMembers: {
ok: len(team.members) > 0
}
hasManager: {
ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) > 0
}
}
The same check, written differently, works as expected:
checks: {
enoughMembers: {
ok: or([ for m in team.members {true}])
}
hasManager: {
ok: or([ for m in team.members {list.Contains(m.role, "EM")}])
}
}
Activity