cue-lang/cue

encoding/openapi: regression in handling of disjunctions

Opened this issue · 2 comments

Originally opened by @eadlam in cuelang/cue#1058

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

$ cue version
cue version v0.4.0 linux/amd64

Does this issue reproduce with the latest release?

Yes

What did you do?

main.cue

#A: {}
#blocks: a: {a: #A}

#B: {}
#blocks: b: {b: #B}

#Block: or([for k, v in #blocks {v}])
$ cue def main.cue -o openapi:example.openapi.json

What did you expect to see?

Note: this works correctly in v0.4.0-rc.1
example.openapi.json

{
    "openapi": "3.0.0",
    "info": {
        "title": "Generated by cue.",
        "version": "no version"
    },
    "paths": {},
    "components": {
        "schemas": {
            "A": {
                "type": "object"
            },
            "B": {
                "type": "object"
            },
            "Block": {
                "type": "object",
                "oneOf": [
                    {
                        "required": [
                            "a"
                        ],
                        "properties": {
                            "a": {
                                "$ref": "#/components/schemas/A"
                            }
                        }
                    },
                    {
                        "required": [
                            "b"
                        ],
                        "properties": {
                            "b": {
                                "$ref": "#/components/schemas/B"
                            }
                        }
                    }
                ]
            },
            ...
        }
    }
}

What did you see instead?

example.openapi.json

{
    "openapi": "3.0.0",
    "info": {
        "title": "Generated by cue.",
        "version": "no version"
    },
    "paths": {},
    "components": {
        "schemas": {
            "A": {
                "type": "object"
            },
            "B": {
                "type": "object"
            },
            "Block": {
                "type": "object",
                "oneOf": [
                    {
                        "$ref": "#/components/schemas/_.v"
                    },
                    {
                        "$ref": "#/components/schemas/_.v"
                    }
                ]
            },
            ...
        }
    }
}

Original reply by @eadlam in cuelang/cue#1058 (comment)

This worked correctly on v0.4.0-rc.1 but fails on v0.4.0.

Thanks very much @eadlam for raising this. Apologies again for the migration-related delay (#1078) in getting round to looking at this.

I can confirm your analysis above:

exec cue export main.cue --out openapi -o openapi.json
cmp openapi.json openapi.json.golden

-- main.cue --
#A: {}

#blocks: a: {a: #A}

#B: {}

#blocks: b: {b: #B}

#Block: or([ for k, v in #blocks {v}])
-- openapi.json.golden --
{
    "openapi": "3.0.0",
    "info": {
        "title": "Generated by cue.",
        "version": "no version"
    },
    "paths": {},
    "components": {
        "schemas": {
            "A": {
                "type": "object"
            },
            "B": {
                "type": "object"
            },
            "Block": {
                "type": "object",
                "oneOf": [
                    {
                        "required": [
                            "a"
                        ],
                        "properties": {
                            "a": {
                                "$ref": "#/components/schemas/A"
                            }
                        }
                    },
                    {
                        "required": [
                            "b"
                        ],
                        "properties": {
                            "b": {
                                "$ref": "#/components/schemas/B"
                            }
                        }
                    }
                ]
            },
            "blocks": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "object",
                        "required": [
                            "a"
                        ],
                        "properties": {
                            "a": {
                                "$ref": "#/components/schemas/A"
                            }
                        }
                    },
                    "b": {
                        "type": "object",
                        "required": [
                            "b"
                        ],
                        "properties": {
                            "b": {
                                "$ref": "#/components/schemas/B"
                            }
                        }
                    }
                },
                "allOf": [
                    {
                        "required": [
                            "a"
                        ]
                    },
                    {
                        "required": [
                            "b"
                        ]
                    }
                ]
            }
        }
    }
}

Bisected this down to 37bf801.