• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kivy / python-for-android / 3770697291

pending completion
3770697291

push

github

GitHub
Merge pull request #2718 from kivy/release-2022.12.20

877 of 2011 branches covered (43.61%)

Branch coverage included in aggregate %.

38 of 86 new or added lines in 16 files covered. (44.19%)

10 existing lines in 4 files now uncovered.

4515 of 6886 relevant lines covered (65.57%)

2.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pythonforandroid/bdistapk.py
1
from setuptools import Command
×
2

3
import sys
×
4
from os.path import realpath, join, exists, dirname, curdir, basename, split
×
5
from os import makedirs
×
6
from glob import glob
×
7
from shutil import rmtree, copyfile
×
8

9

10
def argv_contains(t):
×
11
    for arg in sys.argv:
×
12
        if arg.startswith(t):
×
13
            return True
×
14
    return False
×
15

16

17
class Bdist(Command):
×
18

19
    user_options = []
×
20
    package_type = None
×
21

22
    def initialize_options(self):
×
23
        for option in self.user_options:
×
24
            setattr(self, option[0].strip('=').replace('-', '_'), None)
×
25

26
        option_dict = self.distribution.get_option_dict(self.package_type)
×
27

28
        # This is a hack, we probably aren't supposed to loop through
29
        # the option_dict so early because distutils does exactly the
30
        # same thing later to check that we support the
31
        # options. However, it works...
32
        for (option, (source, value)) in option_dict.items():
×
33
            setattr(self, option, str(value))
×
34

35
    def finalize_options(self):
×
36

37
        setup_options = self.distribution.get_option_dict(self.package_type)
×
38
        for (option, (source, value)) in setup_options.items():
×
39
            if source == 'command line':
×
40
                continue
×
41
            if not argv_contains('--' + option):
×
42
                # allow 'permissions': ['permission', 'permission] in apk
43
                if option == 'permissions':
×
44
                    for perm in value:
×
45
                        sys.argv.append('--permission={}'.format(perm))
×
46
                elif value in (None, 'None'):
×
47
                    sys.argv.append('--{}'.format(option))
×
48
                else:
49
                    sys.argv.append('--{}={}'.format(option, value))
×
50

51
        # Inject some argv options from setup.py if the user did not
52
        # provide them
53
        if not argv_contains('--name'):
×
54
            name = self.distribution.get_name()
×
55
            sys.argv.append('--name="{}"'.format(name))
×
56
            self.name = name
×
57

58
        if not argv_contains('--package'):
×
59
            package = 'org.test.{}'.format(self.name.lower().replace(' ', ''))
×
60
            print('WARNING: You did not supply an Android package '
×
61
                  'identifier, trying {} instead.'.format(package))
62
            print('         This may fail if this is not a valid identifier')
×
63
            sys.argv.append('--package={}'.format(package))
×
64

65
        if not argv_contains('--version'):
×
66
            version = self.distribution.get_version()
×
67
            sys.argv.append('--version={}'.format(version))
×
68

69
        if not argv_contains('--arch'):
×
70
            arch = 'armeabi-v7a'
×
71
            self.arch = arch
×
72
            sys.argv.append('--arch={}'.format(arch))
×
73

74
    def run(self):
×
75
        self.prepare_build_dir()
×
76

77
        from pythonforandroid.entrypoints import main
×
78
        sys.argv[1] = self.package_type
×
79
        main()
×
80

81
    def prepare_build_dir(self):
×
82

83
        if argv_contains('--private') and not argv_contains('--launcher'):
×
84
            print('WARNING: Received --private argument when this would '
×
85
                  'normally be generated automatically.')
86
            print('         This is probably bad unless you meant to do '
×
87
                  'that.')
88

89
        bdist_dir = 'build/bdist.android-{}'.format(self.arch)
×
90
        if exists(bdist_dir):
×
91
            rmtree(bdist_dir)
×
92
        makedirs(bdist_dir)
×
93

94
        globs = []
×
95
        for directory, patterns in self.distribution.package_data.items():
×
96
            for pattern in patterns:
×
97
                globs.append(join(directory, pattern))
×
98

99
        filens = []
×
100
        for pattern in globs:
×
101
            filens.extend(glob(pattern))
×
102

103
        main_py_dirs = []
×
104
        if not argv_contains('--launcher'):
×
105
            for filen in filens:
×
106
                new_dir = join(bdist_dir, dirname(filen))
×
107
                if not exists(new_dir):
×
108
                    makedirs(new_dir)
×
109
                print('Including {}'.format(filen))
×
110
                copyfile(filen, join(bdist_dir, filen))
×
NEW
111
                if basename(filen) in ('main.py', 'main.pyc'):
×
112
                    main_py_dirs.append(filen)
×
113

114
        # This feels ridiculous, but how else to define the main.py dir?
115
        # Maybe should just fail?
116
        if not main_py_dirs and not argv_contains('--launcher'):
×
117
            print('ERROR: Could not find main.py, so no app build dir defined')
×
118
            print('You should name your app entry point main.py')
×
119
            exit(1)
×
120
        if len(main_py_dirs) > 1:
×
121
            print('WARNING: Multiple main.py dirs found, using the shortest path')
×
122
        main_py_dirs = sorted(main_py_dirs, key=lambda j: len(split(j)))
×
123

124
        if not argv_contains('--launcher'):
×
125
            sys.argv.append('--private={}'.format(
×
126
                join(realpath(curdir), bdist_dir, dirname(main_py_dirs[0])))
127
            )
128

129

130
class BdistAPK(Bdist):
×
131
    """distutil command handler for 'apk'."""
132
    description = 'Create an APK with python-for-android'
×
133
    package_type = 'apk'
×
134

135

136
class BdistAAR(Bdist):
×
137
    """distutil command handler for 'aar'."""
138
    description = 'Create an AAR with python-for-android'
×
139
    package_type = 'aar'
×
140

141

142
class BdistAAB(Bdist):
×
143
    """distutil command handler for 'aab'."""
144
    description = 'Create an AAB with python-for-android'
×
145
    package_type = 'aab'
×
146

147

148
def _set_user_options():
×
149
    # This seems like a silly way to do things, but not sure if there's a
150
    # better way to pass arbitrary options onwards to p4a
151
    user_options = [('requirements=', None, None), ]
×
152
    for i, arg in enumerate(sys.argv):
×
153
        if arg.startswith('--'):
×
154
            if ('=' in arg or
×
155
                    (i < (len(sys.argv) - 1) and not sys.argv[i+1].startswith('-'))):
156
                user_options.append((arg[2:].split('=')[0] + '=', None, None))
×
157
            else:
158
                user_options.append((arg[2:], None, None))
×
159

160
    BdistAPK.user_options = user_options
×
161
    BdistAAB.user_options = user_options
×
162
    BdistAAR.user_options = user_options
×
163

164

165
_set_user_options()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc