Skip to content

Commit

Permalink
Factor out dependency checking. Use modern version handling (kivy#2866)
Browse files Browse the repository at this point in the history
LooseVersion used again


Handle bad SDK versions
  • Loading branch information
Julian-O authored Jul 30, 2023
1 parent 910df0a commit 7a0c935
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 83 deletions.
70 changes: 70 additions & 0 deletions pythonforandroid/checkdependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from importlib import import_module
from os import environ
import sys

from packaging.version import Version

from pythonforandroid.prerequisites import (
check_and_install_default_prerequisites,
)


def check_python_dependencies():
"""
Check if the Python requirements are installed. This must appears
before other imports because otherwise they're imported elsewhere.
Using the ok check instead of failing immediately so that all
errors are printed at once.
"""

ok = True

modules = [("colorama", "0.3.3"), "appdirs", ("sh", "1.10"), "jinja2"]

for module in modules:
if isinstance(module, tuple):
module, version = module
else:
version = None

try:
import_module(module)
except ImportError:
if version is None:
print(
"ERROR: The {} Python module could not be found, please "
"install it.".format(module)
)
ok = False
else:
print(
"ERROR: The {} Python module could not be found, "
"please install version {} or higher".format(
module, version
)
)
ok = False
else:
if version is None:
continue
try:
cur_ver = sys.modules[module].__version__
except AttributeError: # this is sometimes not available
continue
if Version(cur_ver) < Version(version):
print(
"ERROR: {} version is {}, but python-for-android needs "
"at least {}.".format(module, cur_ver, version)
)
ok = False

if not ok:
print("python-for-android is exiting due to the errors logged above")
exit(1)


def check():
if not environ.get("SKIP_PREREQUISITES_CHECK", "0") == "1":
check_and_install_default_prerequisites()
check_python_dependencies()
122 changes: 39 additions & 83 deletions pythonforandroid/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,96 +6,43 @@
This module defines the entry point for command line and programmatic use.
"""

from appdirs import user_data_dir
import argparse
from functools import wraps
import glob
import logging
import os
from os import environ
from pythonforandroid import __version__
from pythonforandroid.pythonpackage import get_dep_names_of_package
from pythonforandroid.recommendations import (
RECOMMENDED_NDK_API, RECOMMENDED_TARGET_API, print_recommendations)
from pythonforandroid.util import BuildInterruptingException, load_source
from pythonforandroid.entrypoints import main
from pythonforandroid.prerequisites import check_and_install_default_prerequisites


def check_python_dependencies():
# Check if the Python requirements are installed. This appears
# before the imports because otherwise they're imported elsewhere.

# Using the ok check instead of failing immediately so that all
# errors are printed at once

from distutils.version import LooseVersion
from importlib import import_module
import sys

ok = True

modules = [('colorama', '0.3.3'), 'appdirs', ('sh', '1.10'), 'jinja2']

for module in modules:
if isinstance(module, tuple):
module, version = module
else:
version = None

try:
import_module(module)
except ImportError:
if version is None:
print('ERROR: The {} Python module could not be found, please '
'install it.'.format(module))
ok = False
else:
print('ERROR: The {} Python module could not be found, '
'please install version {} or higher'.format(
module, version))
ok = False
else:
if version is None:
continue
try:
cur_ver = sys.modules[module].__version__
except AttributeError: # this is sometimes not available
continue
if LooseVersion(cur_ver) < LooseVersion(version):
print('ERROR: {} version is {}, but python-for-android needs '
'at least {}.'.format(module, cur_ver, version))
ok = False

if not ok:
print('python-for-android is exiting due to the errors logged above')
exit(1)


if not environ.get('SKIP_PREREQUISITES_CHECK', '0') == '1':
check_and_install_default_prerequisites()
check_python_dependencies()


import sys
from sys import platform
from os.path import (join, dirname, realpath, exists, expanduser, basename)
import os
import glob
import shutil
import re
import shlex
from functools import wraps
import shutil
import sys
from sys import platform

import argparse
# This must be imported and run before other third-party or p4a
# packages.
from pythonforandroid.checkdependencies import check
check()

from packaging.version import Version, InvalidVersion
import sh
from appdirs import user_data_dir
import logging
from distutils.version import LooseVersion

from pythonforandroid.recipe import Recipe
from pythonforandroid.logger import (logger, info, warning, setup_color,
Out_Style, Out_Fore,
info_notify, info_main, shprint)
from pythonforandroid.util import current_directory
from pythonforandroid import __version__
from pythonforandroid.bootstrap import Bootstrap
from pythonforandroid.build import Context, build_recipes
from pythonforandroid.distribution import Distribution, pretty_log_dists
from pythonforandroid.entrypoints import main
from pythonforandroid.graph import get_recipe_order_and_bootstrap
from pythonforandroid.build import Context, build_recipes
from pythonforandroid.logger import (logger, info, warning, setup_color,
Out_Style, Out_Fore,
info_notify, info_main, shprint)
from pythonforandroid.pythonpackage import get_dep_names_of_package
from pythonforandroid.recipe import Recipe
from pythonforandroid.recommendations import (
RECOMMENDED_NDK_API, RECOMMENDED_TARGET_API, print_recommendations)
from pythonforandroid.util import (
current_directory, BuildInterruptingException, load_source)

user_dir = dirname(realpath(os.path.curdir))
toolchain_dir = dirname(__file__)
Expand Down Expand Up @@ -1068,13 +1015,22 @@ def _build_package(self, args, package_type):
self.hook("before_apk_assemble")
build_tools_versions = os.listdir(join(ctx.sdk_dir,
'build-tools'))
build_tools_versions = sorted(build_tools_versions,
key=LooseVersion)

def sort_key(version_text):
try:
# Historically, Android build release candidates have had
# spaces in the version number.
return Version(version_text.replace(" ", ""))
except InvalidVersion:
# Put badly named versions at worst position.
return Version("0")

build_tools_versions.sort(key=sort_key)
build_tools_version = build_tools_versions[-1]
info(('Detected highest available build tools '
'version to be {}').format(build_tools_version))

if build_tools_version < '25.0':
if Version(build_tools_version.replace(" ", "")) < Version('25.0'):
raise BuildInterruptingException(
'build_tools >= 25 is required, but %s is installed' % build_tools_version)
if not exists("gradlew"):
Expand Down

0 comments on commit 7a0c935

Please sign in to comment.