mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-04 14:33:28 +08:00
latest bacloud work
This commit is contained in:
parent
9228d5fd82
commit
4255a2d048
@ -49,8 +49,6 @@ TOOL_NAME = 'bacloud'
|
|||||||
MASTER_SERVER_ADDRESS = ('http://localhost:23524'
|
MASTER_SERVER_ADDRESS = ('http://localhost:23524'
|
||||||
if os.environ.get('BACLOUD_LOCAL') == '1' else
|
if os.environ.get('BACLOUD_LOCAL') == '1' else
|
||||||
'https://bamaster.appspot.com')
|
'https://bamaster.appspot.com')
|
||||||
STATE_DIR = Path('.cache/bacloud')
|
|
||||||
STATE_DATA_PATH = Path(STATE_DIR, 'state')
|
|
||||||
|
|
||||||
CLRHDR = '\033[95m' # Header.
|
CLRHDR = '\033[95m' # Header.
|
||||||
CLRGRN = '\033[92m' # Green.
|
CLRGRN = '\033[92m' # Green.
|
||||||
@ -109,7 +107,7 @@ def get_tz_offset_seconds() -> float:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class File:
|
class PackageFile:
|
||||||
"""Represents a single file within a Package."""
|
"""Represents a single file within a Package."""
|
||||||
filehash: str
|
filehash: str
|
||||||
filesize: int
|
filesize: int
|
||||||
@ -120,7 +118,7 @@ class Package:
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.path = Path('')
|
self.path = Path('')
|
||||||
self.files: Dict[str, File] = {}
|
self.files: Dict[str, PackageFile] = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_from_disk(cls, path: Path) -> Package:
|
def load_from_disk(cls, path: Path) -> Package:
|
||||||
@ -143,7 +141,7 @@ class Package:
|
|||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from multiprocessing import cpu_count
|
from multiprocessing import cpu_count
|
||||||
|
|
||||||
def _get_file_info(filepath: str) -> Tuple[str, File]:
|
def _get_file_info(filepath: str) -> Tuple[str, PackageFile]:
|
||||||
sha = hashlib.sha256()
|
sha = hashlib.sha256()
|
||||||
fullfilepath = os.path.join(packagepathstr, filepath)
|
fullfilepath = os.path.join(packagepathstr, filepath)
|
||||||
if not os.path.isfile(fullfilepath):
|
if not os.path.isfile(fullfilepath):
|
||||||
@ -152,8 +150,8 @@ class Package:
|
|||||||
filebytes = infile.read()
|
filebytes = infile.read()
|
||||||
filesize = len(filebytes)
|
filesize = len(filebytes)
|
||||||
sha.update(filebytes)
|
sha.update(filebytes)
|
||||||
return (filepath, File(filehash=sha.hexdigest(),
|
return (filepath,
|
||||||
filesize=filesize))
|
PackageFile(filehash=sha.hexdigest(), filesize=filesize))
|
||||||
|
|
||||||
# Now use all procs to hash the files efficiently.
|
# Now use all procs to hash the files efficiently.
|
||||||
with ThreadPoolExecutor(max_workers=cpu_count()) as executor:
|
with ThreadPoolExecutor(max_workers=cpu_count()) as executor:
|
||||||
@ -168,49 +166,60 @@ class App:
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._state = StateData()
|
self._state = StateData()
|
||||||
self._package: Optional[Package] = None
|
self._package: Optional[Package] = None
|
||||||
|
self._project_root: Optional[Path] = None
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Run the tool."""
|
"""Run the tool."""
|
||||||
|
|
||||||
# Make reasonably sure we're being run from project root.
|
# Make sure we can locate the project bacloud is being run from.
|
||||||
if not os.path.exists(f'tools/{TOOL_NAME}'):
|
self._project_root = Path(sys.argv[0]).parents[1]
|
||||||
raise CleanError(
|
if not all(
|
||||||
'This tool must be run from ballistica project root.')
|
Path(self._project_root, name).is_dir()
|
||||||
|
for name in ('tools', 'config', 'tests')):
|
||||||
|
raise CleanError('Unable to locate project directory.')
|
||||||
|
|
||||||
# Also run project prereqs checks so we can hopefully inform the user
|
# Also run project prereqs checks so we can hopefully inform the user
|
||||||
# of missing python modules/etc. instead of just failing cryptically.
|
# of missing python modules/etc. instead of just failing cryptically.
|
||||||
try:
|
try:
|
||||||
subprocess.run(['make', '--quiet', 'prereqs'], check=True)
|
subprocess.run(['make', '--quiet', 'prereqs'],
|
||||||
|
check=True,
|
||||||
|
cwd=self._project_root)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise CleanError('"make prereqs" check failed. '
|
raise CleanError('"make prereqs" check failed. '
|
||||||
'Install missing requirements and try again.')
|
'Install missing requirements and try again.')
|
||||||
|
|
||||||
self._load_state()
|
self._load_state()
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
|
||||||
print(f'{CLRRED}You must provide one or more arguments.{CLREND}')
|
|
||||||
self.run_command(['help'])
|
|
||||||
raise CleanError()
|
|
||||||
|
|
||||||
# Simply pass all args to the server and let it do the thing.
|
# Simply pass all args to the server and let it do the thing.
|
||||||
self.run_command(sys.argv[1:])
|
self.run_user_command(sys.argv[1:])
|
||||||
|
|
||||||
self._save_state()
|
self._save_state()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _state_dir(self) -> Path:
|
||||||
|
"""The full path to the state dir."""
|
||||||
|
assert self._project_root is not None
|
||||||
|
return Path(self._project_root, '.cache/bacloud')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _state_data_path(self) -> Path:
|
||||||
|
"""The full path to the state data file."""
|
||||||
|
return Path(self._state_dir, 'state')
|
||||||
|
|
||||||
def _load_state(self) -> None:
|
def _load_state(self) -> None:
|
||||||
if not os.path.exists(STATE_DATA_PATH):
|
if not os.path.exists(self._state_data_path):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
with open(STATE_DATA_PATH, 'r') as infile:
|
with open(self._state_data_path, 'r') as infile:
|
||||||
self._state = StateData(**json.loads(infile.read()))
|
self._state = StateData(**json.loads(infile.read()))
|
||||||
except Exception:
|
except Exception:
|
||||||
print(f'{CLRRED}Error loading {TOOL_NAME} data;'
|
print(f'{CLRRED}Error loading {TOOL_NAME} data;'
|
||||||
f' resetting to defaults.{CLREND}')
|
f' resetting to defaults.{CLREND}')
|
||||||
|
|
||||||
def _save_state(self) -> None:
|
def _save_state(self) -> None:
|
||||||
if not STATE_DIR.exists():
|
if not self._state_dir.exists():
|
||||||
STATE_DIR.mkdir(parents=True, exist_ok=True)
|
self._state_dir.mkdir(parents=True, exist_ok=True)
|
||||||
with open(STATE_DATA_PATH, 'w') as outfile:
|
with open(self._state_data_path, 'w') as outfile:
|
||||||
outfile.write(json.dumps(self._state.__dict__))
|
outfile.write(json.dumps(self._state.__dict__))
|
||||||
|
|
||||||
def _servercmd(self,
|
def _servercmd(self,
|
||||||
@ -242,12 +251,12 @@ class App:
|
|||||||
|
|
||||||
# Handle common responses (can move these out of here at some point)
|
# Handle common responses (can move these out of here at some point)
|
||||||
|
|
||||||
if response.error is not None:
|
|
||||||
raise CleanError(response.error)
|
|
||||||
|
|
||||||
if response.message is not None:
|
if response.message is not None:
|
||||||
print(response.message)
|
print(response.message)
|
||||||
|
|
||||||
|
if response.error is not None:
|
||||||
|
raise CleanError(response.error)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def _upload_file(self, filename: str, call: str, args: Dict) -> None:
|
def _upload_file(self, filename: str, call: str, args: Dict) -> None:
|
||||||
@ -319,16 +328,15 @@ class App:
|
|||||||
# Lastly, run the 'upload complete' command we were passed.
|
# Lastly, run the 'upload complete' command we were passed.
|
||||||
return completecmd, completeargs
|
return completecmd, completeargs
|
||||||
|
|
||||||
def run_command(self, args: List[str]) -> None:
|
def run_user_command(self, args: List[str]) -> None:
|
||||||
"""Run a command to completion."""
|
"""Run a single user command to completion."""
|
||||||
|
|
||||||
nextcall: Optional[Tuple[str, Dict]] = ('toplevel', {'a': args})
|
nextcall: Optional[Tuple[str, Dict]] = ('user', {'a': args})
|
||||||
|
|
||||||
# Now talk to the server in a loop until they are done with us.
|
# Now talk to the server in a loop until there's nothing left to do.
|
||||||
while nextcall is not None:
|
while nextcall is not None:
|
||||||
response = self._servercmd(*nextcall)
|
response = self._servercmd(*nextcall)
|
||||||
nextcall = None
|
nextcall = None
|
||||||
|
|
||||||
if response.loadpackage is not None:
|
if response.loadpackage is not None:
|
||||||
nextcall = self._handle_loadpackage_response(response)
|
nextcall = self._handle_loadpackage_response(response)
|
||||||
if response.upload is not None:
|
if response.upload is not None:
|
||||||
|
|||||||
@ -33,12 +33,6 @@ if TYPE_CHECKING:
|
|||||||
# Overall version we're using for the game currently.
|
# Overall version we're using for the game currently.
|
||||||
PYTHON_VERSION_MAJOR = "3.7"
|
PYTHON_VERSION_MAJOR = "3.7"
|
||||||
|
|
||||||
# Specific version we're using on apple builds.
|
|
||||||
# PYTHON_VERSION_APPLE = "3.7.0"
|
|
||||||
|
|
||||||
# Specific version we're using on android builds.
|
|
||||||
# PYTHON_VERSION_ANDROID = "3.7.2"
|
|
||||||
|
|
||||||
ENABLE_OPENSSL = True
|
ENABLE_OPENSSL = True
|
||||||
|
|
||||||
|
|
||||||
@ -51,7 +45,10 @@ def build_apple(arch: str, debug: bool = False) -> None:
|
|||||||
'git@github.com:pybee/Python-Apple-support.git "' +
|
'git@github.com:pybee/Python-Apple-support.git "' +
|
||||||
builddir + '"')
|
builddir + '"')
|
||||||
os.chdir(builddir)
|
os.chdir(builddir)
|
||||||
efrotools.run('git checkout 3.7')
|
|
||||||
|
# TEMP: Check out a particular commit while the branch head is broken.
|
||||||
|
# efrotools.run('git checkout 1a9c71dca298c03517e8236b81cf1d9c8c521cbf')
|
||||||
|
efrotools.run(f'git checkout {PYTHON_VERSION_MAJOR}')
|
||||||
|
|
||||||
# On mac we currently have to add the _scproxy module or urllib will
|
# On mac we currently have to add the _scproxy module or urllib will
|
||||||
# fail.
|
# fail.
|
||||||
@ -137,9 +134,6 @@ def build_apple(arch: str, debug: bool = False) -> None:
|
|||||||
txt = efrotools.replace_one(
|
txt = efrotools.replace_one(
|
||||||
txt, '&& PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) .',
|
txt, '&& PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) .',
|
||||||
'&& PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" .')
|
'&& PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" .')
|
||||||
# txt = efrotools.replace_one(
|
|
||||||
# txt, '&& PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) m',
|
|
||||||
# '&& PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" m')
|
|
||||||
|
|
||||||
# Remove makefile dependencies so we don't build the
|
# Remove makefile dependencies so we don't build the
|
||||||
# libs we're not using.
|
# libs we're not using.
|
||||||
@ -304,7 +298,8 @@ def build_android(rootdir: str, arch: str, debug: bool = False) -> None:
|
|||||||
|
|
||||||
# Set this to a particular cpython commit to target exact releases from git
|
# Set this to a particular cpython commit to target exact releases from git
|
||||||
# commit = 'e09359112e250268eca209355abeb17abf822486' # 3.7.4 release
|
# commit = 'e09359112e250268eca209355abeb17abf822486' # 3.7.4 release
|
||||||
commit = '5c02a39a0b31a330e06b4d6f44835afb205dc7cc' # 3.7.5 release
|
# commit = '5c02a39a0b31a330e06b4d6f44835afb205dc7cc' # 3.7.5 release
|
||||||
|
commit = '43364a7ae01fbe4288ef42622259a0038ce1edcc' # 3.7.6 release
|
||||||
|
|
||||||
if commit is not None:
|
if commit is not None:
|
||||||
ftxt = efrotools.readfile('pybuild/source.py')
|
ftxt = efrotools.readfile('pybuild/source.py')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user