blob: f8bb67728e9baf9f8f2a2c127baf9f4c430725e2 [file] [log] [blame]
Xianyuan Jia1df188c2020-04-15 15:58:09 -07001#!/usr/bin/env python3
2#
3# Copyright 2017 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import logging
18import os
19import shutil
20import subprocess
21import sys
22from distutils import cmd
23from distutils import log
24
25import setuptools
26from setuptools.command.install import install
27
28FRAMEWORK_DIR = 'acts_framework'
29
30acts_tests_dir = os.path.abspath(os.path.dirname(__file__))
31
32install_requires = [
33 # Future needs to have a newer version that contains urllib.
34 'future>=0.16.0',
35 # Latest version of mock (4.0.0b) causes a number of compatibility issues
36 # with ACTS unit tests (b/148695846, b/148814743)
37 'mock==3.0.5',
38 'numpy',
39 'pyserial',
40 'pyyaml>=5.1',
41 'protobuf>=3.11.3',
42 'requests',
43 'scapy',
44 'xlsxwriter',
45 'mobly>=1.10.0',
46]
47
48if sys.version_info < (3, ):
49 install_requires.append('enum34')
50 install_requires.append('statistics')
51 # "futures" is needed for py2 compatibility and it only works in 2.7
52 install_requires.append('futures')
53 install_requires.append('subprocess32')
54
55
56class ActsContribInstall(install):
57 """Custom installation of the acts_contrib package.
58
59 First installs the required ACTS framework via its own setup.py script,
60 before proceeding with the rest of the installation.
61
62 The installation requires the ACTS framework to exist under the
63 "acts_framework" directory.
64 """
65 def run(self):
66 acts_framework_dir = os.path.join(acts_tests_dir, FRAMEWORK_DIR)
67 if not os.path.isdir(acts_framework_dir):
68 logging.error('Cannot install ACTS framework. Framework dir '
69 '"%s" not found' % acts_framework_dir)
70 exit(1)
71 acts_setup_bin = os.path.join(acts_framework_dir, 'setup.py')
72 if not os.path.isfile(acts_setup_bin):
73 logging.error('Cannot install ACTS framework. Setup script not '
74 'found.')
75 exit(1)
76 command = [sys.executable, acts_setup_bin, 'install']
77 subprocess.check_call(command, cwd=acts_framework_dir)
78 super().run()
79
80
81class ActsContribInstallDependencies(cmd.Command):
82 """Installs only required packages
83
84 Installs all required packages for acts_contrib to work. Rather than using
85 the normal install system which creates links with the python egg, pip is
86 used to install the packages.
87 """
88
89 description = 'Install dependencies needed for acts_contrib packages.'
90 user_options = []
91
92 def initialize_options(self):
93 pass
94
95 def finalize_options(self):
96 pass
97
98 def run(self):
99 install_args = [sys.executable, '-m', 'pip', 'install']
100 subprocess.check_call(install_args + ['--upgrade', 'pip'])
101 required_packages = self.distribution.install_requires
102
103 for package in required_packages:
104 self.announce('Installing %s...' % package, log.INFO)
105 subprocess.check_call(install_args +
106 ['-v', '--no-cache-dir', package])
107
108 self.announce('Dependencies installed.')
109
110
111class ActsContribUninstall(cmd.Command):
112 """acts_contrib uninstaller.
113
114 Uninstalls acts_contrib from the current version of python. This will
115 attempt to import acts_contrib from any of the python egg locations. If it
116 finds an import it will use the modules file location to delete it. This is
117 repeated until acts_contrib can no longer be imported and thus is
118 uninstalled.
119 """
120
121 description = 'Uninstall acts_contrib from the local machine.'
122 user_options = []
123
124 def initialize_options(self):
125 pass
126
127 def finalize_options(self):
128 pass
129
130 def uninstall_acts_contrib_module(self, acts_contrib_module):
131 """Uninstalls acts_contrib from a module.
132
133 Args:
134 acts_contrib_module: The acts_contrib module to uninstall.
135 """
136 for acts_contrib_install_dir in acts_contrib_module.__path__:
137 self.announce('Deleting acts_contrib from: %s'
138 % acts_contrib_install_dir, log.INFO)
139 shutil.rmtree(acts_contrib_install_dir)
140
141 def run(self):
142 """Entry point for the uninstaller."""
143 # Remove the working directory from the python path. This ensures that
144 # Source code is not accidentally targeted.
145 our_dir = os.path.abspath(os.path.dirname(__file__))
146 if our_dir in sys.path:
147 sys.path.remove(our_dir)
148
149 if os.getcwd() in sys.path:
150 sys.path.remove(os.getcwd())
151
152 try:
153 import acts_contrib as acts_contrib_module
154 except ImportError:
155 self.announce('acts_contrib is not installed, nothing to uninstall.',
156 level=log.ERROR)
157 return
158
159 while acts_contrib_module:
160 self.uninstall_acts_contrib_module(acts_contrib_module)
161 try:
162 del sys.modules['acts_contrib']
163 import acts_contrib as acts_contrib_module
164 except ImportError:
165 acts_contrib_module = None
166
167 self.announce('Finished uninstalling acts_contrib.')
168
169
170def main():
171 os.chdir(acts_tests_dir)
172 packages = setuptools.find_packages(include=('acts_contrib*',))
173 setuptools.setup(name='acts_contrib',
174 version='0.9',
175 description='Android Comms Test Suite',
176 license='Apache2.0',
177 packages=packages,
Xianyuan Jia54bdf5c2020-06-03 16:36:41 -0700178 include_package_data=True,
Xianyuan Jia1df188c2020-04-15 15:58:09 -0700179 install_requires=install_requires,
180 cmdclass={
181 'install': ActsContribInstall,
182 'install_deps': ActsContribInstallDependencies,
183 'uninstall': ActsContribUninstall
184 },
185 url="http://www.android.com/")
186
187
188if __name__ == '__main__':
189 main()