redhat-developer / yaml-language-server

Language Server for YAML Files
MIT License
1.05k stars 257 forks source link

Wrong completion inside kubernetes kamelet spec -> types #610

Closed apupier closed 2 years ago

apupier commented 2 years ago

Describe the bug

Calling completion inside objects of spec -> types, I expect having 2 items as completion (schema and mediaType).

it is working fine with a small file, when there are no elements after:

apiVersion: camel.apache.org/v1alpha1
kind: Kamelet
metadata:
  name: twitter-search-source
  labels:
    camel.apache.org/kamelet.type: "source"
spec:
  types:
    out:

it is not working with a more complex one:

apiVersion: camel.apache.org/v1alpha1
kind: Kamelet
metadata:
  name: twitter-search-source
  labels:
    camel.apache.org/kamelet.type: "source"
spec:
  definition:
    title: "Timer"
    description: "Produces periodic events with a custom payload"
    required:
      - message
    properties:
      period:
        title: Period
        description: The time interval between two events
        type: integer
        default: 1000
      message:
        title: Message
        description: The message to generate
        type: string
  types:
    out:

  flow:
    from:
      uri: timer:tick
      parameters:
        period: "{{period}}"
      steps:
        - set-body:
            constant: "{{message}}"
        - to: "kamelet:sink"

it is even providing a wrong completion: status like if it was at the indentation level 0

Expected Behavior

Have schema and mediaType completion

Current Behavior

Have a wrong completion like if it was at the indentation level 0

Steps to Reproduce

  1. Use schema:
    {
    "id": "camel.apache.org/v1alpha1@Kamelet",
    "apiVersion": "camel.apache.org/v1alpha1",
    "kind": "Kamelet",
    "description": "Kamelet is the Schema for the kamelets API",
    "type": "object",
    "properties": {
    "apiVersion": {
      "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
      "type": "string",
      "markdownDescription": "**apiVersion** (string)\n\nAPIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources"
    },
    "kind": {
      "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
      "type": "string",
      "markdownDescription": "Kamelet: Kamelet is the Schema for the kamelets API\n\n**apiVersion** (string)\n\nAPIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n\n**kind** (string)\n\nKind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n\n**metadata** (object)\n\nundefined\n\n**spec** (object)\n\nKameletSpec defines the desired state of Kamelet\n\n**status** (object)\n\nKameletStatus defines the observed state of Kamelet\n\n"
    },
    "metadata": {
      "type": "object",
      "markdownDescription": "**metadata** (object)\n\n"
    },
    "spec": {
      "description": "KameletSpec defines the desired state of Kamelet",
      "properties": {
        "authorization": {
          "description": "AuthorizationSpec is TODO (oauth information)",
          "type": "object"
        },
        "definition": {
          "description": "JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).",
          "properties": {
            "$schema": {
              "description": "JSONSchemaURL represents a schema url.",
              "type": "string"
            },
            "description": {
              "type": "string"
            },
            "example": {
              "description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
              "x-kubernetes-preserve-unknown-fields": true
            },
            "externalDocs": {
              "description": "ExternalDocumentation allows referencing an external resource for extended documentation.",
              "properties": {
                "description": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                }
              },
              "type": "object"
            },
            "id": {
              "type": "string"
            },
            "properties": {
              "additionalProperties": {
                "properties": {
                  "default": {
                    "description": "default is a default value for undefined object fields.",
                    "x-kubernetes-preserve-unknown-fields": true
                  },
                  "description": {
                    "type": "string"
                  },
                  "enum": {
                    "items": {
                      "description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
                      "x-kubernetes-preserve-unknown-fields": true
                    },
                    "type": "array"
                  },
                  "example": {
                    "description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
                    "x-kubernetes-preserve-unknown-fields": true
                  },
                  "exclusiveMaximum": {
                    "type": "boolean"
                  },
                  "exclusiveMinimum": {
                    "type": "boolean"
                  },
                  "format": {
                    "description": "format is an OpenAPI v3 format string. Unknown formats are ignored. The following formats are validated: \n - bsonobjectid: a bson object ID, i.e. a 24 characters hex string - uri: an URI as parsed by Golang net/url.ParseRequestURI - email: an email address as parsed by Golang net/mail.ParseAddress - hostname: a valid representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034]. - ipv4: an IPv4 IP as parsed by Golang net.ParseIP - ipv6: an IPv6 IP as parsed by Golang net.ParseIP - cidr: a CIDR as parsed by Golang net.ParseCIDR - mac: a MAC address as parsed by Golang net.ParseMAC - uuid: an UUID that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid3: an UUID3 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid4: an UUID4 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - uuid5: an UUID5 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - isbn: an ISBN10 or ISBN13 number string like \"0321751043\" or \"978-0321751041\" - isbn10: an ISBN10 number string like \"0321751043\" - isbn13: an ISBN13 number string like \"978-0321751041\" - creditcard: a credit card number defined by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$ with any non digit characters mixed in - ssn: a U.S. social security number following the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ - hexcolor: an hexadecimal color code like \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$ - rgbcolor: an RGB color code like rgb like \"rgb(255,255,2559\" - byte: base64 encoded binary data - password: any kind of string - date: a date string like \"2006-01-02\" as defined by full-date in RFC3339 - duration: a duration string like \"22 ns\" as parsed by Golang time.ParseDuration or compatible with Scala duration format - datetime: a date time string like \"2014-12-15T19:30:20.000Z\" as defined by date-time in RFC3339.",
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "maxItems": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "maxLength": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "maxProperties": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "maximum": {
                    "description": "A Number represents a JSON number literal.",
                    "type": "string"
                  },
                  "minItems": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "minLength": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "minProperties": {
                    "format": "int64",
                    "type": "integer"
                  },
                  "minimum": {
                    "description": "A Number represents a JSON number literal.",
                    "type": "string"
                  },
                  "multipleOf": {
                    "description": "A Number represents a JSON number literal.",
                    "type": "string"
                  },
                  "nullable": {
                    "type": "boolean"
                  },
                  "pattern": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "uniqueItems": {
                    "type": "boolean"
                  },
                  "x-descriptors": {
                    "description": "The list of descriptors that determine which UI components to use on different views",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                },
                "type": "object"
              },
              "type": "object"
            },
            "required": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "title": {
              "type": "string"
            },
            "type": {
              "type": "string"
            }
          },
          "type": "object"
        },
        "dependencies": {
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "flow": {
          "description": "Deprecated: use template",
          "type": "object",
          "x-kubernetes-preserve-unknown-fields": true
        },
        "sources": {
          "items": {
            "description": "SourceSpec --",
            "properties": {
              "compression": {
                "type": "boolean"
              },
              "content": {
                "type": "string"
              },
              "contentKey": {
                "type": "string"
              },
              "contentRef": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "interceptors": {
                "description": "Interceptors are optional identifiers the org.apache.camel.k.RoutesLoader uses to pre/post process sources",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "language": {
                "description": "Language --",
                "type": "string"
              },
              "loader": {
                "description": "Loader is an optional id of the org.apache.camel.k.RoutesLoader that will interpret this source at runtime",
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "path": {
                "type": "string"
              },
              "property-names": {
                "description": "List of property names defined in the source (e.g. if type is \"template\")",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "rawContent": {
                "format": "byte",
                "type": "string"
              },
              "type": {
                "description": "Type defines the kind of source described by this object",
                "type": "string"
              }
            },
            "type": "object"
          },
          "type": "array"
        },
        "template": {
          "description": "Template is an unstructured object representing a Kamelet template in YAML/JSON DSL",
          "type": "object",
          "x-kubernetes-preserve-unknown-fields": true
        },
        "types": {
          "additionalProperties": {
            "properties": {
              "mediaType": {
                "type": "string"
              },
              "schema": {
                "description": "JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).",
                "properties": {
                  "$schema": {
                    "description": "JSONSchemaURL represents a schema url.",
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "example": {
                    "description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
                    "x-kubernetes-preserve-unknown-fields": true
                  },
                  "externalDocs": {
                    "description": "ExternalDocumentation allows referencing an external resource for extended documentation.",
                    "properties": {
                      "description": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "id": {
                    "type": "string"
                  },
                  "properties": {
                    "additionalProperties": {
                      "properties": {
                        "default": {
                          "description": "default is a default value for undefined object fields.",
                          "x-kubernetes-preserve-unknown-fields": true
                        },
                        "description": {
                          "type": "string"
                        },
                        "enum": {
                          "items": {
                            "description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
                            "x-kubernetes-preserve-unknown-fields": true
                          },
                          "type": "array"
                        },
                        "example": {
                          "description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
                          "x-kubernetes-preserve-unknown-fields": true
                        },
                        "exclusiveMaximum": {
                          "type": "boolean"
                        },
                        "exclusiveMinimum": {
                          "type": "boolean"
                        },
                        "format": {
                          "description": "format is an OpenAPI v3 format string. Unknown formats are ignored. The following formats are validated: \n - bsonobjectid: a bson object ID, i.e. a 24 characters hex string - uri: an URI as parsed by Golang net/url.ParseRequestURI - email: an email address as parsed by Golang net/mail.ParseAddress - hostname: a valid representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034]. - ipv4: an IPv4 IP as parsed by Golang net.ParseIP - ipv6: an IPv6 IP as parsed by Golang net.ParseIP - cidr: a CIDR as parsed by Golang net.ParseCIDR - mac: a MAC address as parsed by Golang net.ParseMAC - uuid: an UUID that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid3: an UUID3 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$ - uuid4: an UUID4 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - uuid5: an UUID5 that allows uppercase defined by the regex (?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$ - isbn: an ISBN10 or ISBN13 number string like \"0321751043\" or \"978-0321751041\" - isbn10: an ISBN10 number string like \"0321751043\" - isbn13: an ISBN13 number string like \"978-0321751041\" - creditcard: a credit card number defined by the regex ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\\\d{3})\\\\d{11})$ with any non digit characters mixed in - ssn: a U.S. social security number following the regex ^\\\\d{3}[- ]?\\\\d{2}[- ]?\\\\d{4}$ - hexcolor: an hexadecimal color code like \"#FFFFFF: following the regex ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$ - rgbcolor: an RGB color code like rgb like \"rgb(255,255,2559\" - byte: base64 encoded binary data - password: any kind of string - date: a date string like \"2006-01-02\" as defined by full-date in RFC3339 - duration: a duration string like \"22 ns\" as parsed by Golang time.ParseDuration or compatible with Scala duration format - datetime: a date time string like \"2014-12-15T19:30:20.000Z\" as defined by date-time in RFC3339.",
                          "type": "string"
                        },
                        "id": {
                          "type": "string"
                        },
                        "maxItems": {
                          "format": "int64",
                          "type": "integer"
                        },
                        "maxLength": {
                          "format": "int64",
                          "type": "integer"
                        },
                        "maxProperties": {
                          "format": "int64",
                          "type": "integer"
                        },
                        "maximum": {
                          "description": "A Number represents a JSON number literal.",
                          "type": "string"
                        },
                        "minItems": {
                          "format": "int64",
                          "type": "integer"
                        },
                        "minLength": {
                          "format": "int64",
                          "type": "integer"
                        },
                        "minProperties": {
                          "format": "int64",
                          "type": "integer"
                        },
                        "minimum": {
                          "description": "A Number represents a JSON number literal.",
                          "type": "string"
                        },
                        "multipleOf": {
                          "description": "A Number represents a JSON number literal.",
                          "type": "string"
                        },
                        "nullable": {
                          "type": "boolean"
                        },
                        "pattern": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        },
                        "uniqueItems": {
                          "type": "boolean"
                        },
                        "x-descriptors": {
                          "description": "The list of descriptors that determine which UI components to use on different views",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    },
                    "type": "object"
                  },
                  "required": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "title": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            },
            "type": "object"
          },
          "type": "object"
        }
      },
      "type": "object",
      "markdownDescription": "**spec** (object)\n\nKameletSpec defines the desired state of Kamelet"
    },
    "status": {
      "description": "KameletStatus defines the observed state of Kamelet",
      "properties": {
        "conditions": {
          "items": {
            "description": "KameletCondition describes the state of a resource at a certain point.",
            "properties": {
              "lastTransitionTime": {
                "description": "Last time the condition transitioned from one status to another.",
                "format": "date-time",
                "type": "string"
              },
              "lastUpdateTime": {
                "description": "The last time this condition was updated.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "A human-readable message indicating details about the transition.",
                "type": "string"
              },
              "reason": {
                "description": "The reason for the condition's last transition.",
                "type": "string"
              },
              "status": {
                "description": "Status of the condition, one of True, False, Unknown.",
                "type": "string"
              },
              "type": {
                "description": "Type of kamelet condition.",
                "type": "string"
              }
            },
            "required": [
              "status",
              "type"
            ],
            "type": "object"
          },
          "type": "array"
        },
        "phase": {
          "type": "string"
        },
        "properties": {
          "items": {
            "properties": {
              "default": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "type": "array"
        }
      },
      "type": "object",
      "markdownDescription": "**status** (object)\n\nKameletStatus defines the observed state of Kamelet"
    }
    },
    "name": "org.apache.camel.v1alpha1.Kamelet"
    }
  2. Use file

    apiVersion: camel.apache.org/v1alpha1
    kind: Kamelet
    metadata:
    name: twitter-search-source
    labels:
    camel.apache.org/kamelet.type: "source"
    spec:
    types:
    out:
    
    flow:
    from:
      uri: timer:tick
      parameters:
        period: "{{period}}"
      steps:
        - set-body:
            constant: "{{message}}"
        - to: "kamelet:sink"
  3. Call completion on the line below spec -> types -> out with one new indentation level

Environment

apupier commented 2 years ago

Screenshot from 2021-12-07 16-20-36 Screenshot from 2021-12-07 16-20-31

msivasubramaniaan commented 2 years ago

@apupier it was resolved in 1.3.0 please refer the screenshot image