2023-10-05 20:31:51 +03:00
#
2024-01-09 10:46:16 +02:00
# Copyright © 2016-2024 The Thingsboard Authors
2023-10-05 20:31:51 +03:00
#
# Licensed 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.
#
2023-10-05 14:24:33 +03:00
import sys
import re
2023-10-11 17:34:05 +03:00
2023-10-05 14:24:33 +03:00
def extract_properties_with_comments ( yaml_file_path ) :
properties = { }
with open ( yaml_file_path , ' r ' ) as file :
lines = file . readlines ( )
index = 0
2023-10-11 17:34:05 +03:00
key_level_map = { 0 : ' ' }
2023-10-05 14:24:33 +03:00
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
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
else :
2023-10-05 20:31:51 +03:00
if line_level == 0 :
2023-10-11 17:34:05 +03:00
key_level_map = { 0 : ' ' }
2023-10-05 20:31:51 +03:00
if 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 ( ' # ' )
2023-10-05 14:24:33 +03:00
index = index + 1
parse_line ( table_name , comment , key_level_map , line_level , index , lines , properties )
2023-10-05 20:31:51 +03:00
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 )
2023-10-05 14:24:33 +03:00
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
2023-10-11 17:34:05 +03:00
def check_yml ( total_list , input_yaml_file ) :
2023-10-05 14:24:33 +03:00
# 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 )
2023-10-11 17:34:05 +03:00
# Check all properties have descriptions
variables_without_description = check_descriptions ( property_info )
total_list . extend ( variables_without_description )
if len ( variables_without_description ) > 0 :
print ( f " Check { input_yaml_file } . There are some yml properties without valid description: (total { len ( variables_without_description ) } ) { variables_without_description } . " )
if __name__ == ' __main__ ' :
sys . setrecursionlimit ( 10000 )
files_to_check = [ " application/src/main/resources/thingsboard.yml " ,
" transport/http/src/main/resources/tb-http-transport.yml " ,
" transport/mqtt/src/main/resources/tb-mqtt-transport.yml " ,
" transport/coap/src/main/resources/tb-coap-transport.yml " ,
" transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml " ,
2023-10-12 16:42:39 +03:00
" transport/snmp/src/main/resources/tb-snmp-transport.yml " ,
" msa/vc-executor/src/main/resources/tb-vc-executor.yml " ]
2023-10-05 14:24:33 +03:00
2023-10-11 17:34:05 +03:00
total_list = [ ]
for file in files_to_check :
check_yml ( total_list , file )
if len ( total_list ) > 0 :
2023-10-05 14:24:33 +03:00
exit ( 1 )
else :
print ( " All yml properties have valid description. " )