mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-26 17:03:14 +08:00
More work towards Android 1.5
This commit is contained in:
parent
0fdc5f1fc4
commit
97457e5bfd
@ -4135,16 +4135,16 @@
|
||||
"assets/build/windows/x64/vc_redist.x64.exe": "https://files.ballistica.net/cache/ba1/ea/19/8b8787d81abcdce158ba608cd24f",
|
||||
"assets/build/windows/x64/vcruntime140_1d.dll": "https://files.ballistica.net/cache/ba1/11/d8/ff6344b429b00c24d9a1930d4338",
|
||||
"assets/build/windows/x64/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/20/33/0825e11e6518f87ece3009309933",
|
||||
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/29/9c/24a918c046b06f010d9948458a09",
|
||||
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2e/1c/2285cc92d83ce3a32b26c020cb71",
|
||||
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/24/b6/9410d8cf8be5aaf2ffad07964950",
|
||||
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/48/c4/2bdd6802858b92c348df702c9dcd",
|
||||
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b4/ca/0a1426dabc53a9f90a6beb011423",
|
||||
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f8/ef/4186b927c2675c3e4dfa19ba180d",
|
||||
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/29/59/60175945534d87709dfc29d1b180",
|
||||
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5c/b8/16b868c1bbd8b1be2ebaf4da4d31",
|
||||
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/30/6c/33b6b194062212beeae3043515a3",
|
||||
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/4b/24/c54be077112185f6a3d2c67641ea",
|
||||
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ee/6e/a9d59e81b549b992673d20f84f11",
|
||||
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/5b/73/97159eb1d7dfb4018c5a1241f164"
|
||||
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fc/3d/ab2ccd1f76fec48d1d1f8cc07aa4",
|
||||
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e2/e1/672e2ccaceadf3b0867bf3b887a4",
|
||||
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5f/9d/90533da6e9d91dc6b932a2aa7f43",
|
||||
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/ea/6af215aa0cab66e46c7041a7b091",
|
||||
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/55/66/b8bc31f6818606e282eda887939f",
|
||||
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/52/e7/2419b41d3524735dc709338c4290",
|
||||
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/11/b5/5ee7f3ba18e2683d56b8a020b39f",
|
||||
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/24/5f/6953fd0f2b47e943ea734bc14911",
|
||||
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/1b/fb/739c5d5dc13218efdeaaa020c9f9",
|
||||
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/01/15/75f7b94e3608435a4609a3992dbc",
|
||||
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/9f/9d/cf77bfbd79aed7178d9674b3af14",
|
||||
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c9/b2/6863b197eac679f85a5414525aa9"
|
||||
}
|
||||
1
.idea/dictionaries/ericf.xml
generated
1
.idea/dictionaries/ericf.xml
generated
@ -1196,6 +1196,7 @@
|
||||
<w>modder</w>
|
||||
<w>modders</w>
|
||||
<w>modename</w>
|
||||
<w>modestr</w>
|
||||
<w>modpack</w>
|
||||
<w>modtimes</w>
|
||||
<w>moduledir</w>
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
### 1.5.6 (20072)
|
||||
- Mouse wheel now works in manual camera mode on more platforms.
|
||||
- Lots of internal event-handling cleanup/reorganization in preparation for Android 1.5 update.
|
||||
- Server scripts now run in opt mode in release builds so they can use bundled .opt-1.pyc files.
|
||||
- More misc bug fixes and tidying.
|
||||
|
||||
### 1.5.5 (20069)
|
||||
- Cleaned up Windows version packaging.
|
||||
- More misc bug fixes.
|
||||
|
||||
52
Makefile
52
Makefile
@ -188,14 +188,15 @@ prefab-mac-server-debug-build: prereqs assets-cmake \
|
||||
@${STAGE_ASSETS} -cmakeserver build/prefab/mac-server/debug/dist
|
||||
|
||||
build/prefab/mac-server/debug/ballisticacore_server: \
|
||||
assets/src/server/ballisticacore_server.py
|
||||
@cp $< $@
|
||||
assets/src/server/ballisticacore_server.py tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/mac-server/debug/config_template.yaml: \
|
||||
assets/src/server/config_template.yaml \
|
||||
tools/batools/build.py \
|
||||
tools/batools/snippets.py \
|
||||
tools/bacommon/servermanager.py
|
||||
@tools/snippets filter_server_config $< $@
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/mac-server/debug/README.txt: \
|
||||
assets/src/server/README.txt
|
||||
@ -219,14 +220,15 @@ prefab-mac-server-release-build: prereqs assets-cmake \
|
||||
@${STAGE_ASSETS} -cmakeserver build/prefab/mac-server/release/dist
|
||||
|
||||
build/prefab/mac-server/release/ballisticacore_server: \
|
||||
assets/src/server/ballisticacore_server.py
|
||||
@cp $< $@
|
||||
assets/src/server/ballisticacore_server.py tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/mac-server/release/config_template.yaml: \
|
||||
assets/src/server/config_template.yaml \
|
||||
tools/batools/build.py \
|
||||
tools/batools/snippets.py \
|
||||
tools/bacommon/servermanager.py
|
||||
@tools/snippets filter_server_config $< $@
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/mac-server/release/README.txt: \
|
||||
assets/src/server/README.txt
|
||||
@ -276,14 +278,15 @@ prefab-linux-server-debug-build: prereqs assets-cmake \
|
||||
@${STAGE_ASSETS} -cmakeserver build/prefab/linux-server/debug/dist
|
||||
|
||||
build/prefab/linux-server/debug/ballisticacore_server: \
|
||||
assets/src/server/ballisticacore_server.py
|
||||
@cp $< $@
|
||||
assets/src/server/ballisticacore_server.py tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/linux-server/debug/config_template.yaml: \
|
||||
assets/src/server/config_template.yaml \
|
||||
tools/batools/build.py \
|
||||
tools/batools/snippets.py \
|
||||
tools/bacommon/servermanager.py
|
||||
@tools/snippets filter_server_config $< $@
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/linux-server/debug/README.txt: \
|
||||
assets/src/server/README.txt
|
||||
@ -307,14 +310,15 @@ prefab-linux-server-release-build: prereqs assets-cmake \
|
||||
@${STAGE_ASSETS} -cmakeserver build/prefab/linux-server/release/dist
|
||||
|
||||
build/prefab/linux-server/release/ballisticacore_server: \
|
||||
assets/src/server/ballisticacore_server.py
|
||||
@cp $< $@
|
||||
assets/src/server/ballisticacore_server.py tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/linux-server/release/config_template.yaml: \
|
||||
assets/src/server/config_template.yaml \
|
||||
tools/batools/build.py \
|
||||
tools/batools/snippets.py \
|
||||
tools/bacommon/servermanager.py
|
||||
@tools/snippets filter_server_config $< $@
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/linux-server/release/README.txt: \
|
||||
assets/src/server/README.txt
|
||||
@ -376,25 +380,26 @@ build/prefab/windows-server/debug/dist/ballisticacore_headless.exe: .efrocachema
|
||||
@tools/snippets efrocache_get $@
|
||||
|
||||
build/prefab/windows-server/debug/ballisticacore_server.py: \
|
||||
assets/src/server/ballisticacore_server.py
|
||||
@cp $< $@
|
||||
assets/src/server/ballisticacore_server.py tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/windows-server/debug/launch_ballisticacore_server.bat: \
|
||||
assets/src/server/launch_ballisticacore_server.bat
|
||||
@cp $< $@
|
||||
assets/src/server/launch_ballisticacore_server.bat tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/windows-server/debug/config_template.yaml: \
|
||||
assets/src/server/config_template.yaml \
|
||||
tools/batools/build.py \
|
||||
tools/batools/snippets.py \
|
||||
tools/bacommon/servermanager.py
|
||||
@tools/snippets filter_server_config $< $@
|
||||
@tools/snippets stage_server_file debug $< $@
|
||||
|
||||
build/prefab/windows-server/debug/README.txt: \
|
||||
assets/src/server/README.txt
|
||||
@cp $< $@
|
||||
|
||||
RUN_PREFAB_WINDOWS_SERVER_RELEASE = cd build/prefab/windows-server/release \
|
||||
&& dist/python.exe ballisticacore_server.py
|
||||
&& dist/python.exe -O ballisticacore_server.py
|
||||
|
||||
prefab-windows-server-release: prefab-windows-server-release-build
|
||||
@tools/snippets ensure_prefab_platform windows
|
||||
@ -414,18 +419,19 @@ build/prefab/windows-server/release/dist/ballisticacore_headless.exe: .efrocache
|
||||
@tools/snippets efrocache_get $@
|
||||
|
||||
build/prefab/windows-server/release/ballisticacore_server.py: \
|
||||
assets/src/server/ballisticacore_server.py
|
||||
@cp $< $@
|
||||
assets/src/server/ballisticacore_server.py tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/windows-server/release/launch_ballisticacore_server.bat: \
|
||||
assets/src/server/launch_ballisticacore_server.bat
|
||||
@cp $< $@
|
||||
assets/src/server/launch_ballisticacore_server.bat tools/batools/snippets.py
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/windows-server/release/config_template.yaml: \
|
||||
assets/src/server/config_template.yaml \
|
||||
tools/batools/build.py \
|
||||
tools/batools/snippets.py \
|
||||
tools/bacommon/servermanager.py
|
||||
@tools/snippets filter_server_config $< $@
|
||||
@tools/snippets stage_server_file release $< $@
|
||||
|
||||
build/prefab/windows-server/release/README.txt: \
|
||||
assets/src/server/README.txt
|
||||
|
||||
@ -51,7 +51,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Not sure how much versioning we'll do with this, but this will get
|
||||
# printed at startup in case we need it.
|
||||
VERSION_STR = '1.0.1'
|
||||
VERSION_STR = '1.0.2'
|
||||
|
||||
|
||||
class ServerManagerApp:
|
||||
@ -106,9 +106,13 @@ class ServerManagerApp:
|
||||
|
||||
# Print basic usage info in interactive mode.
|
||||
if sys.stdin.isatty():
|
||||
if __debug__:
|
||||
modestr = '(debug mode)'
|
||||
else:
|
||||
modestr = '(opt mode)'
|
||||
print(f'{Clr.CYN}{Clr.BLD}BallisticaCore server'
|
||||
f' manager {VERSION_STR}'
|
||||
f' starting up...{Clr.RST}\n'
|
||||
f' starting up {modestr}...{Clr.RST}\n'
|
||||
f'{Clr.CYN}Use the "mgr" object to make'
|
||||
f' live server adjustments.\n'
|
||||
f'Type "help(mgr)" for more information.{Clr.RST}')
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
:: Simply run the ballisticacore_server.py script with the bundled
|
||||
:: python interpreter. Run in opt-mode so we pick up all the
|
||||
:: bundled .opt-1.pyc files too.
|
||||
dist\\python.exe -O ballisticacore_server.py
|
||||
:: Python interpreter.
|
||||
dist\\python.exe ballisticacore_server.py
|
||||
|
||||
618
tools/batools/snippets.py
Normal file
618
tools/batools/snippets.py
Normal file
@ -0,0 +1,618 @@
|
||||
# Copyright (c) 2011-2020 Eric Froemling
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# -----------------------------------------------------------------------------
|
||||
"""Standard snippets that can be pulled into project snippets scripts.
|
||||
|
||||
A snippet is a mini-program that directly takes input from stdin and does
|
||||
some focused task. This module consists of ballistica-specific ones.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
# Note: import as little as possible here at the module level to
|
||||
# keep launch times fast for small snippets.
|
||||
import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from efrotools.snippets import PROJROOT
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def stage_server_file() -> None:
|
||||
"""Stage files for the server environment with some filtering."""
|
||||
import os
|
||||
import subprocess
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
from efrotools import replace_one
|
||||
if len(sys.argv) != 5:
|
||||
raise CleanError('Expected 3 args (mode, infile, outfile).')
|
||||
mode, infilename, outfilename = sys.argv[2], sys.argv[3], sys.argv[4]
|
||||
if mode not in ('debug', 'release'):
|
||||
raise CleanError(f"Invalid mode '{mode}'; expected debug or release.")
|
||||
|
||||
print(f'Building server file: {os.path.basename(outfilename)}')
|
||||
|
||||
basename = os.path.basename(infilename)
|
||||
if basename == 'config_template.yaml':
|
||||
# Inject all available config values into the config file.
|
||||
batools.build.filter_server_config(str(PROJROOT), infilename,
|
||||
outfilename)
|
||||
elif basename == 'ballisticacore_server.py':
|
||||
# Run Python in opt mode for release builds.
|
||||
with open(infilename) as infile:
|
||||
lines = infile.read().splitlines()
|
||||
if mode == 'release':
|
||||
lines[0] = replace_one(lines[0], '#!/usr/bin/env python3.7',
|
||||
'#!/usr/bin/env python3.7 -O')
|
||||
with open(outfilename, 'w') as outfile:
|
||||
outfile.write('\n'.join(lines) + '\n')
|
||||
subprocess.run(['chmod', '+x', outfilename], check=True)
|
||||
elif basename == 'launch_ballisticacore_server.bat':
|
||||
# Run Python in opt mode for release builds.
|
||||
with open(infilename) as infile:
|
||||
lines = infile.read().splitlines()
|
||||
if mode == 'release':
|
||||
lines[1] = replace_one(
|
||||
lines[1], ':: Python interpreter.',
|
||||
':: Python interpreter.'
|
||||
' (in opt mode so we use bundled .opt-1.pyc files)')
|
||||
lines[2] = replace_one(
|
||||
lines[2], 'dist\\\\python.exe ballisticacore_server.py',
|
||||
'dist\\\\python.exe -O ballisticacore_server.py')
|
||||
with open(outfilename, 'w') as outfile:
|
||||
outfile.write('\n'.join(lines) + '\n')
|
||||
else:
|
||||
raise CleanError(f"Unknown server file for staging: '{basename}'.")
|
||||
|
||||
|
||||
def py_examine() -> None:
|
||||
"""Run a python examination at a given point in a given file."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import efrotools
|
||||
if len(sys.argv) != 7:
|
||||
print('ERROR: expected 7 args')
|
||||
sys.exit(255)
|
||||
filename = Path(sys.argv[2])
|
||||
line = int(sys.argv[3])
|
||||
column = int(sys.argv[4])
|
||||
selection: Optional[str] = (None if sys.argv[5] == '' else sys.argv[5])
|
||||
operation = sys.argv[6]
|
||||
|
||||
# This stuff assumes it is being run from project root.
|
||||
os.chdir(PROJROOT)
|
||||
|
||||
# Set up pypaths so our main distro stuff works.
|
||||
scriptsdir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(sys.argv[0]),
|
||||
'../assets/src/ba_data/python'))
|
||||
toolsdir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(sys.argv[0]), '../tools'))
|
||||
if scriptsdir not in sys.path:
|
||||
sys.path.append(scriptsdir)
|
||||
if toolsdir not in sys.path:
|
||||
sys.path.append(toolsdir)
|
||||
efrotools.py_examine(PROJROOT, filename, line, column, selection,
|
||||
operation)
|
||||
|
||||
|
||||
def clean_orphaned_assets() -> None:
|
||||
"""Remove asset files that are no longer part of the build."""
|
||||
import os
|
||||
import json
|
||||
import efrotools
|
||||
|
||||
# Operate from dist root..
|
||||
os.chdir(PROJROOT)
|
||||
|
||||
# Our manifest is split into 2 files (public and private)
|
||||
with open('assets/.asset_manifest_public.json') as infile:
|
||||
manifest = set(json.loads(infile.read()))
|
||||
with open('assets/.asset_manifest_private.json') as infile:
|
||||
manifest.update(set(json.loads(infile.read())))
|
||||
for root, _dirs, fnames in os.walk('assets/build'):
|
||||
for fname in fnames:
|
||||
fpath = os.path.join(root, fname)
|
||||
fpathrel = fpath[13:] # paths are relative to assets/build
|
||||
if fpathrel not in manifest:
|
||||
print(f'Removing orphaned asset file: {fpath}')
|
||||
os.unlink(fpath)
|
||||
|
||||
# Lastly, clear empty dirs.
|
||||
efrotools.run('find assets/build -depth -empty -type d -delete')
|
||||
|
||||
|
||||
def fix_mac_ssh() -> None:
|
||||
"""Turn off mac ssh password access.
|
||||
|
||||
(This totally doesn't belong in this project btw..)
|
||||
"""
|
||||
configpath = '/etc/ssh/sshd_config'
|
||||
with open(configpath) as infile:
|
||||
lines = infile.readlines()
|
||||
index = lines.index('#PasswordAuthentication yes\n')
|
||||
lines[index] = 'PasswordAuthentication no\n'
|
||||
index = lines.index('#ChallengeResponseAuthentication yes\n')
|
||||
lines[index] = 'ChallengeResponseAuthentication no\n'
|
||||
index = lines.index('UsePAM yes\n')
|
||||
lines[index] = 'UsePAM no\n'
|
||||
with open(configpath, 'w') as outfile:
|
||||
outfile.write(''.join(lines))
|
||||
print('SSH config updated successfully!')
|
||||
|
||||
|
||||
def check_mac_ssh() -> None:
|
||||
"""Make sure ssh password access is turned off.
|
||||
|
||||
(This totally doesn't belong here, but I use it it to remind myself to
|
||||
fix mac ssh after system updates which blow away ssh customizations).
|
||||
"""
|
||||
with open('/etc/ssh/sshd_config') as infile:
|
||||
lines = infile.read().splitlines()
|
||||
if ('UsePAM yes' in lines or '#PasswordAuthentication yes' in lines
|
||||
or '#ChallengeResponseAuthentication yes' in lines):
|
||||
print('ERROR: ssh config is allowing password access.\n'
|
||||
'To fix: sudo tools/snippets fix_mac_ssh')
|
||||
sys.exit(255)
|
||||
print('password ssh auth seems disabled; hooray!')
|
||||
|
||||
|
||||
def resize_image() -> None:
|
||||
"""Resize an image and save it to a new location.
|
||||
|
||||
args: xres, yres, src, dst
|
||||
"""
|
||||
import os
|
||||
import efrotools
|
||||
if len(sys.argv) != 6:
|
||||
raise Exception('expected 5 args')
|
||||
width = int(sys.argv[2])
|
||||
height = int(sys.argv[3])
|
||||
src = sys.argv[4]
|
||||
dst = sys.argv[5]
|
||||
if not dst.endswith('.png'):
|
||||
raise RuntimeError(f'dst must be a png; got "{dst}"')
|
||||
if not src.endswith('.png'):
|
||||
raise RuntimeError(f'src must be a png; got "{src}"')
|
||||
print('Creating: ' + os.path.basename(dst), file=sys.stderr)
|
||||
efrotools.run(f'convert "{src}" -resize {width}x{height} "{dst}"')
|
||||
|
||||
|
||||
def check_clean_safety() -> None:
|
||||
"""Ensure all files are are added to git or in gitignore.
|
||||
|
||||
Use to avoid losing work if we accidentally do a clean without
|
||||
adding something.
|
||||
"""
|
||||
import os
|
||||
from efrotools.snippets import check_clean_safety as std_snippet
|
||||
|
||||
# First do standard checks.
|
||||
std_snippet()
|
||||
|
||||
# Then also make sure there are no untracked changes to core files
|
||||
# (since we may be blowing core away here).
|
||||
spinoff_bin = os.path.join(str(PROJROOT), 'tools', 'spinoff')
|
||||
if os.path.exists(spinoff_bin):
|
||||
status = os.system(spinoff_bin + ' cleancheck')
|
||||
if status != 0:
|
||||
sys.exit(255)
|
||||
|
||||
|
||||
def archive_old_builds() -> None:
|
||||
"""Stuff our old public builds into the 'old' dir.
|
||||
|
||||
(called after we push newer ones)
|
||||
"""
|
||||
import batools.build
|
||||
if len(sys.argv) < 3:
|
||||
raise Exception('invalid arguments')
|
||||
ssh_server = sys.argv[2]
|
||||
builds_dir = sys.argv[3]
|
||||
ssh_args = sys.argv[4:]
|
||||
batools.build.archive_old_builds(ssh_server, builds_dir, ssh_args)
|
||||
|
||||
|
||||
def lazy_increment_build() -> None:
|
||||
"""Increment build number only if C++ sources have changed.
|
||||
|
||||
This is convenient to place in automatic commit/push scripts.
|
||||
It could make sense to auto update build number when scripts/assets
|
||||
change too, but a build number change requires rebuilding all binaries
|
||||
so I'll leave that as an explicit choice to save work.
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
from efro.terminal import Clr
|
||||
from efro.error import CleanError
|
||||
from efrotools import get_files_hash
|
||||
from efrotools.code import get_code_filenames
|
||||
if sys.argv[2:] not in [[], ['--update-hash-only']]:
|
||||
raise CleanError('Invalid arguments')
|
||||
update_hash_only = '--update-hash-only' in sys.argv
|
||||
codefiles = get_code_filenames(PROJROOT)
|
||||
codehash = get_files_hash(codefiles)
|
||||
hashfilename = '.cache/lazy_increment_build'
|
||||
try:
|
||||
with open(hashfilename) as infile:
|
||||
lasthash = infile.read()
|
||||
except FileNotFoundError:
|
||||
lasthash = ''
|
||||
if codehash != lasthash:
|
||||
print(f'{Clr.SMAG}Source(s) changed; incrementing build...{Clr.RST}')
|
||||
|
||||
if not update_hash_only:
|
||||
# Just go ahead and bless; this will increment the build as needed.
|
||||
# subprocess.run(['make', 'bless'], check=True)
|
||||
subprocess.run(['tools/version_utils', 'incrementbuild'],
|
||||
check=True)
|
||||
|
||||
# We probably just changed code, so we need to re-calc the hash.
|
||||
codehash = get_files_hash(codefiles)
|
||||
os.makedirs(os.path.dirname(hashfilename), exist_ok=True)
|
||||
with open(hashfilename, 'w') as outfile:
|
||||
outfile.write(codehash)
|
||||
|
||||
|
||||
def get_master_asset_src_dir() -> None:
|
||||
"""Print master-asset-source dir for this repo."""
|
||||
import subprocess
|
||||
|
||||
# Ok, for now lets simply use our hard-coded master-src
|
||||
# path if we're on master in and not otherwise. Should
|
||||
# probably make this configurable.
|
||||
output = subprocess.check_output(
|
||||
['git', 'status', '--branch', '--porcelain']).decode()
|
||||
|
||||
# Also compare repo name to split version of itself to
|
||||
# see if we're outside of core (filtering will cause mismatch if so).
|
||||
if ('origin/master' in output.splitlines()[0]
|
||||
and 'ballistica' + 'core' == 'ballisticacore'):
|
||||
|
||||
# We seem to be in master in core repo; lets do it.
|
||||
print('/Users/ericf/Dropbox/ballisticacore_master_assets')
|
||||
else:
|
||||
# Still need to supply dummy path for makefile if not..
|
||||
print('/__DUMMY_MASTER_SRC_DISABLED_PATH__')
|
||||
|
||||
|
||||
def androidaddr() -> None:
|
||||
"""Return the source file location for an android program-counter.
|
||||
|
||||
command line args: archive_dir architecture addr
|
||||
"""
|
||||
import batools.android
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) != 5:
|
||||
raise CleanError(f'ERROR: expected 3 args; got {len(sys.argv) - 2}\n'
|
||||
f'Usage: "tools/snippets android_addr'
|
||||
f' <ARCHIVE-PATH> <ARCH> <ADDR>"')
|
||||
archive_dir = sys.argv[2]
|
||||
arch = sys.argv[3]
|
||||
addr = sys.argv[4]
|
||||
batools.android.androidaddr(archive_dir=archive_dir, arch=arch, addr=addr)
|
||||
|
||||
|
||||
def push_ipa() -> None:
|
||||
"""Construct and push ios IPA for testing."""
|
||||
from pathlib import Path
|
||||
import efrotools.ios
|
||||
root = Path(sys.argv[0], '../..').resolve()
|
||||
if len(sys.argv) != 3:
|
||||
raise Exception('expected 1 arg (debug or release)')
|
||||
modename = sys.argv[2]
|
||||
efrotools.ios.push_ipa(root, modename)
|
||||
|
||||
|
||||
def printcolors() -> None:
|
||||
"""Print all colors available in efro.terminals.TerminalColor."""
|
||||
from efro.error import CleanError
|
||||
from efro.terminal import TerminalColor, Clr
|
||||
|
||||
if Clr.RED == '':
|
||||
raise CleanError('Efro color terminal output is disabled.')
|
||||
|
||||
clrnames = {getattr(Clr, s): s for s in dir(Clr) if s.isupper()}
|
||||
|
||||
# Print everything in Clr (since that's what users should be using
|
||||
# but do it in the order of TerminalColor (since Clr is just a class
|
||||
# so is unordered)
|
||||
for value in TerminalColor:
|
||||
if value is TerminalColor.RESET:
|
||||
continue
|
||||
shortname = f'Clr.{clrnames[value.value]}'
|
||||
longname = f'({value.name})'
|
||||
print(f'{shortname:<12} {longname:<20} {value.value}'
|
||||
f'The quick brown fox jumps over the lazy dog.'
|
||||
f'{TerminalColor.RESET.value}')
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_android() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_android()
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_windows() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_windows()
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_apple() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_apple()
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_linux() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_linux()
|
||||
|
||||
|
||||
def python_build_apple() -> None:
|
||||
"""Build an embeddable python for mac/ios/tvos."""
|
||||
_python_build_apple(debug=False)
|
||||
|
||||
|
||||
def python_build_apple_debug() -> None:
|
||||
"""Build embeddable python for mac/ios/tvos (dbg ver)."""
|
||||
_python_build_apple(debug=True)
|
||||
|
||||
|
||||
def _python_build_apple(debug: bool) -> None:
|
||||
"""Build an embeddable python for macOS/iOS/tvOS."""
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(PROJROOT)
|
||||
archs = ('mac', 'ios', 'tvos')
|
||||
if len(sys.argv) != 3:
|
||||
print('ERROR: expected one <ARCH> arg: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
arch = sys.argv[2]
|
||||
if arch not in archs:
|
||||
print('ERROR: invalid arch. valid values are: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
pybuild.build_apple(arch, debug=debug)
|
||||
|
||||
|
||||
def python_build_android() -> None:
|
||||
"""Build an embeddable Python lib for Android."""
|
||||
_python_build_android(debug=False)
|
||||
|
||||
|
||||
def python_build_android_debug() -> None:
|
||||
"""Build embeddable Android Python lib (debug ver)."""
|
||||
_python_build_android(debug=True)
|
||||
|
||||
|
||||
def _python_build_android(debug: bool) -> None:
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(PROJROOT)
|
||||
archs = ('arm', 'arm64', 'x86', 'x86_64')
|
||||
if len(sys.argv) != 3:
|
||||
print('ERROR: expected one <ARCH> arg: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
arch = sys.argv[2]
|
||||
if arch not in archs:
|
||||
print('ERROR: invalid arch. valid values are: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
pybuild.build_android(str(PROJROOT), arch, debug=debug)
|
||||
|
||||
|
||||
def python_android_patch() -> None:
|
||||
"""Patches Python to prep for building for Android."""
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(sys.argv[2])
|
||||
pybuild.android_patch()
|
||||
|
||||
|
||||
def python_gather() -> None:
|
||||
"""Gather build python components into the project.
|
||||
|
||||
This assumes all embeddable py builds have been run successfully.
|
||||
"""
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(PROJROOT)
|
||||
pybuild.gather()
|
||||
|
||||
|
||||
def capitalize() -> None:
|
||||
"""Print args capitalized."""
|
||||
print(' '.join(w.capitalize() for w in sys.argv[2:]))
|
||||
|
||||
|
||||
def efrocache_update() -> None:
|
||||
"""Build & push files to efrocache for public access."""
|
||||
from efrotools.efrocache import update_cache
|
||||
makefile_dirs = ['', 'assets']
|
||||
update_cache(makefile_dirs)
|
||||
|
||||
|
||||
def efrocache_get() -> None:
|
||||
"""Get a file from efrocache."""
|
||||
from efrotools.efrocache import get_target
|
||||
if len(sys.argv) != 3:
|
||||
raise RuntimeError('Expected exactly 1 arg')
|
||||
get_target(sys.argv[2])
|
||||
|
||||
|
||||
def get_modern_make() -> None:
|
||||
"""Print name of a modern make command."""
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
# Mac gnu make is outdated (due to newer versions using GPL3 I believe).
|
||||
# so let's return 'gmake' there which will point to homebrew make which
|
||||
# should be up to date.
|
||||
if platform.system() == 'Darwin':
|
||||
if subprocess.run(['which', 'gmake'], check=False,
|
||||
capture_output=True).returncode != 0:
|
||||
print(
|
||||
'WARNING: this requires gmake (mac system make is too old).'
|
||||
" Install it with 'brew install make'",
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
print('gmake')
|
||||
else:
|
||||
print('make')
|
||||
|
||||
|
||||
def warm_start_asset_build() -> None:
|
||||
"""Prep asset builds to run faster."""
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from efrotools import getconfig
|
||||
public: bool = getconfig(PROJROOT)['public']
|
||||
|
||||
if public:
|
||||
from efrotools.efrocache import warm_start_cache
|
||||
os.chdir(PROJROOT)
|
||||
warm_start_cache()
|
||||
else:
|
||||
# For internal builds we don't use efrocache but we do use an
|
||||
# internal build cache. Download an initial cache/etc. if need be.
|
||||
subprocess.run(
|
||||
[str(Path(PROJROOT, 'tools/convert_util')), '--init-asset-cache'],
|
||||
check=True)
|
||||
|
||||
|
||||
def update_docs_md() -> None:
|
||||
"""Updates docs markdown files if necessary."""
|
||||
import batools.build
|
||||
batools.build.update_docs_md(check='--check' in sys.argv)
|
||||
|
||||
|
||||
def list_pip_reqs() -> None:
|
||||
"""List Python Pip packages needed for this project."""
|
||||
from batools.build import get_pip_reqs
|
||||
print(' '.join(get_pip_reqs()))
|
||||
|
||||
|
||||
def install_pip_reqs() -> None:
|
||||
"""Install Python Pip packages needed for this project."""
|
||||
import subprocess
|
||||
from efrotools import PYTHON_BIN
|
||||
from efro.terminal import Clr
|
||||
from batools.build import get_pip_reqs
|
||||
subprocess.run([PYTHON_BIN, '-m', 'pip', 'install', '--upgrade'] +
|
||||
get_pip_reqs(),
|
||||
check=True)
|
||||
print(f'{Clr.GRN}All pip requirements installed!{Clr.RST}')
|
||||
|
||||
|
||||
def checkenv() -> None:
|
||||
"""Check for tools necessary to build and run the app."""
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
try:
|
||||
batools.build.checkenv()
|
||||
except RuntimeError as exc:
|
||||
raise CleanError(exc)
|
||||
|
||||
|
||||
def ensure_prefab_platform() -> None:
|
||||
"""Ensure we are running on a particular prefab platform."""
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) != 3:
|
||||
raise CleanError('Expected 1 platform name arg.')
|
||||
needed = sys.argv[2]
|
||||
current = batools.build.get_current_prefab_platform()
|
||||
if current != needed:
|
||||
raise CleanError(
|
||||
f'Incorrect platform: we are {current}, this requires {needed}.')
|
||||
|
||||
|
||||
def prefab_run_var() -> None:
|
||||
"""Print a var for running a prefab run for the current platform.
|
||||
|
||||
We use this mechanism instead of just having a command recursively run
|
||||
a make target so that ctrl-c can be handled cleanly and directly by the
|
||||
command getting run instead of generating extra errors in the recursive
|
||||
processes.
|
||||
"""
|
||||
import batools.build
|
||||
if len(sys.argv) != 3:
|
||||
raise RuntimeError('Expected 1 arg.')
|
||||
base = sys.argv[2].replace('-', '_').upper()
|
||||
platform = batools.build.get_current_prefab_platform().upper()
|
||||
print(f'RUN_PREFAB_{platform}_{base}', end='')
|
||||
|
||||
|
||||
def make_prefab() -> None:
|
||||
"""Run prefab builds for the current platform."""
|
||||
import subprocess
|
||||
import batools.build
|
||||
if len(sys.argv) != 3:
|
||||
raise RuntimeError('Expected one argument')
|
||||
target = batools.build.PrefabTarget(sys.argv[2])
|
||||
platform = batools.build.get_current_prefab_platform()
|
||||
try:
|
||||
subprocess.run(['make', f'prefab-{platform}-{target.value}-build'],
|
||||
check=True)
|
||||
except (Exception, KeyboardInterrupt) as exc:
|
||||
if str(exc):
|
||||
print(f'make_prefab failed with error: {exc}')
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def update_makebob() -> None:
|
||||
"""Build fresh make_bob binaries for all relevant platforms."""
|
||||
import batools.build
|
||||
batools.build.update_makebob()
|
||||
|
||||
|
||||
def lazybuild() -> None:
|
||||
"""Run a build command only if an input has changed."""
|
||||
import subprocess
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) < 5:
|
||||
raise CleanError('Expected at least 3 args')
|
||||
try:
|
||||
category = batools.build.SourceCategory(sys.argv[2])
|
||||
except ValueError as exc:
|
||||
raise CleanError(exc)
|
||||
target = sys.argv[3]
|
||||
command = ' '.join(sys.argv[4:])
|
||||
try:
|
||||
batools.build.lazybuild(target, category, command)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
raise CleanError(exc)
|
||||
562
tools/snippets
562
tools/snippets
@ -32,10 +32,10 @@ from __future__ import annotations
|
||||
|
||||
# Note: import as little as possible here at the module level to
|
||||
# keep launch times fast for small snippets.
|
||||
import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
# Pull in some standard snippets we want to expose.
|
||||
# Pull in the snippets we want to expose. Its more efficient to define them in
|
||||
# modules rather than inline here because we'll be able to load them via pyc.
|
||||
# pylint: disable=unused-import
|
||||
from efrotools.snippets import (
|
||||
PROJROOT, snippets_main, formatcode, formatscripts, formatmakefile,
|
||||
@ -43,554 +43,22 @@ from efrotools.snippets import (
|
||||
sync, sync_all, scriptfiles, pycharm, clioncode, androidstudiocode,
|
||||
makefile_target_list, spelling, spelling_all, pytest, echo,
|
||||
compile_python_files)
|
||||
from batools.snippets import (
|
||||
stage_server_file, py_examine, fix_mac_ssh, check_mac_ssh, resize_image,
|
||||
check_clean_safety, clean_orphaned_assets, archive_old_builds,
|
||||
lazy_increment_build, get_master_asset_src_dir, androidaddr, push_ipa,
|
||||
printcolors, gen_fulltest_buildfile_android,
|
||||
gen_fulltest_buildfile_windows, gen_fulltest_buildfile_apple,
|
||||
gen_fulltest_buildfile_linux, python_build_apple, python_build_apple_debug,
|
||||
python_build_android, python_build_android_debug, python_android_patch,
|
||||
python_gather, capitalize, efrocache_update, efrocache_get,
|
||||
get_modern_make, warm_start_asset_build, update_docs_md, list_pip_reqs,
|
||||
install_pip_reqs, checkenv, ensure_prefab_platform, prefab_run_var,
|
||||
make_prefab, update_makebob, lazybuild)
|
||||
# pylint: enable=unused-import
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def archive_old_builds() -> None:
|
||||
"""Stuff our old public builds into the 'old' dir.
|
||||
|
||||
(called after we push newer ones)
|
||||
"""
|
||||
import batools.build
|
||||
if len(sys.argv) < 3:
|
||||
raise Exception('invalid arguments')
|
||||
ssh_server = sys.argv[2]
|
||||
builds_dir = sys.argv[3]
|
||||
ssh_args = sys.argv[4:]
|
||||
batools.build.archive_old_builds(ssh_server, builds_dir, ssh_args)
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_android() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_android()
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_windows() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_windows()
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_apple() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_apple()
|
||||
|
||||
|
||||
def gen_fulltest_buildfile_linux() -> None:
|
||||
"""Generate fulltest command list for jenkins.
|
||||
|
||||
(so we see nice pretty split-up build trees)
|
||||
"""
|
||||
import batools.build
|
||||
batools.build.gen_fulltest_buildfile_linux()
|
||||
|
||||
|
||||
def resize_image() -> None:
|
||||
"""Resize an image and save it to a new location.
|
||||
|
||||
args: xres, yres, src, dst
|
||||
"""
|
||||
import os
|
||||
import efrotools
|
||||
if len(sys.argv) != 6:
|
||||
raise Exception('expected 5 args')
|
||||
width = int(sys.argv[2])
|
||||
height = int(sys.argv[3])
|
||||
src = sys.argv[4]
|
||||
dst = sys.argv[5]
|
||||
if not dst.endswith('.png'):
|
||||
raise RuntimeError(f'dst must be a png; got "{dst}"')
|
||||
if not src.endswith('.png'):
|
||||
raise RuntimeError(f'src must be a png; got "{src}"')
|
||||
print('Creating: ' + os.path.basename(dst), file=sys.stderr)
|
||||
efrotools.run(f'convert "{src}" -resize {width}x{height} "{dst}"')
|
||||
|
||||
|
||||
def check_clean_safety() -> None:
|
||||
"""Ensure all files are are added to git or in gitignore.
|
||||
|
||||
Use to avoid losing work if we accidentally do a clean without
|
||||
adding something.
|
||||
"""
|
||||
import os
|
||||
from efrotools.snippets import check_clean_safety as std_snippet
|
||||
|
||||
# First do standard checks.
|
||||
std_snippet()
|
||||
|
||||
# Then also make sure there are no untracked changes to core files
|
||||
# (since we may be blowing core away here).
|
||||
spinoff_bin = os.path.join(str(PROJROOT), 'tools', 'spinoff')
|
||||
if os.path.exists(spinoff_bin):
|
||||
status = os.system(spinoff_bin + ' cleancheck')
|
||||
if status != 0:
|
||||
sys.exit(255)
|
||||
|
||||
|
||||
def get_master_asset_src_dir() -> None:
|
||||
"""Print master-asset-source dir for this repo."""
|
||||
import subprocess
|
||||
|
||||
# Ok, for now lets simply use our hard-coded master-src
|
||||
# path if we're on master in and not otherwise. Should
|
||||
# probably make this configurable.
|
||||
output = subprocess.check_output(
|
||||
['git', 'status', '--branch', '--porcelain']).decode()
|
||||
|
||||
# Also compare repo name to split version of itself to
|
||||
# see if we're outside of core (filtering will cause mismatch if so).
|
||||
if ('origin/master' in output.splitlines()[0]
|
||||
and 'ballistica' + 'core' == 'ballisticacore'):
|
||||
|
||||
# We seem to be in master in core repo; lets do it.
|
||||
print('/Users/ericf/Dropbox/ballisticacore_master_assets')
|
||||
else:
|
||||
# Still need to supply dummy path for makefile if not..
|
||||
print('/__DUMMY_MASTER_SRC_DISABLED_PATH__')
|
||||
|
||||
|
||||
def androidaddr() -> None:
|
||||
"""Return the source file location for an android program-counter.
|
||||
|
||||
command line args: archive_dir architecture addr
|
||||
"""
|
||||
import batools.android
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) != 5:
|
||||
raise CleanError(f'ERROR: expected 3 args; got {len(sys.argv) - 2}\n'
|
||||
f'Usage: "tools/snippets android_addr'
|
||||
f' <ARCHIVE-PATH> <ARCH> <ADDR>"')
|
||||
archive_dir = sys.argv[2]
|
||||
arch = sys.argv[3]
|
||||
addr = sys.argv[4]
|
||||
batools.android.androidaddr(archive_dir=archive_dir, arch=arch, addr=addr)
|
||||
|
||||
|
||||
def python_build_apple() -> None:
|
||||
"""Build an embeddable python for mac/ios/tvos."""
|
||||
_python_build_apple(debug=False)
|
||||
|
||||
|
||||
def python_build_apple_debug() -> None:
|
||||
"""Build embeddable python for mac/ios/tvos (dbg ver)."""
|
||||
_python_build_apple(debug=True)
|
||||
|
||||
|
||||
def _python_build_apple(debug: bool) -> None:
|
||||
"""Build an embeddable python for macOS/iOS/tvOS."""
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(PROJROOT)
|
||||
archs = ('mac', 'ios', 'tvos')
|
||||
if len(sys.argv) != 3:
|
||||
print('ERROR: expected one <ARCH> arg: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
arch = sys.argv[2]
|
||||
if arch not in archs:
|
||||
print('ERROR: invalid arch. valid values are: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
pybuild.build_apple(arch, debug=debug)
|
||||
|
||||
|
||||
def python_build_android() -> None:
|
||||
"""Build an embeddable Python lib for Android."""
|
||||
_python_build_android(debug=False)
|
||||
|
||||
|
||||
def python_build_android_debug() -> None:
|
||||
"""Build embeddable Android Python lib (debug ver)."""
|
||||
_python_build_android(debug=True)
|
||||
|
||||
|
||||
def _python_build_android(debug: bool) -> None:
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(PROJROOT)
|
||||
archs = ('arm', 'arm64', 'x86', 'x86_64')
|
||||
if len(sys.argv) != 3:
|
||||
print('ERROR: expected one <ARCH> arg: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
arch = sys.argv[2]
|
||||
if arch not in archs:
|
||||
print('ERROR: invalid arch. valid values are: ' + ', '.join(archs))
|
||||
sys.exit(255)
|
||||
pybuild.build_android(str(PROJROOT), arch, debug=debug)
|
||||
|
||||
|
||||
def python_android_patch() -> None:
|
||||
"""Patches Python to prep for building for Android."""
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(sys.argv[2])
|
||||
pybuild.android_patch()
|
||||
|
||||
|
||||
def python_gather() -> None:
|
||||
"""Gather build python components into the project.
|
||||
|
||||
This assumes all embeddable py builds have been run successfully.
|
||||
"""
|
||||
import os
|
||||
from efrotools import pybuild
|
||||
os.chdir(PROJROOT)
|
||||
pybuild.gather()
|
||||
|
||||
|
||||
def clean_orphaned_assets() -> None:
|
||||
"""Remove asset files that are no longer part of the build."""
|
||||
import os
|
||||
import json
|
||||
import efrotools
|
||||
|
||||
# Operate from dist root..
|
||||
os.chdir(PROJROOT)
|
||||
|
||||
# Our manifest is split into 2 files (public and private)
|
||||
with open('assets/.asset_manifest_public.json') as infile:
|
||||
manifest = set(json.loads(infile.read()))
|
||||
with open('assets/.asset_manifest_private.json') as infile:
|
||||
manifest.update(set(json.loads(infile.read())))
|
||||
for root, _dirs, fnames in os.walk('assets/build'):
|
||||
for fname in fnames:
|
||||
fpath = os.path.join(root, fname)
|
||||
fpathrel = fpath[13:] # paths are relative to assets/build
|
||||
if fpathrel not in manifest:
|
||||
print(f'Removing orphaned asset file: {fpath}')
|
||||
os.unlink(fpath)
|
||||
|
||||
# Lastly, clear empty dirs.
|
||||
efrotools.run('find assets/build -depth -empty -type d -delete')
|
||||
|
||||
|
||||
def py_examine() -> None:
|
||||
"""Run a python examination at a given point in a given file."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import efrotools
|
||||
if len(sys.argv) != 7:
|
||||
print('ERROR: expected 7 args')
|
||||
sys.exit(255)
|
||||
filename = Path(sys.argv[2])
|
||||
line = int(sys.argv[3])
|
||||
column = int(sys.argv[4])
|
||||
selection: Optional[str] = (None if sys.argv[5] == '' else sys.argv[5])
|
||||
operation = sys.argv[6]
|
||||
|
||||
# This stuff assumes it is being run from project root.
|
||||
os.chdir(PROJROOT)
|
||||
|
||||
# Set up pypaths so our main distro stuff works.
|
||||
scriptsdir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(sys.argv[0]),
|
||||
'../assets/src/ba_data/python'))
|
||||
toolsdir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(sys.argv[0]), '../tools'))
|
||||
if scriptsdir not in sys.path:
|
||||
sys.path.append(scriptsdir)
|
||||
if toolsdir not in sys.path:
|
||||
sys.path.append(toolsdir)
|
||||
efrotools.py_examine(PROJROOT, filename, line, column, selection,
|
||||
operation)
|
||||
|
||||
|
||||
def push_ipa() -> None:
|
||||
"""Construct and push ios IPA for testing."""
|
||||
from pathlib import Path
|
||||
import efrotools.ios
|
||||
root = Path(sys.argv[0], '../..').resolve()
|
||||
if len(sys.argv) != 3:
|
||||
raise Exception('expected 1 arg (debug or release)')
|
||||
modename = sys.argv[2]
|
||||
efrotools.ios.push_ipa(root, modename)
|
||||
|
||||
|
||||
def fix_mac_ssh() -> None:
|
||||
"""Turn off mac ssh password access.
|
||||
|
||||
(This totally doesn't belong in this project btw..)
|
||||
"""
|
||||
configpath = '/etc/ssh/sshd_config'
|
||||
with open(configpath) as infile:
|
||||
lines = infile.readlines()
|
||||
index = lines.index('#PasswordAuthentication yes\n')
|
||||
lines[index] = 'PasswordAuthentication no\n'
|
||||
index = lines.index('#ChallengeResponseAuthentication yes\n')
|
||||
lines[index] = 'ChallengeResponseAuthentication no\n'
|
||||
index = lines.index('UsePAM yes\n')
|
||||
lines[index] = 'UsePAM no\n'
|
||||
with open(configpath, 'w') as outfile:
|
||||
outfile.write(''.join(lines))
|
||||
print('SSH config updated successfully!')
|
||||
|
||||
|
||||
def check_mac_ssh() -> None:
|
||||
"""Make sure ssh password access is turned off.
|
||||
|
||||
(This totally doesn't belong here, but I use it it to remind myself to
|
||||
fix mac ssh after system updates which blow away ssh customizations).
|
||||
"""
|
||||
with open('/etc/ssh/sshd_config') as infile:
|
||||
lines = infile.read().splitlines()
|
||||
if ('UsePAM yes' in lines or '#PasswordAuthentication yes' in lines
|
||||
or '#ChallengeResponseAuthentication yes' in lines):
|
||||
print('ERROR: ssh config is allowing password access.\n'
|
||||
'To fix: sudo tools/snippets fix_mac_ssh')
|
||||
sys.exit(255)
|
||||
print('password ssh auth seems disabled; hooray!')
|
||||
|
||||
|
||||
def capitalize() -> None:
|
||||
"""Print args capitalized."""
|
||||
print(' '.join(w.capitalize() for w in sys.argv[2:]))
|
||||
|
||||
|
||||
def efrocache_update() -> None:
|
||||
"""Build & push files to efrocache for public access."""
|
||||
from efrotools.efrocache import update_cache
|
||||
makefile_dirs = ['', 'assets']
|
||||
update_cache(makefile_dirs)
|
||||
|
||||
|
||||
def efrocache_get() -> None:
|
||||
"""Get a file from efrocache."""
|
||||
from efrotools.efrocache import get_target
|
||||
if len(sys.argv) != 3:
|
||||
raise RuntimeError('Expected exactly 1 arg')
|
||||
get_target(sys.argv[2])
|
||||
|
||||
|
||||
def get_modern_make() -> None:
|
||||
"""Print name of a modern make command."""
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
# Mac gnu make is outdated (due to newer versions using GPL3 I believe).
|
||||
# so let's return 'gmake' there which will point to homebrew make which
|
||||
# should be up to date.
|
||||
if platform.system() == 'Darwin':
|
||||
if subprocess.run(['which', 'gmake'], check=False,
|
||||
capture_output=True).returncode != 0:
|
||||
print(
|
||||
'WARNING: this requires gmake (mac system make is too old).'
|
||||
" Install it with 'brew install make'",
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
print('gmake')
|
||||
else:
|
||||
print('make')
|
||||
|
||||
|
||||
def warm_start_asset_build() -> None:
|
||||
"""Prep asset builds to run faster."""
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from efrotools import getconfig
|
||||
public: bool = getconfig(PROJROOT)['public']
|
||||
|
||||
if public:
|
||||
from efrotools.efrocache import warm_start_cache
|
||||
os.chdir(PROJROOT)
|
||||
warm_start_cache()
|
||||
else:
|
||||
# For internal builds we don't use efrocache but we do use an
|
||||
# internal build cache. Download an initial cache/etc. if need be.
|
||||
subprocess.run(
|
||||
[str(Path(PROJROOT, 'tools/convert_util')), '--init-asset-cache'],
|
||||
check=True)
|
||||
|
||||
|
||||
def update_docs_md() -> None:
|
||||
"""Updates docs markdown files if necessary."""
|
||||
import batools.build
|
||||
batools.build.update_docs_md(check='--check' in sys.argv)
|
||||
|
||||
|
||||
def list_pip_reqs() -> None:
|
||||
"""List Python Pip packages needed for this project."""
|
||||
from batools.build import get_pip_reqs
|
||||
print(' '.join(get_pip_reqs()))
|
||||
|
||||
|
||||
def install_pip_reqs() -> None:
|
||||
"""Install Python Pip packages needed for this project."""
|
||||
import subprocess
|
||||
from efrotools import PYTHON_BIN
|
||||
from efro.terminal import Clr
|
||||
from batools.build import get_pip_reqs
|
||||
subprocess.run([PYTHON_BIN, '-m', 'pip', 'install', '--upgrade'] +
|
||||
get_pip_reqs(),
|
||||
check=True)
|
||||
print(f'{Clr.GRN}All pip requirements installed!{Clr.RST}')
|
||||
|
||||
|
||||
def checkenv() -> None:
|
||||
"""Check for tools necessary to build and run the app."""
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
try:
|
||||
batools.build.checkenv()
|
||||
except RuntimeError as exc:
|
||||
raise CleanError(exc)
|
||||
|
||||
|
||||
def ensure_prefab_platform() -> None:
|
||||
"""Ensure we are running on a particular prefab platform."""
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) != 3:
|
||||
raise CleanError('Expected 1 platform name arg.')
|
||||
needed = sys.argv[2]
|
||||
current = batools.build.get_current_prefab_platform()
|
||||
if current != needed:
|
||||
raise CleanError(
|
||||
f'Incorrect platform: we are {current}, this requires {needed}.')
|
||||
|
||||
|
||||
def prefab_run_var() -> None:
|
||||
"""Print a var for running a prefab run for the current platform.
|
||||
|
||||
We use this mechanism instead of just having a command recursively run
|
||||
a make target so that ctrl-c can be handled cleanly and directly by the
|
||||
command getting run instead of generating extra errors in the recursive
|
||||
processes.
|
||||
"""
|
||||
import batools.build
|
||||
if len(sys.argv) != 3:
|
||||
raise RuntimeError('Expected 1 arg.')
|
||||
base = sys.argv[2].replace('-', '_').upper()
|
||||
platform = batools.build.get_current_prefab_platform().upper()
|
||||
print(f'RUN_PREFAB_{platform}_{base}', end='')
|
||||
|
||||
|
||||
def make_prefab() -> None:
|
||||
"""Run prefab builds for the current platform."""
|
||||
import subprocess
|
||||
import batools.build
|
||||
if len(sys.argv) != 3:
|
||||
raise RuntimeError('Expected one argument')
|
||||
target = batools.build.PrefabTarget(sys.argv[2])
|
||||
platform = batools.build.get_current_prefab_platform()
|
||||
try:
|
||||
subprocess.run(['make', f'prefab-{platform}-{target.value}-build'],
|
||||
check=True)
|
||||
except (Exception, KeyboardInterrupt) as exc:
|
||||
if str(exc):
|
||||
print(f'make_prefab failed with error: {exc}')
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def update_makebob() -> None:
|
||||
"""Build fresh make_bob binaries for all relevant platforms."""
|
||||
import batools.build
|
||||
batools.build.update_makebob()
|
||||
|
||||
|
||||
def lazybuild() -> None:
|
||||
"""Run a build command only if an input has changed."""
|
||||
import subprocess
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) < 5:
|
||||
raise CleanError('Expected at least 3 args')
|
||||
try:
|
||||
category = batools.build.SourceCategory(sys.argv[2])
|
||||
except ValueError as exc:
|
||||
raise CleanError(exc)
|
||||
target = sys.argv[3]
|
||||
command = ' '.join(sys.argv[4:])
|
||||
try:
|
||||
batools.build.lazybuild(target, category, command)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
raise CleanError(exc)
|
||||
|
||||
|
||||
def filter_server_config() -> None:
|
||||
"""Add commented-out config options to a server config."""
|
||||
import batools.build
|
||||
from efro.error import CleanError
|
||||
if len(sys.argv) != 4:
|
||||
raise CleanError('Expected 2 args (infile and outfile).')
|
||||
batools.build.filter_server_config(str(PROJROOT), sys.argv[2], sys.argv[3])
|
||||
|
||||
|
||||
def printcolors() -> None:
|
||||
"""Print all colors available in efro.terminals.TerminalColor."""
|
||||
from efro.error import CleanError
|
||||
from efro.terminal import TerminalColor, Clr
|
||||
|
||||
if Clr.RED == '':
|
||||
raise CleanError('Efro color terminal output is disabled.')
|
||||
|
||||
clrnames = {getattr(Clr, s): s for s in dir(Clr) if s.isupper()}
|
||||
|
||||
# Print everything in Clr (since that's what users should be using
|
||||
# but do it in the order of TerminalColor (since Clr is just a class
|
||||
# so is unordered)
|
||||
for value in TerminalColor:
|
||||
if value is TerminalColor.RESET:
|
||||
continue
|
||||
shortname = f'Clr.{clrnames[value.value]}'
|
||||
longname = f'({value.name})'
|
||||
print(f'{shortname:<12} {longname:<20} {value.value}'
|
||||
f'The quick brown fox jumps over the lazy dog.'
|
||||
f'{TerminalColor.RESET.value}')
|
||||
|
||||
|
||||
def lazy_increment_build() -> None:
|
||||
"""Increment build number only if C++ sources have changed.
|
||||
|
||||
This is convenient to place in automatic commit/push scripts.
|
||||
It could make sense to auto update build number when scripts/assets
|
||||
change too, but a build number change requires rebuilding all binaries
|
||||
so I'll leave that as an explicit choice to save work.
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
from efro.terminal import Clr
|
||||
from efro.error import CleanError
|
||||
from efrotools import get_files_hash
|
||||
from efrotools.code import get_code_filenames
|
||||
if sys.argv[2:] not in [[], ['--update-hash-only']]:
|
||||
raise CleanError('Invalid arguments')
|
||||
update_hash_only = '--update-hash-only' in sys.argv
|
||||
codefiles = get_code_filenames(PROJROOT)
|
||||
codehash = get_files_hash(codefiles)
|
||||
hashfilename = '.cache/lazy_increment_build'
|
||||
try:
|
||||
with open(hashfilename) as infile:
|
||||
lasthash = infile.read()
|
||||
except FileNotFoundError:
|
||||
lasthash = ''
|
||||
if codehash != lasthash:
|
||||
print(f'{Clr.SMAG}Source(s) changed; incrementing build...{Clr.RST}')
|
||||
|
||||
if not update_hash_only:
|
||||
# Just go ahead and bless; this will increment the build as needed.
|
||||
# subprocess.run(['make', 'bless'], check=True)
|
||||
subprocess.run(['tools/version_utils', 'incrementbuild'],
|
||||
check=True)
|
||||
|
||||
# We probably just changed code, so we need to re-calc the hash.
|
||||
codehash = get_files_hash(codefiles)
|
||||
os.makedirs(os.path.dirname(hashfilename), exist_ok=True)
|
||||
with open(hashfilename, 'w') as outfile:
|
||||
outfile.write(codehash)
|
||||
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
snippets_main(globals())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user