Skip to content

Commit ccb225a

Browse files
committed
Replaced many exit(1)s with exceptions
1 parent acaa004 commit ccb225a

File tree

9 files changed

+101
-91
lines changed

9 files changed

+101
-91
lines changed

pythonforandroid/archs.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import sys
44
from distutils.spawn import find_executable
55

6-
from pythonforandroid.logger import warning
76
from pythonforandroid.recipe import Recipe
7+
from pythonforandroid.util import BuildInterruptingException
88

99

1010
class Arch(object):
@@ -86,11 +86,11 @@ def get_env(self, with_flags_in_cc=True):
8686
command_prefix=command_prefix), path=environ['PATH'])
8787
if cc is None:
8888
print('Searching path are: {!r}'.format(environ['PATH']))
89-
warning('Couldn\'t find executable for CC. This indicates a '
90-
'problem locating the {} executable in the Android '
91-
'NDK, not that you don\'t have a normal compiler '
92-
'installed. Exiting.')
93-
exit(1)
89+
raise BuildInterruptingException(
90+
'Couldn\'t find executable for CC. This indicates a '
91+
'problem locating the {} executable in the Android '
92+
'NDK, not that you don\'t have a normal compiler '
93+
'installed. Exiting.')
9494

9595
if with_flags_in_cc:
9696
env['CC'] = '{ccache}{command_prefix}-gcc {cflags}'.format(

pythonforandroid/bdistapk.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ def finalize_options(self):
7373
sys.argv.append('--arch={}'.format(arch))
7474

7575
def run(self):
76-
7776
self.prepare_build_dir()
7877

7978
from pythonforandroid.toolchain import main

pythonforandroid/build.py

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
import re
1010
import sh
1111

12-
from pythonforandroid.util import (ensure_dir, current_directory)
13-
from pythonforandroid.logger import (info, warning, error, info_notify,
14-
Err_Fore, info_main, shprint)
12+
from pythonforandroid.util import (ensure_dir, current_directory, BuildInterruptingException)
13+
from pythonforandroid.logger import (info, warning, info_notify, info_main, shprint)
1514
from pythonforandroid.archs import ArchARM, ArchARMv7_a, ArchAarch_64, Archx86
1615
from pythonforandroid.recipe import Recipe
1716

@@ -223,8 +222,7 @@ def prepare_build_environment(self,
223222
'maintain your own SDK download.')
224223
sdk_dir = possible_dirs[0]
225224
if sdk_dir is None:
226-
warning('Android SDK dir was not specified, exiting.')
227-
exit(1)
225+
raise BuildInterruptingException('Android SDK dir was not specified, exiting.')
228226
self.sdk_dir = realpath(sdk_dir)
229227

230228
# Check what Android API we're using
@@ -243,11 +241,11 @@ def prepare_build_environment(self,
243241
self.android_api = android_api
244242

245243
if self.android_api >= 21 and self.archs[0].arch == 'armeabi':
246-
error('Asked to build for armeabi architecture with API '
247-
'{}, but API 21 or greater does not support armeabi'.format(
248-
self.android_api))
249-
error('You probably want to build with --arch=armeabi-v7a instead')
250-
exit(1)
244+
raise BuildInterruptingException(
245+
'Asked to build for armeabi architecture with API '
246+
'{}, but API 21 or greater does not support armeabi'.format(
247+
self.android_api),
248+
instructions='You probably want to build with --arch=armeabi-v7a instead')
251249

252250
if exists(join(sdk_dir, 'tools', 'bin', 'avdmanager')):
253251
avdmanager = sh.Command(join(sdk_dir, 'tools', 'bin', 'avdmanager'))
@@ -256,9 +254,9 @@ def prepare_build_environment(self,
256254
android = sh.Command(join(sdk_dir, 'tools', 'android'))
257255
targets = android('list').stdout.decode('utf-8').split('\n')
258256
else:
259-
error('Could not find `android` or `sdkmanager` binaries in '
260-
'Android SDK. Exiting.')
261-
exit(1)
257+
raise BuildInterruptingException(
258+
'Could not find `android` or `sdkmanager` binaries in Android SDK',
259+
instructions='Make sure the path to the Android SDK is correct')
262260
apis = [s for s in targets if re.match(r'^ *API level: ', s)]
263261
apis = [re.findall(r'[0-9]+', s) for s in apis]
264262
apis = [int(s[0]) for s in apis if s]
@@ -268,10 +266,9 @@ def prepare_build_environment(self,
268266
info(('Requested API target {} is available, '
269267
'continuing.').format(android_api))
270268
else:
271-
warning(('Requested API target {} is not available, install '
272-
'it with the SDK android tool.').format(android_api))
273-
warning('Exiting.')
274-
exit(1)
269+
raise BuildInterruptingException(
270+
('Requested API target {} is not available, install '
271+
'it with the SDK android tool.').format(android_api))
275272

276273
# Find the Android NDK
277274
# Could also use ANDROID_NDK, but doesn't look like many tools use this
@@ -304,8 +301,7 @@ def prepare_build_environment(self,
304301
'maintain your own NDK download.')
305302
ndk_dir = possible_dirs[0]
306303
if ndk_dir is None:
307-
warning('Android NDK dir was not specified, exiting.')
308-
exit(1)
304+
raise BuildInterruptingException('Android NDK dir was not specified')
309305
self.ndk_dir = realpath(ndk_dir)
310306

311307
# Find the NDK version, and check it against what the NDK dir
@@ -366,11 +362,11 @@ def prepare_build_environment(self,
366362
self.ndk_api = ndk_api
367363

368364
if self.ndk_api > self.android_api:
369-
error('Target NDK API is {}, higher than the target Android API {}.'.format(
370-
self.ndk_api, self.android_api))
371-
error('The NDK API is a minimum supported API number and must be lower '
372-
'than the target Android API')
373-
exit(1)
365+
raise BuildInterruptingException(
366+
'Target NDK API is {}, higher than the target Android API {}.'.format(
367+
self.ndk_api, self.android_api),
368+
instructions=('The NDK API is a minimum supported API number and must be lower '
369+
'than the target Android API'))
374370

375371
info('Using {} NDK {}'.format(self.ndk.capitalize(), self.ndk_ver))
376372

@@ -398,8 +394,7 @@ def prepare_build_environment(self,
398394
self.cython = cython
399395
break
400396
else:
401-
error('No cython binary found. Exiting.')
402-
exit(1)
397+
raise BuildInterruptingException('No cython binary found.')
403398
if not self.cython:
404399
ok = False
405400
warning("Missing requirement: cython is not installed")
@@ -473,9 +468,8 @@ def prepare_build_environment(self,
473468
executable))
474469

475470
if not ok:
476-
error('{}python-for-android cannot continue; aborting{}'.format(
477-
Err_Fore.RED, Err_Fore.RESET))
478-
sys.exit(1)
471+
raise BuildInterruptingException(
472+
'python-for-android cannot continue due to the missing executables above')
479473

480474
def __init__(self):
481475
super(Context, self).__init__()
@@ -522,8 +516,7 @@ def set_archs(self, arch_names):
522516
new_archs.add(match)
523517
self.archs = list(new_archs)
524518
if not self.archs:
525-
warning('Asked to compile for no Archs, so failing.')
526-
exit(1)
519+
raise BuildInterruptingException('Asked to compile for no Archs, so failing.')
527520
info('Will compile for the following archs: {}'.format(
528521
', '.join([arch.arch for arch in self.archs])))
529522

pythonforandroid/distribution.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
import glob
33
import json
44

5-
from pythonforandroid.logger import (info, info_notify, warning,
6-
Err_Style, Err_Fore, error)
7-
from pythonforandroid.util import current_directory
5+
from pythonforandroid.logger import (info, info_notify, Err_Style, Err_Fore)
6+
from pythonforandroid.util import current_directory, BuildInterruptingException
87

98

109
class Distribution(object):
@@ -124,17 +123,16 @@ def get_distribution(cls, ctx, name=None, recipes=[],
124123
# then the existing dist is incompatible with the requested
125124
# configuration and the build cannot continue
126125
if name_match_dist is not None:
127-
error('Asked for dist with name {name} with recipes ({req_recipes}) and '
128-
'NDK API {req_ndk_api}, but a dist '
129-
'with this name already exists and has either incompatible recipes '
130-
'({dist_recipes}) or NDK API {dist_ndk_api}'.format(
131-
name=name,
132-
req_ndk_api=ndk_api,
133-
dist_ndk_api=name_match_dist.ndk_api,
134-
req_recipes=', '.join(recipes),
135-
dist_recipes=', '.join(name_match_dist.recipes)))
136-
error('No compatible dist found, so exiting.')
137-
exit(1)
126+
raise BuildInterruptingException(
127+
'Asked for dist with name {name} with recipes ({req_recipes}) and '
128+
'NDK API {req_ndk_api}, but a dist '
129+
'with this name already exists and has either incompatible recipes '
130+
'({dist_recipes}) or NDK API {dist_ndk_api}'.format(
131+
name=name,
132+
req_ndk_api=ndk_api,
133+
dist_ndk_api=name_match_dist.ndk_api,
134+
req_recipes=', '.join(recipes),
135+
dist_recipes=', '.join(name_match_dist.recipes)))
138136

139137
# If we got this far, we need to build a new dist
140138
dist = Distribution(ctx)
@@ -158,9 +156,9 @@ def get_distribution(cls, ctx, name=None, recipes=[],
158156
def get_distributions(cls, ctx, extra_dist_dirs=[]):
159157
'''Returns all the distributions found locally.'''
160158
if extra_dist_dirs:
161-
warning('extra_dist_dirs argument to get_distributions '
162-
'is not yet implemented')
163-
exit(1)
159+
raise BuildInterruptingException(
160+
'extra_dist_dirs argument to get_distributions '
161+
'is not yet implemented')
164162
dist_dir = ctx.dist_dir
165163
folders = glob.glob(join(dist_dir, '*'))
166164
for dir in extra_dist_dirs:

pythonforandroid/graph.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from copy import deepcopy
22
from itertools import product
3-
from sys import exit
43

5-
from pythonforandroid.logger import (info, warning, error)
4+
from pythonforandroid.logger import (info, warning)
65
from pythonforandroid.recipe import Recipe
76
from pythonforandroid.bootstrap import Bootstrap
7+
from pythonforandroid.util import BuildInterruptingException
88

99

1010
class RecipeOrder(dict):
@@ -133,11 +133,10 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None):
133133
key=lambda order: -('python2' in order) - ('sdl2' in order))
134134

135135
if not orders:
136-
error('Didn\'t find any valid dependency graphs.')
137-
error('This means that some of your requirements pull in '
138-
'conflicting dependencies.')
139-
error('Exiting.')
140-
exit(1)
136+
raise BuildInterruptingException(
137+
'Didn\'t find any valid dependency graphs. This means that some of your '
138+
'requirements pull in conflicting dependencies.')
139+
141140
# It would be better to check against possible orders other
142141
# than the first one, but in practice clashes will be rare,
143142
# and can be resolved by specifying more parameters

pythonforandroid/recipe.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
from urlparse import urlparse
1717
except ImportError:
1818
from urllib.parse import urlparse
19-
from pythonforandroid.logger import (logger, info, warning, error, debug, shprint, info_main)
20-
from pythonforandroid.util import (urlretrieve, current_directory, ensure_dir)
19+
from pythonforandroid.logger import (logger, info, warning, debug, shprint, info_main)
20+
from pythonforandroid.util import (urlretrieve, current_directory, ensure_dir,
21+
BuildInterruptingException)
2122

2223
# this import is necessary to keep imp.load_source from complaining :)
2324
if PY2:
@@ -582,8 +583,8 @@ class IncludedFilesBehaviour(object):
582583

583584
def prepare_build_dir(self, arch):
584585
if self.src_filename is None:
585-
print('IncludedFilesBehaviour failed: no src_filename specified')
586-
exit(1)
586+
raise BuildInterruptingException(
587+
'IncludedFilesBehaviour failed: no src_filename specified')
587588
shprint(sh.rm, '-rf', self.get_build_dir(arch))
588589
shprint(sh.cp, '-a', join(self.get_recipe_dir(), self.src_filename),
589590
self.get_build_dir(arch))
@@ -1051,9 +1052,9 @@ def __init__(self, *args, **kwargs):
10511052
def prebuild_arch(self, arch):
10521053
super(TargetPythonRecipe, self).prebuild_arch(arch)
10531054
if self.from_crystax and self.ctx.ndk != 'crystax':
1054-
error('The {} recipe can only be built when '
1055-
'using the CrystaX NDK. Exiting.'.format(self.name))
1056-
exit(1)
1055+
raise BuildInterruptingException(
1056+
'The {} recipe can only be built when '
1057+
'using the CrystaX NDK. Exiting.'.format(self.name))
10571058
self.ctx.python_recipe = self
10581059

10591060
def include_root(self, arch):

pythonforandroid/recipes/python3/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from pythonforandroid.recipe import TargetPythonRecipe
22
from pythonforandroid.toolchain import shprint, current_directory
3-
from pythonforandroid.logger import logger, info, error
4-
from pythonforandroid.util import ensure_dir, walk_valid_filens
3+
from pythonforandroid.logger import logger, info
4+
from pythonforandroid.util import ensure_dir, walk_valid_filens, BuildInterruptingException
55
from os.path import exists, join, dirname
66
from os import environ
77
import glob
@@ -45,9 +45,9 @@ class Python3Recipe(TargetPythonRecipe):
4545

4646
def build_arch(self, arch):
4747
if self.ctx.ndk_api < self.MIN_NDK_API:
48-
error('Target ndk-api is {}, but the python3 recipe supports only {}+'.format(
49-
self.ctx.ndk_api, self.MIN_NDK_API))
50-
exit(1)
48+
raise BuildInterruptingException(
49+
'Target ndk-api is {}, but the python3 recipe supports only {}+'.format(
50+
self.ctx.ndk_api, self.MIN_NDK_API))
5151

5252
recipe_build_dir = self.get_build_dir(arch.arch)
5353

pythonforandroid/toolchain.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from __future__ import print_function
1010
from pythonforandroid import __version__
1111
from pythonforandroid.build import DEFAULT_NDK_API, DEFAULT_ANDROID_API
12+
from pythonforandroid.util import BuildInterruptingException, handle_build_exception
1213

1314

1415
def check_python_dependencies():
@@ -58,8 +59,7 @@ def check_python_dependencies():
5859
ok = False
5960

6061
if not ok:
61-
print('python-for-android is exiting due to the errors above.')
62-
exit(1)
62+
print('python-for-android is exiting due to the errors logged above')
6363

6464

6565
check_python_dependencies()
@@ -85,7 +85,7 @@ def check_python_dependencies():
8585
from pythonforandroid.recipe import Recipe
8686
from pythonforandroid.logger import (logger, info, warning, setup_color,
8787
Out_Style, Out_Fore,
88-
info_notify, info_main, shprint, error)
88+
info_notify, info_main, shprint)
8989
from pythonforandroid.util import current_directory
9090
from pythonforandroid.bootstrap import Bootstrap
9191
from pythonforandroid.distribution import Distribution, pretty_log_dists
@@ -628,7 +628,7 @@ def clean(self, args):
628628

629629
for component in components:
630630
if component not in component_clean_methods:
631-
raise ValueError((
631+
raise BuildInterruptingException((
632632
'Asked to clean "{}" but this argument is not '
633633
'recognised'.format(component)))
634634
component_clean_methods[component](args)
@@ -725,10 +725,10 @@ def export_dist(self, args):
725725
ctx = self.ctx
726726
dist = dist_from_args(ctx, args)
727727
if dist.needs_build:
728-
info('You asked to export a dist, but there is no dist '
729-
'with suitable recipes available. For now, you must '
730-
' create one first with the create argument.')
731-
exit(1)
728+
raise BuildInterruptingException(
729+
'You asked to export a dist, but there is no dist '
730+
'with suitable recipes available. For now, you must '
731+
' create one first with the create argument.')
732732
if args.symlink:
733733
shprint(sh.ln, '-s', dist.dist_dir, args.output_dir)
734734
else:
@@ -821,9 +821,8 @@ def apk(self, args):
821821
elif args.build_mode == "release":
822822
gradle_task = "assembleRelease"
823823
else:
824-
error("Unknown build mode {} for apk()".format(
825-
args.build_mode))
826-
exit(1)
824+
raise BuildInterruptingException(
825+
"Unknown build mode {} for apk()".format(args.build_mode))
827826
output = shprint(gradlew, gradle_task, _tail=20,
828827
_critical=True, _env=env)
829828

@@ -838,9 +837,9 @@ def apk(self, args):
838837
try:
839838
ant = sh.Command('ant')
840839
except sh.CommandNotFound:
841-
error('Could not find ant binary, please install it '
842-
'and make sure it is in your $PATH.')
843-
exit(1)
840+
raise BuildInterruptingException(
841+
'Could not find ant binary, please install it '
842+
'and make sure it is in your $PATH.')
844843
output = shprint(ant, args.build_mode, _tail=20,
845844
_critical=True, _env=env)
846845
apk_dir = join(dist.dist_dir, "bin")
@@ -874,7 +873,7 @@ def apk(self, args):
874873
apk_file = apks[-1]
875874
break
876875
else:
877-
raise ValueError('Couldn\'t find the built APK')
876+
raise BuildInterruptingException('Couldn\'t find the built APK')
878877

879878
info_main('# Found APK file: {}'.format(apk_file))
880879
if apk_add_version:
@@ -1007,7 +1006,10 @@ def build_status(self, _args):
10071006

10081007

10091008
def main():
1010-
ToolchainCL()
1009+
try:
1010+
ToolchainCL()
1011+
except BuildInterruptingException as exc:
1012+
handle_build_exception(exc)
10111013

10121014

10131015
if __name__ == "__main__":

0 commit comments

Comments
 (0)