lbry-android-sdk/p4a/pythonforandroid/util.py

107 lines
3.5 KiB
Python
Raw Permalink Normal View History

2022-11-29 21:35:24 +01:00
import contextlib
from os.path import exists, join
from os import getcwd, chdir, makedirs, walk, uname
import shutil
from fnmatch import fnmatch
from tempfile import mkdtemp
from pythonforandroid.logger import (logger, Err_Fore, error, info)
build_platform = '{system}-{machine}'.format(
system=uname()[0], machine=uname()[-1]).lower()
"""the build platform in the format `system-machine`. We use
this string to define the right build system when compiling some recipes or
to get the right path for clang compiler"""
@contextlib.contextmanager
def current_directory(new_dir):
cur_dir = getcwd()
logger.info(''.join((Err_Fore.CYAN, '-> directory context ', new_dir,
Err_Fore.RESET)))
chdir(new_dir)
yield
logger.info(''.join((Err_Fore.CYAN, '<- directory context ', cur_dir,
Err_Fore.RESET)))
chdir(cur_dir)
@contextlib.contextmanager
def temp_directory():
temp_dir = mkdtemp()
try:
logger.debug(''.join((Err_Fore.CYAN, ' + temp directory used ',
temp_dir, Err_Fore.RESET)))
yield temp_dir
finally:
shutil.rmtree(temp_dir)
logger.debug(''.join((Err_Fore.CYAN, ' - temp directory deleted ',
temp_dir, Err_Fore.RESET)))
def ensure_dir(filename):
if not exists(filename):
makedirs(filename)
def walk_valid_filens(base_dir, invalid_dir_names, invalid_file_patterns):
"""Recursively walks all the files and directories in ``dirn``,
ignoring directories that match any pattern in ``invalid_dirns``
and files that patch any pattern in ``invalid_filens``.
``invalid_dirns`` and ``invalid_filens`` should both be lists of
strings to match. ``invalid_dir_patterns`` expects a list of
invalid directory names, while ``invalid_file_patterns`` expects a
list of glob patterns compared against the full filepath.
File and directory paths are evaluated as full paths relative to ``dirn``.
"""
for dirn, subdirs, filens in walk(base_dir):
# Remove invalid subdirs so that they will not be walked
for i in reversed(range(len(subdirs))):
subdir = subdirs[i]
if subdir in invalid_dir_names:
subdirs.pop(i)
for filen in filens:
for pattern in invalid_file_patterns:
if fnmatch(filen, pattern):
break
else:
yield join(dirn, filen)
def load_source(module, filename):
# Python 3.5+
import importlib.util
if hasattr(importlib.util, 'module_from_spec'):
spec = importlib.util.spec_from_file_location(module, filename)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
else:
# Python 3.3 and 3.4:
from importlib.machinery import SourceFileLoader
return SourceFileLoader(module, filename).load_module()
class BuildInterruptingException(Exception):
def __init__(self, message, instructions=None):
super().__init__(message, instructions)
self.message = message
self.instructions = instructions
def handle_build_exception(exception):
"""
Handles a raised BuildInterruptingException by printing its error
message and associated instructions, if any, then exiting.
"""
error('Build failed: {}'.format(exception.message))
if exception.instructions is not None:
info('Instructions: {}'.format(exception.instructions))
exit(1)