def _get_info(cls): # https://hitchdev.com/strictyaml schema = Map({ Optional("knobs"): Map({ Optional("log_to_console"): Bool(), Optional("log_level_debug"): Bool(), }) | EmptyDict(), "globals": Map({ "topic_prefix": Str(), Optional( "reconnect_interval", default=const.MQTT_DEFAULT_RECONNECT_INTERVAL, ): Float(), Optional("poll_interval", default=const.MYQ_DEFAULT_POLL_INTERVAL): Float(), Optional( "periodic_mqtt_report", default=const.DEFAULT_PERIODIC_MQTT_REPORT, ): Float(), Optional("user_agent"): Str(), }), "mqtt": Map({ "host": Str(), Optional("client_id", default=const.MQTT_DEFAULT_CLIENT_ID): Str(), Optional("username"): Str(), Optional("password"): Str(), }), "myq": Map({ "email": Email(), "password": Str(), }), Optional("alias"): MapPattern(Str(), Str()) | EmptyDict(), }) if not cls._info: config_filename = cls._get_config_filename() logger.info("loading yaml config file %s", config_filename) with open(config_filename, "r") as ymlfile: raw_cfg = load(ymlfile.read(), schema).data cls._parse_raw_cfg(raw_cfg) return cls._info
Str(), "command": Str() | Seq(Str()), "schedule": Str() | Map({ Opt("minute"): Str(), Opt("hour"): Str(), Opt("dayOfMonth"): Str(), Opt("month"): Str(), Opt("year"): Str(), Opt("dayOfWeek"): Str(), }), }) CONFIG_SCHEMA = EmptyDict() | Map({ Opt("defaults"): Map(_job_defaults_common), Opt("jobs"): Seq(Map(_job_schema_dict)), Opt("web"): Map({"listen": Seq(Str())}), }) # Slightly modified version of https://stackoverflow.com/a/7205672/2211825 def mergedicts(dict1, dict2): for k in set(dict1.keys()).union(dict2.keys()): if k in dict1 and k in dict2: v1 = dict1[k] v2 = dict2[k] if isinstance(v1, dict) and isinstance(v2, dict): yield (k, dict(mergedicts(v1, v2))) elif isinstance(v1, dict) and v2 is None: # modification
SHARED_FIELDS_KEYS = { "install_msg": Str(), "author": Seq(Str()), **COMMON_KEYS, } #: `cogs` metadata keys. COG_KEYS = { "name": Str(), # Downloader doesn't use this but I can set friendlier name "short": Str(), "description": Str(), "end_user_data_statement": Str(), Optional("class_docstring"): Str(), Optional("install_msg"): Str(), Optional("author"): Seq(Str()), Optional("required_cogs", {}): EmptyDict() | MapPattern(Str(), Url()), Optional("requirements", []): EmptyList() | Seq(Str()), Optional("tags", []): EmptyList() | Seq(Str()), **COMMON_KEYS, } #: Root schema of the info.yaml file. SCHEMA = Map({ "repo": Map(REPO_KEYS), "shared_fields": Map(SHARED_FIELDS_KEYS), "cogs": MapPattern(Str(), Map(COG_KEYS)), }) #: Keys that should be skipped when outputting to info.json. #: These keys are for infogen's usage. KEYS_TO_SKIP_IN_COG_INFO = {"class_docstring"}
def wrap_in_map(dictionary): could_be_empty = all(isinstance(key, Optional) for key in dictionary) if could_be_empty: return Map(dictionary) | EmptyDict() return Map(dictionary)
def generate_schema( stage_actions: OptionalType[List[str]] = None, default_compute_type: OptionalType[str] = None, default_image: OptionalType[str] = None, log_group_config: Dict = None, ) -> Map: """Generate a schema""" input_artifact_validator = Str() if stage_actions: input_artifact_validator = Enum(stage_actions) name_validation_key = Optional("name") if (log_group_config and log_group_config["enabled"] and not log_group_config["create"]): # name becomes mandatory if we're not creating it and it's enabled name_validation_key = "name" log_group_validator = { Optional( "enabled", default=CODEBUILD_DEFAULTS["log_group"]["enabled"], ): Bool(), name_validation_key: Str(), Optional( "create", default=CODEBUILD_DEFAULTS["log_group"]["create"], ): Bool(), Optional("retention"): Int(), } return Map({ "config": Map({ "s3_bucket": Str(), "kms_key_arn": Str(), Optional( "codepipeline", default=CODEPIPELINE_DEFAULTS, ): Map({ Optional( "restart_execution_on_update", default=CODEPIPELINE_DEFAULTS["restart_execution_on_update"], ): Bool(), }), Optional("codebuild", default=CODEBUILD_DEFAULTS): Map({ Optional( "compute_type", default=CODEBUILD_DEFAULTS["compute_type"], ): Str(), Optional( "image", default=CODEBUILD_DEFAULTS["image"], ): Str(), Optional( "log_group", default=CODEBUILD_DEFAULTS["log_group"], ): Map(log_group_validator), }), Optional("iam", default=[]): EmptyList() | Seq( Map({ Optional("Effect", default="Allow"): Enum(["Allow", "Deny"]), "Action": Seq(Str()), "Resource": Seq(Str()), })), }), "sources": Seq( Map({ "name": UniqueStr(), "from": Enum(["CodeCommit", "CodeStarConnection"]), "repository": Str(), "branch": Str(), Optional("poll_for_source_changes", default=False): Bool(), Optional("event_for_source_changes", default=True): Bool(), Optional("connection_arn"): Str(), })), "stages": Seq( Map({ "name": UniqueStr(), Optional("enabled", default=True): Bool(), "actions": Seq( Map({ "name": UniqueStr(), Optional("category", default="Build"): Enum(["Build", "Test", "Deploy"]), Optional("provider", default="CodeBuild"): Enum(["CodeBuild"]), Optional("buildspec"): Str(), Optional("commands"): Seq(Str()), Optional("artifacts"): Seq(Str()), Optional( "compute_type", default=default_compute_type, ): Str(), Optional("image", default=default_image): Str(), Optional("environment", default={}): EmptyDict() | MapPattern(Str(), Str()), Optional("input_artifacts", default=[]): EmptyList() | Seq(input_artifact_validator), })), })), })
Optional(REQUIRED_SETTINGS, []): Seq(Str()) | EmptyList(), Optional(REQUIREMENTS, {PACKAGES: [], SETTINGS: []}): Map( # Ignored { Optional(PACKAGES, []): Seq(Str()) | EmptyList(), Optional(SETTINGS, []): Seq(Str()) | EmptyList(), } ), FEEDS: MapPattern( Str(), Map( { HTTP: Map( { URL: Str(), Optional(HEADERS, {}): MapPattern(Str(), Str()) | EmptyDict(), Optional(TIMEOUT): HumanReadableTimePeriod(), } ), PARSER: Map( { Optional(BUILT_IN, None): PyEnum(models.Feed.BuiltInParser), Optional(CUSTOM, None): Str(), Optional(OPTIONS): MapPattern(Str(), Any()) | EmptyDict(), } ), Optional(AUTO_UPDATE, {ENABLED: False, PERIOD: -1}): Map( { Optional(ENABLED, True): Bool(), Optional(PERIOD, -1): HumanReadableTimePeriod(), }