Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Parse parameters into JSON schema objects #5468

Merged
merged 4 commits into from
Jul 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}
hnnasit marked this conversation as resolved.
Show resolved Hide resolved

# 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
Leo10Gama marked this conversation as resolved.
Show resolved Hide resolved

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()