blob: 4dbf6f790972746b577c80e4e1007ce7e635c534 [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
Xianyuan Jia1df188c2020-04-15 15:58:09 -070017import os
18import shutil
19import subprocess
20import sys
21from distutils import cmd
22from distutils import log
23
24import setuptools
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -080025from setuptools.command.develop import develop
Xianyuan Jia1df188c2020-04-15 15:58:09 -070026from setuptools.command.install import install
27
28FRAMEWORK_DIR = 'acts_framework'
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -080029LOCAL_FRAMEWORK_DIR = '../acts/framework'
Xianyuan Jia1df188c2020-04-15 15:58:09 -070030
31acts_tests_dir = os.path.abspath(os.path.dirname(__file__))
32
33install_requires = [
34 # Future needs to have a newer version that contains urllib.
35 'future>=0.16.0',
36 # Latest version of mock (4.0.0b) causes a number of compatibility issues
37 # with ACTS unit tests (b/148695846, b/148814743)
38 'mock==3.0.5',
39 'numpy',
40 'pyserial',
41 'pyyaml>=5.1',
42 'protobuf>=3.11.3',
43 'requests',
44 'scapy',
45 'xlsxwriter',
46 'mobly>=1.10.0',
47]
48
49if sys.version_info < (3, ):
50 install_requires.append('enum34')
51 install_requires.append('statistics')
52 # "futures" is needed for py2 compatibility and it only works in 2.7
53 install_requires.append('futures')
54 install_requires.append('subprocess32')
55
56
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -080057def _setup_acts_framework(option, *args):
58 """Locates and runs setup.py for the ACTS framework.
59
60 Args:
61 option: the option to use with setup.py, e.g. install, develop
62 args: additional args for the command
63 """
64 acts_framework_dir = os.path.join(acts_tests_dir, FRAMEWORK_DIR)
65 if not os.path.isdir(acts_framework_dir):
66 log.info('Directory "%s" not found. Attempting to locate ACTS '
67 'framework through local repository.' % acts_framework_dir)
68 acts_framework_dir = os.path.join(acts_tests_dir, LOCAL_FRAMEWORK_DIR)
69 if not os.path.isdir(acts_framework_dir):
70 log.error('Cannot install ACTS framework. Framework dir "%s" not '
71 'found.' % acts_framework_dir)
72 exit(1)
73 acts_setup_bin = os.path.join(acts_framework_dir, 'setup.py')
74 if not os.path.isfile(acts_setup_bin):
75 log.error('Cannot install ACTS framework. Setup script not found.')
76 exit(1)
77 command = [sys.executable, acts_setup_bin, option, *args]
78 subprocess.check_call(command, cwd=acts_framework_dir)
79
80
Xianyuan Jia1df188c2020-04-15 15:58:09 -070081class ActsContribInstall(install):
82 """Custom installation of the acts_contrib package.
83
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -080084 Also installs the required ACTS framework via its own setup.py script.
Xianyuan Jia1df188c2020-04-15 15:58:09 -070085
86 The installation requires the ACTS framework to exist under the
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -080087 "acts_framework" directory, at the same level of this setup script.
88 Otherwise, it will attempt to locate the ACTS framework from the local
89 repository.
Xianyuan Jia1df188c2020-04-15 15:58:09 -070090 """
91 def run(self):
Xianyuan Jia1df188c2020-04-15 15:58:09 -070092 super().run()
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -080093 _setup_acts_framework('install')
94
95
96class ActsContribDevelop(develop):
97 """Custom installation of the acts_contrib package (in develop mode).
98
99 See ActsContribInstall for more details.
100 """
101 def run(self):
102 super().run()
103 if self.uninstall:
104 _setup_acts_framework('develop', '-u')
105 else:
106 _setup_acts_framework('develop')
Xianyuan Jia1df188c2020-04-15 15:58:09 -0700107
108
109class ActsContribInstallDependencies(cmd.Command):
110 """Installs only required packages
111
112 Installs all required packages for acts_contrib to work. Rather than using
113 the normal install system which creates links with the python egg, pip is
114 used to install the packages.
115 """
116
117 description = 'Install dependencies needed for acts_contrib packages.'
118 user_options = []
119
120 def initialize_options(self):
121 pass
122
123 def finalize_options(self):
124 pass
125
126 def run(self):
127 install_args = [sys.executable, '-m', 'pip', 'install']
128 subprocess.check_call(install_args + ['--upgrade', 'pip'])
129 required_packages = self.distribution.install_requires
130
131 for package in required_packages:
132 self.announce('Installing %s...' % package, log.INFO)
133 subprocess.check_call(install_args +
134 ['-v', '--no-cache-dir', package])
135
136 self.announce('Dependencies installed.')
137
138
139class ActsContribUninstall(cmd.Command):
140 """acts_contrib uninstaller.
141
142 Uninstalls acts_contrib from the current version of python. This will
143 attempt to import acts_contrib from any of the python egg locations. If it
144 finds an import it will use the modules file location to delete it. This is
145 repeated until acts_contrib can no longer be imported and thus is
146 uninstalled.
147 """
148
149 description = 'Uninstall acts_contrib from the local machine.'
150 user_options = []
151
152 def initialize_options(self):
153 pass
154
155 def finalize_options(self):
156 pass
157
158 def uninstall_acts_contrib_module(self, acts_contrib_module):
159 """Uninstalls acts_contrib from a module.
160
161 Args:
162 acts_contrib_module: The acts_contrib module to uninstall.
163 """
164 for acts_contrib_install_dir in acts_contrib_module.__path__:
165 self.announce('Deleting acts_contrib from: %s'
166 % acts_contrib_install_dir, log.INFO)
167 shutil.rmtree(acts_contrib_install_dir)
168
169 def run(self):
170 """Entry point for the uninstaller."""
171 # Remove the working directory from the python path. This ensures that
172 # Source code is not accidentally targeted.
173 our_dir = os.path.abspath(os.path.dirname(__file__))
174 if our_dir in sys.path:
175 sys.path.remove(our_dir)
176
177 if os.getcwd() in sys.path:
178 sys.path.remove(os.getcwd())
179
180 try:
181 import acts_contrib as acts_contrib_module
182 except ImportError:
183 self.announce('acts_contrib is not installed, nothing to uninstall.',
184 level=log.ERROR)
185 return
186
187 while acts_contrib_module:
188 self.uninstall_acts_contrib_module(acts_contrib_module)
189 try:
190 del sys.modules['acts_contrib']
191 import acts_contrib as acts_contrib_module
192 except ImportError:
193 acts_contrib_module = None
194
195 self.announce('Finished uninstalling acts_contrib.')
196
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -0800197 # Uninstall the ACTS framework
198 _setup_acts_framework('uninstall')
199
Xianyuan Jia1df188c2020-04-15 15:58:09 -0700200
201def main():
202 os.chdir(acts_tests_dir)
203 packages = setuptools.find_packages(include=('acts_contrib*',))
204 setuptools.setup(name='acts_contrib',
205 version='0.9',
206 description='Android Comms Test Suite',
207 license='Apache2.0',
208 packages=packages,
Xianyuan Jia54bdf5c2020-06-03 16:36:41 -0700209 include_package_data=True,
Xianyuan Jia1df188c2020-04-15 15:58:09 -0700210 install_requires=install_requires,
211 cmdclass={
212 'install': ActsContribInstall,
Xianyuan Jiaeb15d4e2020-11-11 19:00:47 -0800213 'develop': ActsContribDevelop,
Xianyuan Jia1df188c2020-04-15 15:58:09 -0700214 'install_deps': ActsContribInstallDependencies,
215 'uninstall': ActsContribUninstall
216 },
217 url="http://www.android.com/")
218
219
220if __name__ == '__main__':
221 main()