• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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