Source code for core.rawlint
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Linter for raw files. Ported from Lethosor's Lua script:
https://github.com/lethosor/dfhack-scripts/blob/master/raw-lint.lua"""
import os
from . import log
from .dfraw import DFRaw
# TODO: Handle older versions correctly
# For example, 40d and earlier use object names MATGLOSS and DESCRIPTOR
valid_objnames = [
'BODY_DETAIL_PLAN',
'BODY',
'BUILDING',
'CREATURE_VARIATION',
'CREATURE',
'DESCRIPTOR_COLOR',
'DESCRIPTOR_PATTERN',
'DESCRIPTOR_SHAPE',
'ENTITY',
'INORGANIC',
'INTERACTION',
'ITEM',
'LANGUAGE',
'MATERIAL_TEMPLATE',
'PLANT',
'REACTION',
'TISSUE_TEMPLATE',
]
objname_overrides = {
'b_detail_plan': 'BODY_DETAIL_PLAN',
'c_variation': 'CREATURE_VARIATION',
}
[docs]def check_file(path):
"""Validates the raw file located at <path>. Error details are printed to
the log with level WARNING. Returns True/False."""
# pylint:disable=too-many-branches
file_ok = True
if not path.endswith('.txt'):
log.w('Unrecognized filename')
return False
contents = DFRaw.read(path)
filename = os.path.basename(path)[:-4]
try:
realname = contents.splitlines()[0]
except IndexError:
realname = ''
try:
rawname = realname.split()[0]
except IndexError:
rawname = realname
# Everything before first whitespace must match filename
if not (realname == realname.lstrip() and rawname == filename):
log.w('Name mismatch: expected %s, found %s' % (filename, rawname))
file_ok = False
objname = filename
check_objnames = []
for k, v in objname_overrides.items():
if filename.startswith(k) and v in valid_objnames:
check_objnames.append(v)
for o in valid_objnames:
if filename.upper().startswith(o):
check_objnames.append(o)
if check_objnames:
found = False
for i, objname in enumerate(check_objnames):
objname = '[OBJECT:' + objname.upper() + ']'
if objname in contents:
found = True
check_objnames[i] = objname
if not found:
log.w('None of %s found' % ', '.join(check_objnames))
file_ok = False
else:
log.w('No valid object names')
file_ok = False
return file_ok
[docs]def check_folder(path):
"""Validates all raw files in <path> and its subfolders. Problems with
individual files are printed to the log with level WARNING. General problems
are printed to the log with level ERROR.
Returns:
(passed, failed): two lists of paths of files that passed or failed,
respectively.
"""
log.push_prefix('RawLint')
files = []
for d in os.walk(path):
files += [os.path.join(d[0], f) for f in d[2]]
passed = []
failed = []
if not files:
log.e('Could not find any files in ' + path)
for f in files:
f_parts = f.split(os.sep)
if (f.endswith('.txt') and 'notes' not in f_parts
and 'examples and notes' not in f_parts and 'text' not in f_parts):
log.push_prefix(f)
has_passed = check_file(f)
log.pop_prefix()
if has_passed:
passed.append(f)
else:
failed.append(f)
log.pop_prefix()
return (passed, failed)
[docs]def check_df(path):
"""Validates the raw/objects folder in the Dwarf Fortress folder located at
<path>. Problem with individual files are printed to the log with level
WARNING. General problems are printed to the log with level ERROR.
Returns:
(passed, failed): two lists of paths of files that passed or failed,
respectively.
"""
return check_folder(os.path.join(path, 'raw', 'objects'))
[docs]def check_folder_bool(path):
"""Returns True if all raw files in <path> pass validation. Problems with
individual files are printed to the log with level WARNING. General
problems are printed to the log with level ERROR."""
p, f = check_folder(path)
return len(f) == 0 and len(p) != 0
[docs]def check_df_bool(path):
"""Validates the raw/objects folder in the Dwarf Fortress folder located at
<path> and returns True if all files pass validation. Problems with
individual files are printed to the log with level WARNING. General
problems are printed to the log with level ERROR."""
p, f = check_df(path)
return len(f) == 0 and len(p) != 0