forked from rackspace/runway
-
Notifications
You must be signed in to change notification settings - Fork 0
/
runway.file.spec
118 lines (99 loc) · 4.27 KB
/
runway.file.spec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""pyinstaller spec file to build a single-binary distribution of runway.
This file should be considered a python file and linted as such.
"""
# pylint: disable=undefined-variable,wrong-import-order,invalid-name
# pylint: disable=wrong-import-position,import-self
import os
import pkgutil
from pkg_resources import get_distribution, get_entry_info
# distutils not included with virtualenv < 20 so we have to import it here
# can be removed once we can upgrade virtualenv and pyinstaller
import distutils
if distutils.distutils_path.endswith('__init__.py'):
distutils.distutils_path = os.path.dirname(distutils.distutils_path)
CLI_PATH = os.path.join(os.path.dirname(os.path.dirname(workpath)), # noqa
'runway')
def get_submodules(package):
"""Get submodules of a package to add to hiddenimports.
Package must be installed and imported for this to be used.
This is needed for dependencies that do not have a
native pyinstaller hook. This may not find everything that
needs to be included.
Args:
package: An import package to inspect.
Returns:
List of submodules.
"""
return [name for _, name, _ in
pkgutil.walk_packages(path=package.__path__,
prefix=package.__name__+'.',
onerror=lambda x: None)]
def Entrypoint(dist, group, name, **kwargs): # noqa
"""Get entrypoint info for packages using setuptools."""
ep = get_entry_info(dist, group, name)
# script name must not be a valid module name to avoid name clashes on import
script_path = os.path.join(workpath, name + '-script.py') # noqa: F821
print("creating script for entry point", dist, group, name)
with open(script_path, 'w') as fh:
print("import", ep.module_name, file=fh)
print("%s.%s()" % (ep.module_name, '.'.join(ep.attrs)), file=fh)
return Analysis([script_path] + kwargs.get('scripts', []), **kwargs) # noqa: F821
# files that are not explicitly imported but consumed at runtime
# need to be included as data_files.
data_files = [
(os.path.join(CLI_PATH, 'templates'), './runway/templates'),
(os.path.join(CLI_PATH, 'blueprints'), './runway/blueprints'),
(os.path.join(CLI_PATH, 'hooks'), './runway/hooks')
]
data_files.append(('{}/yamllint/conf'.format(get_distribution('yamllint').location),
'yamllint/conf/'))
data_files.append(('{}/cfnlint/data'.format(get_distribution('cfn-lint').location),
'cfnlint/data/'))
data_files.append(('{}/botocore/data'.format(get_distribution('botocore').location),
'botocore/data/'))
data_files.append(('{}/awscli/data'.format(get_distribution('awscli').location),
'awscli/data/'))
# pyinstaller is not able to find dependencies of dependencies
# unless a hook already exists for pyinstaller so we have to
# add their dependencies here.
hiddenimports = []
# these packages do not have pyinstaller hooks so we need to import
# them to collect a list of submodules to include as hidden imports.
import runway # noqa
import troposphere # noqa
import awacs # noqa
import awscli # noqa
import botocore # noqa
hiddenimports.extend(get_submodules(runway))
hiddenimports.extend(get_submodules(troposphere))
hiddenimports.extend(get_submodules(awacs))
hiddenimports.extend(get_submodules(awscli))
hiddenimports.extend(get_submodules(botocore))
# needed due to pkg_resources dropping python2 support
# can be removed on the next pyinstaller release
# https://github.com/pypa/setuptools/issues/1963#issuecomment-582084099
hiddenimports.append('pkg_resources.py2_warn')
a = Entrypoint('runway',
'console_scripts',
'runway',
pathex=[CLI_PATH],
datas=data_files,
hiddenimports=hiddenimports,
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False,
binaries=[])
pyz = PYZ(a.pure, a.zipped_data, # noqa: F821
cipher=None)
exe = EXE(pyz, # noqa: F821
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='runway',
strip=False,
upx=True,
runtime_tmpdir=None,
console=True)