diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index 5e46b2e7..fcb5af3b 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -54,6 +54,7 @@ anroid antigravity apichanges + apis apks appcfg appconfig @@ -934,6 +935,7 @@ minigames minusbutton minval + minver mios mipmap mipmaps @@ -1689,6 +1691,7 @@ vmshell vmware vmwarevm + vnums vobj voffs vorbis @@ -1696,6 +1699,7 @@ vrmode vrtesting vscode + vstr vsync vsyncs vval diff --git a/Makefile b/Makefile index 039aeb9f..80509e66 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ DOCPREFIX = "ballisticacore_" ################################################################################ # List targets in this Makefile and basic descriptions for them. -help: list +help: @tools/snippets makefile_target_list Makefile # Prerequisites that should be in place before running most any other build; @@ -448,7 +448,7 @@ TOOL_CFG_SRC = tools/efrotools/snippets.py config/config.json .pycheckers: config/toolconfigsrc/pycheckers ${TOOL_CFG_SRC} ${TOOL_CFG_INST} $< $@ -.cache/checkenv: +.cache/checkenv: tools/snippets @tools/snippets checkenv @mkdir -p .cache @touch .cache/checkenv diff --git a/tools/efrotools/efrocache.py b/tools/efrotools/efrocache.py index c111e68b..acf55684 100644 --- a/tools/efrotools/efrocache.py +++ b/tools/efrotools/efrocache.py @@ -210,7 +210,7 @@ def update_cache(makefile_dirs: List[str]) -> None: # Push what we just wrote to the staging server print('Pushing cache to staging...', flush=True) - run('rsync --recursive build/efrocache/' + run('rsync --progress --recursive build/efrocache/' ' ubuntu@ballistica.net:files.ballistica.net/cache/ba1/') print(f'Cache update successful!') diff --git a/tools/snippets b/tools/snippets index 633dde22..1cf147eb 100755 --- a/tools/snippets +++ b/tools/snippets @@ -49,7 +49,7 @@ from efrotools.snippets import ( # pylint: disable=unused-import compile_python_files) if TYPE_CHECKING: - from typing import Optional, List + from typing import Optional, List, Sequence # Parts of full-tests suite we only run on particular days. # (This runs in listed order so should be randomized by hand to avoid @@ -640,11 +640,63 @@ def warm_start_asset_build() -> None: check=True) +def _vstr(nums: Sequence[int]) -> str: + return '.'.join(str(i) for i in nums) + + def checkenv() -> None: """Check for tools necessary to build and run the app.""" - if subprocess.run(['which', 'python3.7'], check=False, + print('Checking environment...', flush=True) + + python_bin = 'python3.7' + pylint_min_ver = [2, 4, 3] + mypy_min_ver = [0, 740] + + # Make sure they've got our target python version. + if subprocess.run(['which', python_bin], check=False, capture_output=True).returncode != 0: - raise CleanError('python3.7 is required for these builds.') + raise CleanError(f'{python_bin} is required.') + + # Make sure they've got pip for that python version. + if subprocess.run(f"{python_bin} -m pip --version", + shell=True, + check=False, + capture_output=True).returncode != 0: + raise CleanError('pip (for {python_bin}) is required.') + + # Check for some required python modules. + for modname, minver in [ + ('pylint', pylint_min_ver), + ('mypy', mypy_min_ver), + ('typing_extensions', None), + ('pytz', None), + ]: + + if minver is not None: + results = subprocess.run(f'{python_bin} -m {modname} --version', + shell=True, + check=False, + capture_output=True) + else: + results = subprocess.run(f'{python_bin} -c "import {modname}"', + shell=True, + check=False, + capture_output=True) + if results.returncode != 0: + raise CleanError( + f'{modname} (for {python_bin}) is required.\n' + f'To install it, try: "{python_bin} -m pip install {modname}"') + if minver is not None: + ver_line = results.stdout.decode().splitlines()[0] + assert modname in ver_line + vnums = [int(x) for x in ver_line.split()[-1].split('.')] + assert len(vnums) == len(minver) + if vnums < minver: + raise CleanError( + f'{modname} ver. {_vstr(minver)} or newer required;' + f' found {_vstr(vnums)}') + + print('Environment ok.', flush=True) def make_prefab() -> None: