|
2 | 2 | """ |
3 | 3 | Packaging implementation for PythonTurtle. |
4 | 4 | """ |
5 | | -from os.path import dirname, join |
| 5 | +from glob import glob |
| 6 | +import os |
| 7 | +import os.path |
| 8 | +import shutil |
| 9 | + |
| 10 | +from setuptools.command.test import test |
6 | 11 | from setuptools import setup, find_packages |
7 | 12 |
|
8 | 13 | import pythonturtle as package |
9 | 14 |
|
10 | 15 |
|
| 16 | +class Bundle(test): |
| 17 | + """A setuptools command to build application bundles for all platforms""" |
| 18 | + |
| 19 | + def run(self): |
| 20 | + import PyInstaller.__main__ |
| 21 | + |
| 22 | + resources_folder = os.path.join('pythonturtle', 'resources') |
| 23 | + |
| 24 | + def resource_path(file_glob): |
| 25 | + return os.path.join(resources_folder, file_glob) |
| 26 | + |
| 27 | + def include_resources(file_glob): |
| 28 | + return '{src}{separator}{dest}'.format( |
| 29 | + src=resource_path(file_glob), |
| 30 | + separator=os.pathsep, |
| 31 | + dest=resources_folder) |
| 32 | + |
| 33 | + PyInstaller.__main__.run([ |
| 34 | + '--name=%s' % package.name, |
| 35 | + '--onefile', |
| 36 | + '--windowed', |
| 37 | + '--add-binary=%s' % include_resources('*.ic*'), |
| 38 | + '--add-binary=%s' % include_resources('*.png'), |
| 39 | + '--add-data=%s' % include_resources('*.txt'), |
| 40 | + '--icon=%s' % resource_path('icon.ico'), |
| 41 | + os.path.join('pythonturtle', '__main__.py'), |
| 42 | + ]) |
| 43 | + |
| 44 | + |
| 45 | +class Clean(test): |
| 46 | + """A setuptools command to remove build files and folders""" |
| 47 | + |
| 48 | + def run(self): |
| 49 | + delete_in_root = [ |
| 50 | + 'build', |
| 51 | + 'dist', |
| 52 | + '.eggs', |
| 53 | + '*.egg-info', |
| 54 | + '.pytest_cache', |
| 55 | + '*.spec', |
| 56 | + '.tox', |
| 57 | + ] |
| 58 | + delete_everywhere = [ |
| 59 | + '*.pyc', |
| 60 | + '__pycache__', |
| 61 | + ] |
| 62 | + for candidate in delete_in_root: |
| 63 | + rmtree_glob(candidate) |
| 64 | + for visible_dir in glob('[A-Za-z0-9_]*'): |
| 65 | + for candidate in delete_everywhere: |
| 66 | + rmtree_glob(os.path.join(visible_dir, candidate)) |
| 67 | + rmtree_glob(os.path.join(visible_dir, '*', candidate)) |
| 68 | + rmtree_glob(os.path.join(visible_dir, '*', '*', candidate)) |
| 69 | + |
| 70 | + |
| 71 | +def rmtree_glob(file_glob): |
| 72 | + """Platform independent rmtree, which also allows wildcards (globbing)""" |
| 73 | + for item in glob(file_glob): |
| 74 | + try: |
| 75 | + shutil.rmtree(item) |
| 76 | + print('%s/ removed ...' % item) |
| 77 | + except OSError: |
| 78 | + try: |
| 79 | + os.remove(item) |
| 80 | + print('%s removed ...' % item) |
| 81 | + except OSError as err: |
| 82 | + print(err) |
| 83 | + |
| 84 | + |
11 | 85 | def read_file(filename): |
12 | 86 | """Source the contents of a file""" |
13 | | - with open(join(dirname(__file__), filename)) as file: |
| 87 | + with open(os.path.join(os.path.dirname(__file__), filename)) as file: |
14 | 88 | return file.read() |
15 | 89 |
|
16 | 90 |
|
@@ -49,6 +123,11 @@ def read_file(filename): |
49 | 123 | zip_safe=True, |
50 | 124 | # install_requires=['wxPython'], |
51 | 125 | tests_require=['tox'], |
| 126 | + test_suite='tests', |
| 127 | + cmdclass={ |
| 128 | + 'bundle': Bundle, |
| 129 | + 'clean': Clean, |
| 130 | + }, |
52 | 131 | entry_points={ |
53 | 132 | 'console_scripts': [ |
54 | 133 | 'PythonTurtle = pythonturtle.__main__:application.run', |
|
0 commit comments