1#!/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 os 18import shutil 19import subprocess 20import sys 21from distutils import cmd 22from distutils import log 23 24import setuptools 25from setuptools.command.develop import develop 26from setuptools.command.install import install 27 28FRAMEWORK_DIR = 'acts_framework' 29LOCAL_FRAMEWORK_DIR = '../acts/framework' 30 31acts_tests_dir = os.path.abspath(os.path.dirname(__file__)) 32 33install_requires = [] 34 35 36 37def _setup_acts_framework(option, *args): 38 """Locates and runs setup.py for the ACTS framework. 39 40 Args: 41 option: the option to use with setup.py, e.g. install, develop 42 args: additional args for the command 43 """ 44 acts_framework_dir = os.path.join(acts_tests_dir, FRAMEWORK_DIR) 45 if not os.path.isdir(acts_framework_dir): 46 log.info('Directory "%s" not found. Attempting to locate ACTS ' 47 'framework through local repository.' % acts_framework_dir) 48 acts_framework_dir = os.path.join(acts_tests_dir, LOCAL_FRAMEWORK_DIR) 49 if not os.path.isdir(acts_framework_dir): 50 log.error('Cannot install ACTS framework. Framework dir "%s" not ' 51 'found.' % acts_framework_dir) 52 exit(1) 53 acts_setup_bin = os.path.join(acts_framework_dir, 'setup.py') 54 if not os.path.isfile(acts_setup_bin): 55 log.error('Cannot install ACTS framework. Setup script not found.') 56 exit(1) 57 command = [sys.executable, acts_setup_bin, option, *args] 58 subprocess.check_call(command, cwd=acts_framework_dir) 59 60 61class ActsContribInstall(install): 62 """Custom installation of the acts_contrib package. 63 64 Also installs the required ACTS framework via its own setup.py script. 65 66 The installation requires the ACTS framework to exist under the 67 "acts_framework" directory, at the same level of this setup script. 68 Otherwise, it will attempt to locate the ACTS framework from the local 69 repository. 70 """ 71 def run(self): 72 super().run() 73 _setup_acts_framework('install') 74 75 76class ActsContribDevelop(develop): 77 """Custom installation of the acts_contrib package (in develop mode). 78 79 See ActsContribInstall for more details. 80 """ 81 def run(self): 82 super().run() 83 if self.uninstall: 84 _setup_acts_framework('develop', '-u') 85 else: 86 _setup_acts_framework('develop') 87 88 89class ActsContribInstallDependencies(cmd.Command): 90 """Installs only required packages 91 92 Installs all required packages for acts_contrib to work. Rather than using 93 the normal install system which creates links with the python egg, pip is 94 used to install the packages. 95 """ 96 97 description = 'Install dependencies needed for acts_contrib packages.' 98 user_options = [] 99 100 def initialize_options(self): 101 pass 102 103 def finalize_options(self): 104 pass 105 106 def run(self): 107 install_args = [sys.executable, '-m', 'pip', 'install'] 108 subprocess.check_call(install_args + ['--upgrade', 'pip']) 109 required_packages = self.distribution.install_requires 110 111 for package in required_packages: 112 self.announce('Installing %s...' % package, log.INFO) 113 subprocess.check_call(install_args + 114 ['-v', '--no-cache-dir', package]) 115 116 self.announce('Dependencies installed.') 117 118 119class ActsContribUninstall(cmd.Command): 120 """acts_contrib uninstaller. 121 122 Uninstalls acts_contrib from the current version of python. This will 123 attempt to import acts_contrib from any of the python egg locations. If it 124 finds an import it will use the modules file location to delete it. This is 125 repeated until acts_contrib can no longer be imported and thus is 126 uninstalled. 127 """ 128 129 description = 'Uninstall acts_contrib from the local machine.' 130 user_options = [] 131 132 def initialize_options(self): 133 pass 134 135 def finalize_options(self): 136 pass 137 138 def uninstall_acts_contrib_module(self, acts_contrib_module): 139 """Uninstalls acts_contrib from a module. 140 141 Args: 142 acts_contrib_module: The acts_contrib module to uninstall. 143 """ 144 for acts_contrib_install_dir in acts_contrib_module.__path__: 145 self.announce('Deleting acts_contrib from: %s' 146 % acts_contrib_install_dir, log.INFO) 147 shutil.rmtree(acts_contrib_install_dir) 148 149 def run(self): 150 """Entry point for the uninstaller.""" 151 # Remove the working directory from the python path. This ensures that 152 # Source code is not accidentally targeted. 153 our_dir = os.path.abspath(os.path.dirname(__file__)) 154 if our_dir in sys.path: 155 sys.path.remove(our_dir) 156 157 if os.getcwd() in sys.path: 158 sys.path.remove(os.getcwd()) 159 160 try: 161 import acts_contrib as acts_contrib_module 162 except ImportError: 163 self.announce('acts_contrib is not installed, nothing to uninstall.', 164 level=log.ERROR) 165 return 166 167 while acts_contrib_module: 168 self.uninstall_acts_contrib_module(acts_contrib_module) 169 try: 170 del sys.modules['acts_contrib'] 171 import acts_contrib as acts_contrib_module 172 except ImportError: 173 acts_contrib_module = None 174 175 self.announce('Finished uninstalling acts_contrib.') 176 177 # Uninstall the ACTS framework 178 _setup_acts_framework('uninstall') 179 180 181def main(): 182 os.chdir(acts_tests_dir) 183 packages = setuptools.find_packages(include=('acts_contrib*',)) 184 setuptools.setup(name='acts_contrib', 185 version='0.9', 186 description='Android Comms Test Suite', 187 license='Apache2.0', 188 packages=packages, 189 include_package_data=True, 190 install_requires=install_requires, 191 cmdclass={ 192 'install': ActsContribInstall, 193 'develop': ActsContribDevelop, 194 'install_deps': ActsContribInstallDependencies, 195 'uninstall': ActsContribUninstall 196 }, 197 url="http://www.android.com/") 198 199 200if __name__ == '__main__': 201 main() 202