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