Skip to content

Commit

Permalink
feat: Parse parameters into JSON schema objects (#5468)
Browse files Browse the repository at this point in the history
* Parse parameters into JSON schema objects

* Add JSON indent

* Add case checking

* Make param type variable

---------

Co-authored-by: Leonardo Gama <leogama@amazon.com>
  • Loading branch information
Leo10Gama and Leonardo Gama authored Jul 11, 2023
1 parent 113ef02 commit 9f18cda
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions schema/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@


import importlib
from typing import Dict, List, Optional, Union
import json
from enum import Enum
from typing import Any, Dict

import click

from samcli.cli.command import _SAM_CLI_COMMAND_PACKAGES
from samcli.lib.config.samconfig import SamConfig


def format_param(param: click.core.Option) -> Dict[str, Union[Optional[str], List[str]]]:
class SchemaKeys(Enum):
SCHEMA_FILE_NAME = "samcli.json"
SCHEMA_DRAFT = "http://json-schema.org/draft-04/schema"
TITLE = "AWS SAM CLI samconfig schema"


def format_param(param: click.core.Option) -> Dict[str, Any]:
"""Format a click Option parameter to a dictionary object.
A parameter object should contain the following information that will be
Expand All @@ -22,20 +30,23 @@ def format_param(param: click.core.Option) -> Dict[str, Union[Optional[str], Lis
a list of those allowed options
* default - The default option for that parameter
"""
formatted_param: Dict[str, Union[Optional[str], List[str]]] = {"name": param.name, "help": param.help}
formatted_param: Dict[str, Any] = {"title": param.name, "description": param.help}

# NOTE: Params do not have explicit "string" type; either "text" or "path".
# All choice options are from a set of strings.
if param.type.name in ["text", "path", "choice"]:
param_type = param.type.name.lower()
if param_type in ["text", "path", "choice", "filename", "directory"]:
formatted_param["type"] = "string"
elif param_type == "list":
formatted_param["type"] = "array"
else:
formatted_param["type"] = param.type.name
formatted_param["type"] = param_type or "string"

if param.default:
formatted_param["default"] = str(param.default)
formatted_param["default"] = list(param.default) if isinstance(param.default, tuple) else param.default

if param.type.name == "choice" and isinstance(param.type, click.Choice):
formatted_param["choices"] = list(param.type.choices)
formatted_param["enum"] = list(param.type.choices)

return formatted_param

Expand Down Expand Up @@ -91,15 +102,34 @@ def generate_schema() -> dict:
schema: dict = {}
commands = {}
params = set() # NOTE(leogama): Currently unused due to some params having different help values
# TODO: Populate schema with relevant attributes

# Populate schema with relevant attributes
schema["$schema"] = SchemaKeys.SCHEMA_DRAFT.value
schema["title"] = SchemaKeys.TITLE.value
schema["type"] = "object"
schema["properties"] = {
# Version number required for samconfig files to be valid
"version": {"type": "number"}
}
schema["required"] = ["version"]
schema["additionalProperties"] = False
# Iterate through packages for command and parameter information
for package_name in _SAM_CLI_COMMAND_PACKAGES:
new_command = retrieve_command_structure(package_name)
commands.update(new_command)
for param_list in new_command.values():
command_params = [param for param in param_list]
params.update(command_params)
# TODO: Generate schema for each of the commands
return schema


def write_schema():
"""Generate the SAM CLI JSON schema and write it to file."""
schema = generate_schema()
with open(SchemaKeys.SCHEMA_FILE_NAME.value, "w+", encoding="utf-8") as outfile:
json.dump(schema, outfile, indent=2)


if __name__ == "__main__":
generate_schema()

0 comments on commit 9f18cda

Please sign in to comment.