Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Module for build host support.""" | 5 """Module for build host support.""" |
| 6 | 6 |
| 7 import os | 7 import os |
| 8 import pipes | 8 import pipes |
| 9 import signal | 9 import signal |
| 10 import subprocess | 10 import subprocess |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 def Matches(self): | 29 def Matches(self): |
| 30 """Detects whether this is the correct host implementation. | 30 """Detects whether this is the correct host implementation. |
| 31 | 31 |
| 32 This method is overridden by the concrete implementations. | 32 This method is overridden by the concrete implementations. |
| 33 Returns: | 33 Returns: |
| 34 true if the plugin matches the machine it is running on. | 34 true if the plugin matches the machine it is running on. |
| 35 """ | 35 """ |
| 36 return False | 36 return False |
| 37 | 37 |
| 38 @classmethod | 38 @classmethod |
| 39 def Select(cls, context): | 39 def Select(cls): |
| 40 for host in cls.Plugins(): | 40 for host in cls.Plugins(): |
| 41 if host.Matches(): | 41 if host.Matches(): |
| 42 return host | 42 return host |
| 43 | 43 |
| 44 def _Execute(self, context, command, | 44 def _Execute(self, command, |
| 45 shell=False, capture=False, silent=False, | 45 shell=False, capture=False, silent=False, |
| 46 ignore_dry_run=False, return_status=False, | 46 ignore_dry_run=False, return_status=False, |
| 47 ignore_interrupt_signal=False): | 47 ignore_interrupt_signal=False): |
| 48 """This is the only method that launches external programs. | 48 """This is the only method that launches external programs. |
| 49 | 49 |
| 50 It is a thin wrapper around subprocess.Popen that handles cr specific | 50 It is a thin wrapper around subprocess.Popen that handles cr specific |
| 51 issues. The command is expanded in the context, so that context variables | 51 issues. The command is expanded in the so that context variables |
|
Andrew Hayden (chromium.org)
2014/03/19 18:20:06
Search and replace is not your friend.
iancottrell
2014/03/19 22:17:11
Unfortunately none of this change was amenable to
| |
| 52 are substituted. | 52 are substituted. |
| 53 Args: | 53 Args: |
| 54 context: the cr context to run under. | |
| 55 command: the command to run. | 54 command: the command to run. |
| 56 shell: whether to run the command using the shell. | 55 shell: whether to run the command using the shell. |
| 57 capture: controls wether the output of the command is captured. | 56 capture: controls wether the output of the command is captured. |
| 58 ignore_dry_run: Normally, if the context is in dry run mode the command is | 57 ignore_dry_run: Normally, if the context is in dry run mode the command is |
| 59 printed but not executed. This flag overrides that behaviour, causing | 58 printed but not executed. This flag overrides that behaviour, causing |
| 60 the command to be run anyway. | 59 the command to be run anyway. |
| 61 return_status: switches the function to returning the status code rather | 60 return_status: switches the function to returning the status code rather |
| 62 the output. | 61 the output. |
| 63 ignore_interrupt_signal: Ignore the interrupt signal (i.e., Ctrl-C) while | 62 ignore_interrupt_signal: Ignore the interrupt signal (i.e., Ctrl-C) while |
| 64 the command is running. Useful for letting interactive programs manage | 63 the command is running. Useful for letting interactive programs manage |
| 65 Ctrl-C by themselves. | 64 Ctrl-C by themselves. |
| 66 Returns: | 65 Returns: |
| 67 the status if return_status is true, or the output if capture is true, | 66 the status if return_status is true, or the output if capture is true, |
| 68 otherwise nothing. | 67 otherwise nothing. |
| 69 """ | 68 """ |
| 70 with context.Trace(): | 69 with cr.context.Trace(): |
| 71 command = [context.Substitute(arg) for arg in command if arg] | 70 command = [cr.context.Substitute(arg) for arg in command if arg] |
| 72 trail = context.trail | 71 trail = cr.context.trail |
| 73 if not command: | 72 if not command: |
| 74 print 'Empty command passed to execute' | 73 print 'Empty command passed to execute' |
| 75 exit(1) | 74 exit(1) |
| 76 if context.verbose: | 75 if cr.context.verbose: |
| 77 print ' '.join(command) | 76 print ' '.join(command) |
| 78 if context.verbose >= _TRAIL_VERBOSITY: | 77 if cr.context.verbose >= _TRAIL_VERBOSITY: |
| 79 print 'Command expanded the following variables:' | 78 print 'Command expanded the following variables:' |
| 80 for key, value in trail: | 79 for key, value in trail: |
| 81 print ' ', key, '=', value | 80 print ' ', key, '=', value |
| 82 if ignore_dry_run or not context.dry_run: | 81 if ignore_dry_run or not cr.context.dry_run: |
| 83 out = None | 82 out = None |
| 84 if capture: | 83 if capture: |
| 85 out = subprocess.PIPE | 84 out = subprocess.PIPE |
| 86 elif silent: | 85 elif silent: |
| 87 out = open(os.devnull, "w") | 86 out = open(os.devnull, "w") |
| 88 try: | 87 try: |
| 89 p = subprocess.Popen( | 88 p = subprocess.Popen( |
| 90 command, shell=shell, | 89 command, shell=shell, |
| 91 env={k: str(v) for k, v in context.exported.items()}, | 90 env={k: str(v) for k, v in cr.context.exported.items()}, |
| 92 stdout=out) | 91 stdout=out) |
| 93 except OSError: | 92 except OSError: |
| 94 print 'Failed to exec', command | 93 print 'Failed to exec', command |
| 95 # Don't log the trail if we already have | 94 # Don't log the trail if we already have |
| 96 if context.verbose < _TRAIL_VERBOSITY: | 95 if cr.context.verbose < _TRAIL_VERBOSITY: |
| 97 print 'Variables used to build the command were:' | 96 print 'Variables used to build the command were:' |
| 98 for key, value in trail: | 97 for key, value in trail: |
| 99 print ' ', key, '=', value | 98 print ' ', key, '=', value |
| 100 exit(1) | 99 exit(1) |
| 101 try: | 100 try: |
| 102 if ignore_interrupt_signal: | 101 if ignore_interrupt_signal: |
| 103 signal.signal(signal.SIGINT, signal.SIG_IGN) | 102 signal.signal(signal.SIGINT, signal.SIG_IGN) |
| 104 output, _ = p.communicate() | 103 output, _ = p.communicate() |
| 105 finally: | 104 finally: |
| 106 if ignore_interrupt_signal: | 105 if ignore_interrupt_signal: |
| 107 signal.signal(signal.SIGINT, signal.SIG_DFL) | 106 signal.signal(signal.SIGINT, signal.SIG_DFL) |
| 108 if silent: | 107 if silent: |
| 109 out.close() | 108 out.close() |
| 110 if return_status: | 109 if return_status: |
| 111 return p.returncode | 110 return p.returncode |
| 112 if p.returncode != 0: | 111 if p.returncode != 0: |
| 113 print 'Error {0} executing command {1}'.format(p.returncode, command) | 112 print 'Error {0} executing command {1}'.format(p.returncode, command) |
| 114 exit(p.returncode) | 113 exit(p.returncode) |
| 115 return output or '' | 114 return output or '' |
| 116 return '' | 115 return '' |
| 117 | 116 |
| 118 @cr.Plugin.activemethod | 117 @cr.Plugin.activemethod |
| 119 def Shell(self, context, *command): | 118 def Shell(self, *command): |
| 120 command = ' '.join([pipes.quote(arg) for arg in command]) | 119 command = ' '.join([pipes.quote(arg) for arg in command]) |
| 121 return self._Execute(context, [command], shell=True, | 120 return self._Execute([command], shell=True, ignore_interrupt_signal=True) |
| 122 ignore_interrupt_signal=True) | |
| 123 | 121 |
| 124 @cr.Plugin.activemethod | 122 @cr.Plugin.activemethod |
| 125 def Execute(self, context, *command): | 123 def Execute(self, *command): |
| 126 return self._Execute(context, command, shell=False) | 124 return self._Execute(command, shell=False) |
| 127 | 125 |
| 128 @cr.Plugin.activemethod | 126 @cr.Plugin.activemethod |
| 129 def ExecuteSilently(self, context, *command): | 127 def ExecuteSilently(self, *command): |
| 130 return self._Execute(context, command, shell=False, silent=True) | 128 return self._Execute(command, shell=False, silent=True) |
| 131 | 129 |
| 132 @cr.Plugin.activemethod | 130 @cr.Plugin.activemethod |
| 133 def CaptureShell(self, context, *command): | 131 def CaptureShell(self, *command): |
| 134 return self._Execute(context, command, | 132 return self._Execute(command, |
| 135 shell=True, capture=True, ignore_dry_run=True) | 133 shell=True, capture=True, ignore_dry_run=True) |
| 136 | 134 |
| 137 @cr.Plugin.activemethod | 135 @cr.Plugin.activemethod |
| 138 def Capture(self, context, *command): | 136 def Capture(self, *command): |
| 139 return self._Execute(context, command, capture=True, ignore_dry_run=True) | 137 return self._Execute(command, capture=True, ignore_dry_run=True) |
| 140 | 138 |
| 141 @cr.Plugin.activemethod | 139 @cr.Plugin.activemethod |
| 142 def ExecuteStatus(self, context, *command): | 140 def ExecuteStatus(self, *command): |
| 143 return self._Execute(context, command, | 141 return self._Execute(command, |
| 144 ignore_dry_run=True, return_status=True) | 142 ignore_dry_run=True, return_status=True) |
| 145 | 143 |
| 146 @cr.Plugin.activemethod | 144 @cr.Plugin.activemethod |
| 147 def YesNo(self, question, default=True): | 145 def YesNo(self, question, default=True): |
| 148 """Ask the user a yes no question | 146 """Ask the user a yes no question |
| 149 | 147 |
| 150 This blocks until the user responds. | 148 This blocks until the user responds. |
| 151 Args: | 149 Args: |
| 152 question: The question string to show the user | 150 question: The question string to show the user |
| 153 default: True if the default response is Yes | 151 default: True if the default response is Yes |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 172 result = [] | 170 result = [] |
| 173 extensions = [''] | 171 extensions = [''] |
| 174 extensions.extend(os.environ.get('PATHEXT', '').split(os.pathsep)) | 172 extensions.extend(os.environ.get('PATHEXT', '').split(os.pathsep)) |
| 175 for path in os.environ.get('PATH', '').split(os.pathsep): | 173 for path in os.environ.get('PATH', '').split(os.pathsep): |
| 176 partial = os.path.join(path, name) | 174 partial = os.path.join(path, name) |
| 177 for extension in extensions: | 175 for extension in extensions: |
| 178 filename = partial + extension | 176 filename = partial + extension |
| 179 if os.path.exists(filename) and filename not in result: | 177 if os.path.exists(filename) and filename not in result: |
| 180 result.append(filename) | 178 result.append(filename) |
| 181 return result | 179 return result |
| OLD | NEW |