192 Zeilen
7.4 KiB
Python
192 Zeilen
7.4 KiB
Python
import sys
|
|
import os
|
|
import codecs
|
|
import re
|
|
|
|
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
|
|
def print_error(*args, **kwargs):
|
|
print(*args, file=sys.stderr, **kwargs)
|
|
|
|
|
|
def read_file(filename):
|
|
with codecs.open(os.path.join(PROJECT_ROOT, filename), 'r', 'utf-8') as f:
|
|
return f.read()
|
|
|
|
|
|
def write_file(filename, value):
|
|
with codecs.open(os.path.join(PROJECT_ROOT, filename), 'w', 'utf-8') as f:
|
|
f.write(value)
|
|
|
|
|
|
def check_messages():
|
|
success = True
|
|
|
|
# read info from hpp file:
|
|
logmessage_hpp = os.path.join(PROJECT_ROOT, 'shared', 'src', 'traintastic', 'enum', 'logmessage.hpp')
|
|
hpp = read_file(logmessage_hpp)
|
|
|
|
messages = re.findall(r'\b(D|I|N|W|E|C|F)(\d{4})_[A-Z0-9_]+[ ]*=[ ]*LogMessageOffset::[a-z]+[ ]+\+[ ]+(\d{4})', hpp)
|
|
for message in messages:
|
|
if message[1] != message[2]:
|
|
print_error('Error: ' + message[0] + message[1] + ' != ' + message[2] + ' in ' + logmessage_hpp)
|
|
success = False
|
|
|
|
success &= check_message_file('D', 'debug.md', messages)
|
|
success &= check_message_file('I', 'info.md', messages)
|
|
success &= check_message_file('N', 'notice.md', messages)
|
|
success &= check_message_file('W', 'warning.md', messages)
|
|
success &= check_message_file('E', 'error.md', messages)
|
|
success &= check_message_file('C', 'critical.md', messages)
|
|
success &= check_message_file('F', 'fatal.md', messages)
|
|
|
|
return success
|
|
|
|
|
|
def check_message_file(prefix, filename, messages):
|
|
success = True
|
|
md_file = os.path.join(PROJECT_ROOT, 'manual', 'traintasticmanual', 'en-us', 'messages', filename)
|
|
md = read_file(md_file)
|
|
for message in messages:
|
|
if prefix == message[0]:
|
|
id = message[0] + message[1]
|
|
if re.search('^## ' + id + ': .*{#' + id.lower() + '}$', md, re.MULTILINE) is None:
|
|
print_error('Error: ' + id + ' missing in ' + md_file)
|
|
success = False
|
|
|
|
return success
|
|
|
|
|
|
def check_lua_enum():
|
|
success = True
|
|
|
|
# read info from hpp files:
|
|
enums_hpp = read_file(os.path.join('server', 'src', 'lua', 'enums.hpp'))
|
|
m = re.findall(r'#define LUA_ENUMS([ \nA-Za-z0-9_,\\]+)\n\n', enums_hpp)
|
|
m = re.sub(r'[ \\\n]+', '', m[0])
|
|
enums = []
|
|
for cpp_name in m.split(','):
|
|
hpp = read_file(os.path.join('shared', 'src', 'traintastic', 'enum', cpp_name.lower() + '.hpp'))
|
|
enum = re.search(r'enum class ' + cpp_name + r'[ ]*(:[ ]*[A-Za-z0-9_]+|)[ \n]*{(.+?)};', hpp, re.DOTALL)
|
|
values = [{'cpp_name': m[0], 'description': m[3]} for m in re.findall(r'^[ ]*([A-Za-z0-9_]+)[ ]*=[ ]*.+?[ ]*(,|)[ ]*(//!< (.+)|)\n', enum.group(2), re.MULTILINE)] if enum is not None else None
|
|
info = re.search(r'TRAINTASTIC_ENUM\([ ]*' + cpp_name + r'[ \n]*,[ \n]*"([a-z0-9_]+)"[ \n]*,[ \n]*\d+[ \n]*,[ \n]*{(.+?)}[ \n]*\);', hpp, re.DOTALL)
|
|
|
|
if info is not None:
|
|
for value in values:
|
|
m = re.search(cpp_name + '::' + value['cpp_name'] + r'[ ]*,[ ]*"([A-Za-z0-9_]+)"', info.group(2))
|
|
if m is not None:
|
|
value['lua_name'] = m.group(1).upper()
|
|
|
|
enums.append({
|
|
'cpp_name': cpp_name,
|
|
'lua_name': info.group(1) if info is not None else None,
|
|
'values': values,
|
|
})
|
|
|
|
# check manual markdown files
|
|
for enum in enums:
|
|
md_file = os.path.join(PROJECT_ROOT, 'manual', 'traintasticmanual', 'en-us', 'lua', 'library', 'enum', enum['lua_name'].replace('_', '') + '.md')
|
|
if not os.path.exists(md_file):
|
|
print_error('Error: ' + md_file + ' doesn\'t exist')
|
|
|
|
md = \
|
|
'# `enum.' + enum['lua_name'] + '` {#lua-enum-' + enum['lua_name'].replace('_', '') + '}' + os.linesep + \
|
|
os.linesep + \
|
|
'TODO' + os.linesep + \
|
|
os.linesep + \
|
|
'## Constants' + os.linesep
|
|
|
|
for value in enum['values']:
|
|
md += \
|
|
os.linesep + \
|
|
'### `enum.' + enum['lua_name'] + '.' + value['lua_name'] + '`'+ os.linesep + \
|
|
(value['description'] if value['description'] != '' else 'TODO') + os.linesep
|
|
|
|
write_file(md_file, md)
|
|
print('Bootstrapped: ' + md_file)
|
|
success = False
|
|
continue
|
|
|
|
md = read_file(md_file)
|
|
|
|
# check if all values exist
|
|
for value in enum['values']:
|
|
label = '`enum.' + enum['lua_name'] + '.' + value['lua_name'] + '`'
|
|
if re.search('^### ' + label, md, re.MULTILINE) is None:
|
|
print_error('Error: ' + label + ' missing in ' + md_file)
|
|
success = False
|
|
|
|
return success
|
|
|
|
|
|
def check_lua_set():
|
|
success = True
|
|
|
|
# read info from hpp files:
|
|
sets_hpp = read_file(os.path.join('server', 'src', 'lua', 'sets.hpp'))
|
|
m = re.findall(r'#define LUA_SETS([ \nA-Za-z0-9_,\\]+)\n\n', sets_hpp)
|
|
m = re.sub(r'[ \\\n]+', '', m[0])
|
|
sets = []
|
|
for cpp_name in m.split(','):
|
|
hpp = read_file(os.path.join('shared', 'src', 'traintastic', 'set', cpp_name.lower() + '.hpp'))
|
|
set = re.search(r'enum class ' + cpp_name + r'[ ]*(:[ ]*[A-Za-z0-9_]+|)[ \n]*{(.+?)};', hpp, re.DOTALL)
|
|
values = [{'cpp_name': m[0], 'description': m[3]} for m in re.findall(r'^[ ]*([A-Za-z0-9_]+)[ ]*=[ ]*.+?[ ]*(,|)[ ]*(//!< (.+)|)\n', set.group(2), re.MULTILINE)] if set is not None else None
|
|
info = re.search(r'TRAINTASTIC_SET\([ ]*' + cpp_name + r'[ \n]*,[ \n]*"([a-z0-9_]+)"[ \n]*,[ \n]*\d+[ \n]*,[ \n]*\(.+?\),[ \n]*{(.+?)}[ \n]*\);', hpp, re.DOTALL)
|
|
|
|
if info is not None:
|
|
for value in values:
|
|
m = re.search(cpp_name + '::' + value['cpp_name'] + r'[ ]*,[ ]*"([A-Za-z0-9_]+)"', info.group(2))
|
|
if m is not None:
|
|
value['lua_name'] = m.group(1).upper()
|
|
|
|
sets.append({
|
|
'cpp_name': cpp_name,
|
|
'lua_name': info.group(1) if info is not None else None,
|
|
'values': values,
|
|
})
|
|
|
|
# check manual markdown files
|
|
for set in sets:
|
|
md_file = os.path.join(PROJECT_ROOT, 'manual', 'traintasticmanual', 'en-us', 'lua', 'library', 'set', set['lua_name'].replace('_', '') + '.md')
|
|
if not os.path.exists(md_file):
|
|
print_error('Error: ' + md_file + ' doesn\'t exist')
|
|
|
|
md = \
|
|
'# `set.' + set['lua_name'] + '` {#lua-set-' + set['lua_name'].replace('_', '') + '}' + os.linesep + \
|
|
os.linesep + \
|
|
'TODO' + os.linesep + \
|
|
os.linesep + \
|
|
'## Constants' + os.linesep
|
|
|
|
for value in set['values']:
|
|
md += \
|
|
os.linesep + \
|
|
'### `set.' + set['lua_name'] + '.' + value['lua_name'] + '`' + os.linesep + \
|
|
(value['description'] if value['description'] != '' else 'TODO') + os.linesep
|
|
|
|
write_file(md_file, md)
|
|
print('Bootstrapped: ' + md_file)
|
|
success = False
|
|
continue
|
|
|
|
md = read_file(md_file)
|
|
|
|
# check if all values exist
|
|
for value in set['values']:
|
|
label = '`set.' + set['lua_name'] + '.' + value['lua_name'] + '`'
|
|
if re.search('^### ' + label, md, re.MULTILINE) is None:
|
|
print_error('Error: ' + label + ' missing in ' + md_file)
|
|
success = False
|
|
|
|
return success
|
|
|
|
|
|
success = True
|
|
success &= check_messages()
|
|
success &= check_lua_enum()
|
|
success &= check_lua_set()
|
|
|
|
if not success:
|
|
sys.exit(1)
|