mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-06 15:47:06 +08:00
More reorganization for the update-project tool
This commit is contained in:
parent
b22c29bd43
commit
c6e95c5d83
@ -22,7 +22,7 @@ import sys
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Optional, Tuple, List, Sequence, Dict, Set
|
from typing import Optional, Tuple, List, Dict, Set
|
||||||
|
|
||||||
CLRHDR = '\033[95m' # Header.
|
CLRHDR = '\033[95m' # Header.
|
||||||
CLRGRN = '\033[92m' # Green.
|
CLRGRN = '\033[92m' # Green.
|
||||||
@ -31,68 +31,6 @@ CLRRED = '\033[91m' # Red.
|
|||||||
CLREND = '\033[0m' # End.
|
CLREND = '\033[0m' # End.
|
||||||
|
|
||||||
|
|
||||||
def _check_files(src_files: Sequence[str]) -> None:
|
|
||||||
|
|
||||||
# A bit of sanity/lint-testing while we're here.
|
|
||||||
for fsrc in src_files:
|
|
||||||
if fsrc.endswith('.cpp') or fsrc.endswith('.cxx'):
|
|
||||||
raise Exception('please use .cc for c++ files; found ' + fsrc)
|
|
||||||
|
|
||||||
# Watch out for in-progress emacs edits.
|
|
||||||
# Could just ignore these but it probably means I intended
|
|
||||||
# to save something and forgot.
|
|
||||||
if '/.#' in fsrc:
|
|
||||||
print(f'{CLRRED}'
|
|
||||||
f'ERROR: Found an unsaved emacs file: "{fsrc}"'
|
|
||||||
f'{CLREND}')
|
|
||||||
sys.exit(255)
|
|
||||||
|
|
||||||
|
|
||||||
def _check_headers(header_files: Sequence[str], fixable_header_errors: Dict,
|
|
||||||
fix: bool) -> None:
|
|
||||||
for header_file_raw in header_files:
|
|
||||||
assert header_file_raw[0] == '/'
|
|
||||||
header_file = 'src/ballistica' + header_file_raw
|
|
||||||
|
|
||||||
# If its a header-file, lets make sure its define guard is correct.
|
|
||||||
if header_file.endswith('.h'):
|
|
||||||
guard = (
|
|
||||||
header_file[4:].upper().replace('/', '_').replace('.', '_') +
|
|
||||||
'_')
|
|
||||||
with open(header_file) as fhdr:
|
|
||||||
lines = fhdr.read().splitlines()
|
|
||||||
expected_lines = [(0, '// Copyright 2019 Eric Froemling'),
|
|
||||||
(2, '#ifndef ' + guard), (3, '#define ' + guard),
|
|
||||||
(-1, '#endif // ' + guard)]
|
|
||||||
errors_found = False
|
|
||||||
can_fix = True
|
|
||||||
for line, expected in expected_lines:
|
|
||||||
if lines[line] != expected:
|
|
||||||
errors_found = True
|
|
||||||
print("Incorrect line " + str(line) + " in " +
|
|
||||||
header_file + ":\n"
|
|
||||||
"Expected: " + expected + "\n"
|
|
||||||
"Found: " + lines[line])
|
|
||||||
|
|
||||||
# If the beginning of the line differs,
|
|
||||||
# don't attempt auto-fix.
|
|
||||||
if lines[line][:16] != expected[:16]:
|
|
||||||
can_fix = False
|
|
||||||
if errors_found:
|
|
||||||
if can_fix:
|
|
||||||
fixable_header_errors.setdefault(header_file, [])\
|
|
||||||
.append((line, expected))
|
|
||||||
else:
|
|
||||||
print(CLRRED + "Error found in '" + header_file +
|
|
||||||
"'. Not auto-fixable; please correct manually." +
|
|
||||||
CLREND)
|
|
||||||
sys.exit(255)
|
|
||||||
if fixable_header_errors and not fix:
|
|
||||||
print(CLRRED +
|
|
||||||
'Fixable header error(s) found; pass --fix to correct.' + CLREND)
|
|
||||||
sys.exit(255)
|
|
||||||
|
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
"""Context for an app run."""
|
"""Context for an app run."""
|
||||||
|
|
||||||
@ -109,9 +47,6 @@ class App:
|
|||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Do the thing."""
|
"""Do the thing."""
|
||||||
|
|
||||||
# pylint: disable=too-many-branches
|
|
||||||
# pylint: disable=too-many-statements
|
|
||||||
|
|
||||||
# Make sure we're operating from a project root.
|
# Make sure we're operating from a project root.
|
||||||
if not os.path.isdir('config') or not os.path.isdir('tools'):
|
if not os.path.isdir('config') or not os.path.isdir('tools'):
|
||||||
raise Exception('This must be run from a project root.')
|
raise Exception('This must be run from a project root.')
|
||||||
@ -125,36 +60,44 @@ class App:
|
|||||||
self._check_python_files()
|
self._check_python_files()
|
||||||
self._check_sync_states()
|
self._check_sync_states()
|
||||||
|
|
||||||
# Now go through and update our various build files
|
|
||||||
# (MSVC, CMake, Android NDK, etc) as well as sanity-testing/fixing
|
|
||||||
# various other files such as headers while we're at it.
|
|
||||||
|
|
||||||
# Grab sources/headers.
|
|
||||||
self._find_sources_and_headers('src/ballistica')
|
self._find_sources_and_headers('src/ballistica')
|
||||||
|
self._check_files()
|
||||||
# Run some checks on them.
|
self._check_headers()
|
||||||
_check_files(self._src_files)
|
|
||||||
_check_headers(self._header_files, self._fixable_header_errors,
|
|
||||||
self._fix)
|
|
||||||
|
|
||||||
self._update_cmake_files()
|
self._update_cmake_files()
|
||||||
self._update_visual_studio_projects()
|
self._update_visual_studio_projects()
|
||||||
|
|
||||||
# If we're all good to here, do the actual writes.
|
# If we're all good to here, do actual writes of the
|
||||||
|
# _files_to_write entries filled out by the above stuff.
|
||||||
|
self._write_header_fixes()
|
||||||
|
self._write_changed_project_files()
|
||||||
|
self._update_compile_commands_file()
|
||||||
|
self._update_dummy_module()
|
||||||
|
|
||||||
# First, write any header fixes.
|
if self._check:
|
||||||
if self._fixable_header_errors:
|
print('Check-Builds: Everything up to date.')
|
||||||
for filename, fixes in self._fixable_header_errors.items():
|
|
||||||
with open(filename, 'r') as infile:
|
|
||||||
lines = infile.read().splitlines()
|
|
||||||
for fix_line, fix_str in fixes:
|
|
||||||
lines[fix_line] = fix_str
|
|
||||||
with open(filename, 'w') as outfile:
|
|
||||||
outfile.write('\n'.join(lines) + '\n')
|
|
||||||
print(CLRBLU + 'Writing header: ' + filename + CLREND)
|
|
||||||
else:
|
else:
|
||||||
print(f'No issues found in {len(self._header_files)} headers.')
|
print('Update-Builds: SUCCESS!')
|
||||||
|
|
||||||
|
def _update_dummy_module(self) -> None:
|
||||||
|
# Lastly update our dummy _ba module.
|
||||||
|
# We need to do this very last because it may run the cmake build
|
||||||
|
# so its success may depend on the cmake build files having already
|
||||||
|
# been updated.
|
||||||
|
if os.path.exists('tools/gendummymodule.py'):
|
||||||
|
if os.system('tools/gendummymodule.py' + self._checkarg) != 0:
|
||||||
|
print(CLRRED + 'Error checking/updating dummy module' + CLREND)
|
||||||
|
sys.exit(255)
|
||||||
|
|
||||||
|
def _update_compile_commands_file(self) -> None:
|
||||||
|
# Update our local compile-commands file based on any changes to
|
||||||
|
# our cmake stuff. Do this at end so cmake changes already happened.
|
||||||
|
if not self._check and os.path.exists('ballisticacore-cmake'):
|
||||||
|
if os.system('make .irony/compile_commands.json') != 0:
|
||||||
|
print(CLRRED + 'Error updating compile-commands.' + CLREND)
|
||||||
|
sys.exit(255)
|
||||||
|
|
||||||
|
def _write_changed_project_files(self) -> None:
|
||||||
# Now write out any project files that have changed
|
# Now write out any project files that have changed
|
||||||
# (or error if we're in check mode).
|
# (or error if we're in check mode).
|
||||||
unchanged_project_count = 0
|
unchanged_project_count = 0
|
||||||
@ -179,26 +122,83 @@ class App:
|
|||||||
if unchanged_project_count > 0:
|
if unchanged_project_count > 0:
|
||||||
print(f'All {unchanged_project_count} project files up to date.')
|
print(f'All {unchanged_project_count} project files up to date.')
|
||||||
|
|
||||||
# Update our local compile-commands file based on any changes to
|
def _write_header_fixes(self) -> None:
|
||||||
# our cmake stuff. Do this at end so cmake changes already happened.
|
# First, write any header fixes.
|
||||||
if not self._check and os.path.exists('ballisticacore-cmake'):
|
if self._fixable_header_errors:
|
||||||
if os.system('make .irony/compile_commands.json') != 0:
|
for filename, fixes in self._fixable_header_errors.items():
|
||||||
print(CLRRED + 'Error updating compile-commands.' + CLREND)
|
with open(filename, 'r') as infile:
|
||||||
sys.exit(255)
|
lines = infile.read().splitlines()
|
||||||
|
for fix_line, fix_str in fixes:
|
||||||
# Lastly update our dummy _ba module.
|
lines[fix_line] = fix_str
|
||||||
# We need to do this very last because it may run the cmake build
|
with open(filename, 'w') as outfile:
|
||||||
# so its success may depend on the cmake build files having already
|
outfile.write('\n'.join(lines) + '\n')
|
||||||
# been updated.
|
print(CLRBLU + 'Writing header: ' + filename + CLREND)
|
||||||
if os.path.exists('tools/gendummymodule.py'):
|
|
||||||
if os.system('tools/gendummymodule.py' + self._checkarg) != 0:
|
|
||||||
print(CLRRED + 'Error checking/updating dummy module' + CLREND)
|
|
||||||
sys.exit(255)
|
|
||||||
|
|
||||||
if self._check:
|
|
||||||
print('Check-Builds: Everything up to date.')
|
|
||||||
else:
|
else:
|
||||||
print('Update-Builds: SUCCESS!')
|
print(f'No issues found in {len(self._header_files)} headers.')
|
||||||
|
|
||||||
|
def _check_files(self) -> None:
|
||||||
|
|
||||||
|
# A bit of sanity/lint-testing while we're here.
|
||||||
|
for fsrc in self._src_files:
|
||||||
|
if fsrc.endswith('.cpp') or fsrc.endswith('.cxx'):
|
||||||
|
raise Exception('please use .cc for c++ files; found ' + fsrc)
|
||||||
|
|
||||||
|
# Watch out for in-progress emacs edits.
|
||||||
|
# Could just ignore these but it probably means I intended
|
||||||
|
# to save something and forgot.
|
||||||
|
if '/.#' in fsrc:
|
||||||
|
print(f'{CLRRED}'
|
||||||
|
f'ERROR: Found an unsaved emacs file: "{fsrc}"'
|
||||||
|
f'{CLREND}')
|
||||||
|
sys.exit(255)
|
||||||
|
|
||||||
|
def _check_headers(self) -> None:
|
||||||
|
for header_file_raw in self._header_files:
|
||||||
|
assert header_file_raw[0] == '/'
|
||||||
|
header_file = 'src/ballistica' + header_file_raw
|
||||||
|
|
||||||
|
if header_file.endswith('.h'):
|
||||||
|
self._check_header(header_file)
|
||||||
|
|
||||||
|
if self._fixable_header_errors and not self._fix:
|
||||||
|
print(CLRRED +
|
||||||
|
'Fixable header error(s) found; pass --fix to correct.' +
|
||||||
|
CLREND)
|
||||||
|
sys.exit(255)
|
||||||
|
|
||||||
|
def _check_header(self, header_file: str) -> None:
|
||||||
|
# Make sure its define guard is correct.
|
||||||
|
guard = (header_file[4:].upper().replace('/', '_').replace('.', '_') +
|
||||||
|
'_')
|
||||||
|
with open(header_file) as fhdr:
|
||||||
|
lines = fhdr.read().splitlines()
|
||||||
|
expected_lines = [(0, '// Copyright 2019 Eric Froemling'),
|
||||||
|
(2, '#ifndef ' + guard), (3, '#define ' + guard),
|
||||||
|
(-1, '#endif // ' + guard)]
|
||||||
|
errors_found = False
|
||||||
|
can_fix = True
|
||||||
|
for line, expected in expected_lines:
|
||||||
|
if lines[line] != expected:
|
||||||
|
errors_found = True
|
||||||
|
print("Incorrect line " + str(line) + " in " + header_file +
|
||||||
|
":\n"
|
||||||
|
"Expected: " + expected + "\n"
|
||||||
|
"Found: " + lines[line])
|
||||||
|
|
||||||
|
# If the beginning of the line differs, don't attempt auto-fix.
|
||||||
|
if lines[line][:16] != expected[:16]:
|
||||||
|
can_fix = False
|
||||||
|
if errors_found:
|
||||||
|
if can_fix:
|
||||||
|
self._fixable_header_errors.setdefault(header_file,
|
||||||
|
[]).append(
|
||||||
|
(line,
|
||||||
|
expected))
|
||||||
|
else:
|
||||||
|
print(CLRRED + "Error found in '" + header_file +
|
||||||
|
"'. Not auto-fixable; please correct manually." +
|
||||||
|
CLREND)
|
||||||
|
sys.exit(255)
|
||||||
|
|
||||||
def _update_visual_studio_project(self, fname: str, src_root: str) -> None:
|
def _update_visual_studio_project(self, fname: str, src_root: str) -> None:
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
@ -334,6 +334,7 @@ class App:
|
|||||||
self._header_files = sorted(header_files)
|
self._header_files = sorted(header_files)
|
||||||
|
|
||||||
def _check_python_files(self) -> None:
|
def _check_python_files(self) -> None:
|
||||||
|
|
||||||
# Make sure all module dirs in python scripts contain an __init__.py
|
# Make sure all module dirs in python scripts contain an __init__.py
|
||||||
scripts_dir = 'assets/src/data/scripts'
|
scripts_dir = 'assets/src/data/scripts'
|
||||||
for root, _dirs, files in os.walk(scripts_dir):
|
for root, _dirs, files in os.walk(scripts_dir):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user