Skip to content
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}

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