latest bacloud work

This commit is contained in:
Eric Froemling 2020-01-14 12:24:32 -08:00
parent 9228d5fd82
commit 4255a2d048
2 changed files with 45 additions and 42 deletions

View File

@ -49,8 +49,6 @@ TOOL_NAME = 'bacloud'
MASTER_SERVER_ADDRESS = ('http://localhost:23524'
if os.environ.get('BACLOUD_LOCAL') == '1' else
'https://bamaster.appspot.com')
STATE_DIR = Path('.cache/bacloud')
STATE_DATA_PATH = Path(STATE_DIR, 'state')
CLRHDR = '\033[95m' # Header.
CLRGRN = '\033[92m' # Green.
@ -109,7 +107,7 @@ def get_tz_offset_seconds() -> float:
@dataclass
class File:
class PackageFile:
"""Represents a single file within a Package."""
filehash: str
filesize: int
@ -120,7 +118,7 @@ class Package:
def __init__(self) -> None:
self.path = Path('')
self.files: Dict[str, File] = {}
self.files: Dict[str, PackageFile] = {}
@classmethod
def load_from_disk(cls, path: Path) -> Package:
@ -143,7 +141,7 @@ class Package:
from concurrent.futures import ThreadPoolExecutor
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()
fullfilepath = os.path.join(packagepathstr, filepath)
if not os.path.isfile(fullfilepath):
@ -152,8 +150,8 @@ class Package:
filebytes = infile.read()
filesize = len(filebytes)
sha.update(filebytes)
return (filepath, File(filehash=sha.hexdigest(),
filesize=filesize))
return (filepath,
PackageFile(filehash=sha.hexdigest(), filesize=filesize))
# Now use all procs to hash the files efficiently.
with ThreadPoolExecutor(max_workers=cpu_count()) as executor:
@ -168,49 +166,60 @@ class App:
def __init__(self) -> None:
self._state = StateData()
self._package: Optional[Package] = None
self._project_root: Optional[Path] = None
def run(self) -> None:
"""Run the tool."""
# Make reasonably sure we're being run from project root.
if not os.path.exists(f'tools/{TOOL_NAME}'):
raise CleanError(
'This tool must be run from ballistica project root.')
# Make sure we can locate the project bacloud is being run from.
self._project_root = Path(sys.argv[0]).parents[1]
if not all(
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
# of missing python modules/etc. instead of just failing cryptically.
try:
subprocess.run(['make', '--quiet', 'prereqs'], check=True)
subprocess.run(['make', '--quiet', 'prereqs'],
check=True,
cwd=self._project_root)
except subprocess.CalledProcessError:
raise CleanError('"make prereqs" check failed. '
'Install missing requirements and try again.')
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.
self.run_command(sys.argv[1:])
self.run_user_command(sys.argv[1:])
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:
if not os.path.exists(STATE_DATA_PATH):
if not os.path.exists(self._state_data_path):
return
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()))
except Exception:
print(f'{CLRRED}Error loading {TOOL_NAME} data;'
f' resetting to defaults.{CLREND}')
def _save_state(self) -> None:
if not STATE_DIR.exists():
STATE_DIR.mkdir(parents=True, exist_ok=True)
with open(STATE_DATA_PATH, 'w') as outfile:
if not self._state_dir.exists():
self._state_dir.mkdir(parents=True, exist_ok=True)
with open(self._state_data_path, 'w') as outfile:
outfile.write(json.dumps(self._state.__dict__))
def _servercmd(self,
@ -242,12 +251,12 @@ class App:
# 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:
print(response.message)
if response.error is not None:
raise CleanError(response.error)
return response
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.
return completecmd, completeargs
def run_command(self, args: List[str]) -> None:
"""Run a command to completion."""
def run_user_command(self, args: List[str]) -> None:
"""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:
response = self._servercmd(*nextcall)
nextcall = None
if response.loadpackage is not None:
nextcall = self._handle_loadpackage_response(response)
if response.upload is not None:

View File

@ -33,12 +33,6 @@ if TYPE_CHECKING:
# Overall version we're using for the game currently.
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
@ -51,7 +45,10 @@ def build_apple(arch: str, debug: bool = False) -> None:
'git@github.com:pybee/Python-Apple-support.git "' +
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
# fail.
@ -137,9 +134,6 @@ def build_apple(arch: str, debug: bool = False) -> None:
txt = efrotools.replace_one(
txt, '&& 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
# 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
# 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:
ftxt = efrotools.readfile('pybuild/source.py')