import sys import re def extract_properties_with_comments(yaml_file_path): properties = {} with open(yaml_file_path, 'r') as file: lines = file.readlines() index = 0 key_level_map = {0 : ''} parse_line('', '', key_level_map, 0, index, lines, properties) return properties def parse_line(table_name, comment, key_level_map, parent_line_level, index, lines, properties): if index >= len(lines): return line = lines[index] line_level = (len(line) - len(line.lstrip())) if line.strip() else 0 if line_level == 0: key_level_map = {0 : ''} line = line.strip() # if line is empty - parse next line if not line: index = index + 1 parse_line(table_name, comment, key_level_map, line_level, index, lines, properties) # if line is a comment - save comment and parse next line elif line.startswith('#'): if line_level == 0: table_name = line.lstrip('#') elif line_level == parent_line_level: comment = comment + '\n' + line.lstrip('#') else: comment = line.lstrip('#') index = index + 1 parse_line(table_name, comment, key_level_map, line_level, index, lines, properties) else: # Check if it's a property line if ':' in line: # clean comment if level was changed if line_level != parent_line_level: comment = '' key, value = line.split(':', 1) if key.startswith('- '): key = key.lstrip('- ') key_level_map[line_level] = key value = value.strip() if value.split('#')[0]: current_key = '' for k in key_level_map.keys(): if k <= line_level: current_key = ((current_key + '.') if current_key else '') + key_level_map[k] properties[current_key] = (value, comment, table_name) comment = '' index = index + 1 parse_line(table_name, comment, key_level_map, line_level, index, lines, properties) def extract_property_info(properties): rows = [] for property_name, value in properties.items(): if '#' in value[0]: value_parts = value[0].split('#') comment = value_parts[1] else: comment = value[1] pattern = r'\"\$\{(.*?)\:(.*?)\}\"' match = re.match(pattern, value[0]) if match is not None: rows.append((property_name, match.group(1), match.group(2), comment, value[2])) else: rows.append((property_name, "", value[0].split('#')[0], comment, value[2])) return rows def check_descriptions(properties): variables_without_description = [] for row in properties: # Extract information from the tuple property_name, env_variable, default_value, comment, table_name = row if comment == '' or len(comment) < 5 : variables_without_description.append(property_name) return variables_without_description if __name__ == '__main__': sys. setrecursionlimit(10000) # path to the YAML file input_yaml_file = "application/src/main/resources/thingsboard.yml" # Parse yml file to map where key is property key path with '.' separator # and value is an object (env_name_with_default_value, comment, table_name) properties = extract_properties_with_comments(input_yaml_file) # Extract property information (extract env name, default value and comment nearby property) property_info = extract_property_info(properties) # Check all properies have descriptions variables_without_desc = check_descriptions(property_info) if len(variables_without_desc) > 0: print(f"There are some yml properties without valid description: (total {len(variables_without_desc)}) {variables_without_desc}.") exit(1) else: print("All yml properties have valid description.")