apple / pkl-pantry

Shared Pkl packages
Apache License 2.0
229 stars 31 forks source link

[JSON Schema Contrib] Failure importing GitHub Workflow Schema #23

Open johnallen3d opened 4 months ago

johnallen3d commented 4 months ago

I'm trying to use the latest version of org.json_schema.contrib to generate a Pkl template from the GitHub Workflow Json Schema.

When I execute:

pkl \
  eval package://pkg.pkl-lang.org/pkl-pantry/org.json_schema.contrib@1.0.1#/generate.pkl \
  --multiple-file-output-path . \
  --property source="https://json.schemastore.org/github-workflow.json"

I see the following error report:

–– Pkl Error ––
A stack overflow occurred.

581 | members {
      ^^^^^^^^^
at org.json_schema.contrib.internal.TypesGenerator#generateUnionType.members (https://github.com/apple/pkl-pantry/blob/org.json_schema.contrib@1.0.1/packages/org.json_schema.contrib/internal/TypesGenerator.pkl#L581-594)

72 | let (childrenRendered = members.toList().map((t) -> t.render(currentIndent)))
                             ^^^^^^^
at pkl.experimental.syntax.TypeNode#UnionTypeNode.render (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeNode.pkl#L72-72)

┌─ 3824 repetitions of:
│ 
│ 49 | else "<" + typeArguments.toList().map((t) -> t.render(currentIndent)).join(", ") + ">"
│                                                   ^^^^^^^^^^^^^^^^^^^^^^^
│ at pkl.experimental.syntax.TypeNode#DeclaredTypeNode.renderTypeArguments.<function#1> (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeNode.pkl#L49-49)
│ 
│ 49 | else "<" + typeArguments.toList().map((t) -> t.render(currentIndent)).join(", ") + ">"
│                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│ at pkl.experimental.syntax.TypeNode#DeclaredTypeNode.renderTypeArguments (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeNode.pkl#L49-49)
│ 
│ 51 | function render(currentIndent: String) = name.render(currentIndent) + renderTypeArguments(currentIndent)
│                                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│ at pkl.experimental.syntax.TypeNode#DeclaredTypeNode.render (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeNode.pkl#L51-51)
│ 
│ 72 | let (childrenRendered = members.toList().map((t) -> t.render(currentIndent)))
│                                                          ^^^^^^^^^^^^^^^^^^^^^^^
│ at pkl.experimental.syntax.TypeNode#UnionTypeNode.render.<function#3> (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeNode.pkl#L72-72)
│ 
│ 72 | let (childrenRendered = members.toList().map((t) -> t.render(currentIndent)))
│                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│ at pkl.experimental.syntax.TypeNode#UnionTypeNode.render (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeNode.pkl#L72-72)
└─

40 | type.render(currentIndent)
     ^^^^^^^^^^^^^^^^^^^^^^^^^^
at pkl.experimental.syntax.TypeAliasNode#renderAlias[#4] (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeAliasNode.pkl#L40-40)

35 | local function renderAlias(currentIndent: String) = new Listing {
                                                         ^^^^^^^^^^^^^
at pkl.experimental.syntax.TypeAliasNode#renderAlias (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeAliasNode.pkl#L35-41)

46 | currentIndent + renderAlias(currentIndent)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
at pkl.experimental.syntax.TypeAliasNode#render (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/TypeAliasNode.pkl#L46-46)

122 | typealiases?.toList()?.map((t) -> t.render(currentIndent))?.join("\n\n")
                                        ^^^^^^^^^^^^^^^^^^^^^^^
at pkl.experimental.syntax.ModuleNode#render.<function#2> (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/ModuleNode.pkl#L122-122)

122 | typealiases?.toList()?.map((t) -> t.render(currentIndent))?.join("\n\n")
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
at pkl.experimental.syntax.ModuleNode#render (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/ModuleNode.pkl#L122-122)

36 | text = render("")
            ^^^^^^^^^^
at pkl.experimental.syntax.Node#output.text (https://github.com/apple/pkl-pantry/blob/pkl.experimental.syntax@1.0.0/packages/pkl.experimental.syntax/Node.pkl#L36-36)

I'm not quite fluent enough with Pkl to understand where the error is occurring but I thought I'd share in case others are running into this.

StefMa commented 4 months ago

While working on my pkl GitHub Action module I ran into the same(?) problem. See also https://github.com/apple/pkl/discussions/263#discussioncomment-8642807

bioball commented 4 months ago

Looks like this is because of a recursive reference:

    "configuration": {
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "number"
        },
        {
          "type": "boolean"
        },
        {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/configuration"
          }
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/definitions/configuration"
          }
        }
      ]
    },

At the moment, Pkl's typealiases cannot be cyclic. Ideally, this turns into:

typealias Configuration = String|Boolean|Mapping<String, Configuration>|Listing<Configuration>

Side note: this means that arbitrarily nested values are accepted Configuration values, e.g. [[[[[[[1]]]]]]].