Damans227 commented on code in PR #13895:
URL: https://github.com/apache/cloudstack/pull/13895#discussion_r4158485829
##########
api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java:
##########
@@ -111,9 +113,11 @@ public class ListTemplatesCmd extends
BaseListTaggedResourcesCmd implements User
since = "4.21.0")
private Boolean forCks;
- @Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "the CPU arch of the template. Valid options are:
x86_64, aarch64, s390x",
- since = "4.20")
+ @Parameter(name = ApiConstants.ARCH,
+ type = CommandType.STRING,
+ description = "the CPU arch of the template. Valid options are:
x86_64, aarch64, s390x",
+ since = "4.20",
+ allowedValueType = CPU.CPUArch.class)
Review Comment:
ok that covers it, thanks
##########
api/src/main/java/com/cloud/template/TemplateApiType.java:
##########
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.template;
+
+public enum TemplateApiType {
Review Comment:
got it, thanks
##########
scripts/check_allowed_values.py:
##########
@@ -0,0 +1,293 @@
+#!/usr/bin/env python3
+
+import re
+import sys
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parent.parent
+
+
+def find_java_files():
+ return ROOT.glob("**/*.java")
+
+
+def extract_parameter_blocks(source):
+ blocks = []
+ start = 0
+
+ while True:
+ match = source.find("@Parameter(", start)
+ if match == -1:
+ break
+
+ depth = 0
+ in_string = False
+ escape = False
+ end = None
+
+ for i in range(match, len(source)):
+ char = source[i]
+
+ if in_string:
+ if escape:
+ escape = False
+ elif char == "\\":
+ escape = True
+ elif char == '"':
+ in_string = False
+ continue
+
+ if char == '"':
+ in_string = True
+ elif char == "(":
+ depth += 1
+ elif char == ")":
+ depth -= 1
+ if depth == 0:
+ end = i + 1
+ break
+
+ if end is None:
+ break
+
+ blocks.append((match, source[match:end]))
+ start = end
+
+ return blocks
+
+
+def is_string_parameter(block):
+ return bool(
+ re.search(
+ r"\btype\s*=\s*CommandType\.STRING\b",
+ block,
+ )
+ )
+
+
+def extract_description(block):
+ match = re.search(
+ r"\bdescription\s*=\s*((?:\"(?:\\.|[^\"\\])*\")"
+ r"(?:\s*\+\s*\"(?:\\.|[^\"\\])*\")*)",
+ block,
+ re.DOTALL,
+ )
+
+ if not match:
+ return ""
+
+ expression = match.group(1)
+
+ strings = re.findall(
+ r'"((?:\\.|[^"\\])*)"',
+ expression,
+ re.DOTALL,
+ )
+
+ return "".join(strings)
+
+
+def extract_valid_values(description):
+ patterns = [
+ r"\bvalid\s+values?\s*(?:are|:)\s*(.+?)(?:\.|$)",
+ r"\bvalid\s+options?\s*(?:are|:)\s*(.+?)(?:\.|$)",
+ r"\bpossible\s+values?\s*(?:are|:|include)\s*(.+?)(?:\.|$)",
+ r"\bpossible\s+options?\s*(?:are|:|include)\s*(.+?)(?:\.|$)",
+ r"\ballowed\s+values?\s*(?:are|:)\s*(.+?)(?:\.|$)",
+ ]
+
+ match = None
+
+ for pattern in patterns:
+ match = re.search(pattern, description, re.IGNORECASE)
+ if match:
+ break
+
+ if not match:
+ return []
+
+ values_text = match.group(1).strip()
+
+ # Some descriptions contain a fixed set of examples but also
+ # explicitly allow additional values. These are not closed enums
+ # and therefore should not require an allowedValues annotation.
+ if re.search(r"\bor\s+valid\s+protocol\s+number\b", values_text,
re.IGNORECASE):
+ return []
+
+ # Remove a leading colon if the wording leaves one behind.
+ values_text = values_text.lstrip(":").strip()
+
+ # Convert "A, B, and C" into "A, B, C".
+ values_text = re.sub(
+ r",?\s+and\s+",
+ ", ",
+ values_text,
+ flags=re.IGNORECASE,
+ )
+
+ values = [
+ value.strip().strip('"').strip("'")
+ for value in values_text.split(",")
+ ]
+
+ return [value for value in values if value]
+
+
+def extract_parameter_name(block):
+ match = re.search(
+ r"\bname\s*=\s*(?:ApiConstants\.([A-Z0-9_]+)|\"([^\"]+)\")",
+ block,
+ )
+
+ if not match:
+ return "<unknown>"
+
+ if match.group(1):
+ return f"ApiConstants.{match.group(1)}"
+
+ return match.group(2)
+
+def extract_inner_enums(source):
+ enums = {}
+
+ pattern = re.compile(
+ r"\benum\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{([^}]*)\}",
+ re.DOTALL,
+ )
+
+ for match in pattern.finditer(source):
+ enum_name = match.group(1)
+ body = match.group(2)
+
+ constants = []
+
+ for constant in body.split(","):
+ constant = constant.strip()
+
+ constant_match = re.match(
+ r"([A-Z][A-Z0-9_]*)\b",
+ constant,
+ )
+
+ if constant_match:
+ constants.append(constant_match.group(1))
+
+ if constants:
+ enums[enum_name] = constants
+
+ return enums
+
+
+def extract_parameter_field_name(source, parameter_end):
+ match = re.match(
+ r"\s*private\s+String\s+([A-Za-z_][A-Za-z0-9_]*)\s*;",
+ source[parameter_end:],
+ )
+
+ if not match:
+ return None
+
+ return match.group(1)
+
+
+def find_enum_for_parameter(source, parameter_end, field_name):
+ if not field_name:
+ return None
+
+ enum_pattern = re.compile(
+ rf"\benum\s+{re.escape(field_name.capitalize())}Values\b"
+ r"\s*\{",
+ )
+
+ if enum_pattern.search(source):
+ return field_name.capitalize() + "Values"
+
+ return None
+
+def check_file(path):
+ source = Path(path).read_text(encoding="utf-8")
+ violations = []
+
+ enums = extract_inner_enums(source)
+
+ for start, block in extract_parameter_blocks(source):
+ if not is_string_parameter(block):
+ continue
+
+ if re.search(r"\ballowedValues\s*=", block):
+ continue
+
+ if re.search(r"\ballowedValueType\s*=", block):
Review Comment:
ok that covers it
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]