def search(clazz, tarball, pattern, ignore_case=False, whole_word=False): 'Return the output of either ag (silver searcher) or grep for the contents of an archive.' ag = which.which('ag') if ag: cmd = [ag] else: grep = which.which('grep') if not grep: raise RuntimeError('No grep or ag found.') cmd = [grep, '-r'] if ignore_case: cmd.append('-i') if whole_word: cmd.append('-w') cmd.extend([pattern, '.']) tmp_dir = temp_file.make_temp_dir() archiver.extract(tarball, tmp_dir, strip_common_ancestor=True) result = execute.execute(cmd, cwd=tmp_dir, shell=True, raise_error=False) file_util.remove(tmp_dir) return result
def test_which_unix(self): 'Test which() in unix.' tmp_dir = self.make_temp_dir() bin_dir = path.join(tmp_dir, 'bin') content = '!#/bin/bash\nechoecho kiwi\nexit 0\n' temp_exe = file_util.save(path.join(bin_dir, 'fruit_kiwi_tool'), content=content, mode=0o0755) self.assertEqual(None, which.which('fruit_kiwi_tool')) with env_override.path_append(bin_dir) as env: expected_path = path.join(bin_dir, 'fruit_kiwi_tool') self.assertEqual(expected_path, which.which('fruit_kiwi_tool'))
def test_which_windows(self): 'Test which() in unix.' tmp_dir = self.make_temp_dir() bin_dir = path.join(tmp_dir, 'bin') content = '@echo off\n\recho kiwi\n\rexit 0\n\r' temp_bat = file_util.save(path.join(bin_dir, 'fruit_kiwi_tool.bat'), content=content, mode=0o0755) self.assertEqual(None, which.which('fruit_kiwi_tool.bat')) with env_override.path_append(bin_dir) as env: expected_path = path.join(bin_dir, 'fruit_kiwi_tool.bat') self.assertEqual(expected_path, which.which('fruit_kiwi_tool.bat')) self.assertEqual(expected_path, which.which('fruit_kiwi_tool'))
def page(clazz, filename): 'Page a file with ${PAGER}' check.check_string(filename) if not path.exists(filename): raise RuntimeError('Not found: "{}"'.format(filename)) v = os_env_var('PAGER') if v.is_set: pager = which.which(v.value) else: pager = which.which('less') or which.which('more') if not pager: raise RuntimeError('Pager not found') subprocess.call([pager, filename])
def _call_softwareupdate(clazz, args, verbose): check.check_string_seq(args) check.check_bool(verbose) command_line.check_args_type(args) args = object_util.listify(args) exe = which.which('softwareupdate') if not exe: raise softwareupdater_error('softwareupdate not found') clazz._log.log_d('_call_softwareupdate: exe={} args={}'.format( exe, args)) cmd = [exe] + args env = os_env.clone_current_env() rv = execute.execute(cmd, env=env, stderr_to_stdout=True, raise_error=False, non_blocking=verbose) if rv.exit_code != 0: cmd_flat = ' '.join(cmd) msg = 'softwareupdate command failed: {} - {}\n{}'.format( cmd, rv.exit_code, rv.stdout) raise softwareupdater_error(msg, status_code=rv.exit_code) return rv
def exe_for_sys_version(clazz, absolute=True): 'Return the python executable binary for sys.version (python2.7, python3.7, etc)' check.check_bool(absolute) exe = 'python{major}.{minor}'.format(major=sys.version_info.major, minor=sys.version_info.minor) if absolute: return which.which(exe) else: return exe
def _find_handle_exe(clazz): 'Find the handle.exe' extra_path = [ r'c:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\layout', r'c:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.Visua#lStudio.Setup.Service', ] handle_exe_name = 'handle.exe' exe = which.which(handle_exe_name, extra_path=extra_path) if exe: return exe raise handle_error('Failed to find {}'.format(handle_exe_name))
def _call_ssh_keyscan(clazz, args, cwd=None): exe = which.which('ssh-keyscan') if not exe: raise ssh_config_error('ssh-keyscan executable not found') cmd = [exe] + command_line.parse_args(args) try: rv = execute.execute(cmd, env=os_env.make_clean_env(), cwd=cwd, stderr_to_stdout=True) return rv.stdout.strip() except Exception as ex: raise ssh_config_error('Failed to run: "{}" - '.format( ' '.join(cmd), str(ex)))
def installed(clazz, verbose=False): 'Return True of command line tools are installed.' exe = which.which('xcode-select') if not exe: return False cmd = [exe, '--print-path'] rv = execute.execute(cmd, raise_error=False) if rv.exit_code != 0: if verbose: print('not installed') return False print('installed') return True
def _find_egoist(clazz): v = os_env_var('EGOIST') if v.is_set: if not path.exists(v.value): raise RuntimeError('${EGOIST} not found: {}'.format(v.value)) if not file_path.is_executable(v.value): raise RuntimeError('${EGOIST} not an executable: {}'.format( v.value)) return v.value for possible_egoist in ['egoist', 'egoist2.py', 'egoist3.py']: egoist = which.which(possible_egoist, raise_error=False) if egoist: return egoist raise RuntimeError( 'egoist not found in either the environment or PATH.')
def call_docker(clazz, args, cwd=None, non_blocking=True, shell=False): exe = which.which('docker') if not exe: raise docker_error('docker not found') cmd = [exe] + command_line.parse_args(args) env = os_env.clone_current_env(d={}) rv = execute.execute(cmd, env=env, shell=shell, cwd=cwd, stderr_to_stdout=True, non_blocking=non_blocking, raise_error=False) if rv.exit_code != 0: cmd_flag = ' '.join(cmd) msg = 'docker command failed: {}\n{}'.format(cmd_flag, rv.stdout) raise docker_error(msg) return rv
def call_sudo(clazz, args, options=None): check.check_sudo_cli_options(options, allow_none=True) command_line.check_args_type(args) args = object_util.listify(args) options = options or sudo_cli_options() exe = which.which('sudo') if not exe: raise sudo_error('sudo not found') clazz._log.log_d('sudo: exe={} args={} options={}'.format( exe, args, options)) cmd = [exe] tmp_askpass = None askpass_env = {} if options.password: tmp_askpass = clazz._make_temp_askpass(options.password) askpass_env = {'SUDO_ASKPASS': tmp_askpass} cmd.append('--askpass') if options.prompt: cmd.extend(['--prompt', '"{}"'.format(options.prompt)]) cmd.extend(args) env = os_env.clone_current_env(d=askpass_env) try: rv = execute.execute(cmd, env=env, cwd=options.working_dir, stderr_to_stdout=True, raise_error=False, non_blocking=options.verbose) if rv.exit_code != 0: if options.error_message: msg = options.error_message else: cmd_flat = ' '.join(cmd) msg = 'sudo command failed: {}\n{}'.format( cmd_flat, rv.stdout) raise sudo_error(msg) return rv finally: if tmp_askpass: file_util.remove(tmp_askpass)
def copy_tree(clazz, src_dir, dst_dir, excludes=None): excludes = excludes or [] if not path.isdir(src_dir): raise RuntimeError('src_dir is not a directory: %s' % (src_dir)) file_util.mkdir(dst_dir) xcopy_exe = which.which('robocopy.exe') cmd = [ xcopy_exe, '"{}"'.format(src_dir), '"{}"'.format(dst_dir), '/E', # Copies all subdirectories, even if they are empty ] if excludes: for exclude in excludes: cmd.extend(['/XF', '"{}"'.format(exclude)]) rv = execute.execute(cmd, shell=True, raise_error=False, stderr_to_stdout=True) if rv.exit_code >= 0 and rv.exit_code <= 7: return raise RuntimError('robocopy failed: "{}" - {}'.format( ' '.join(cmd), str(rv.stdout)))
def find_exe(clazz, raise_error = False): 'Return the pyinstaller executable or None if not found' return which.which('pyinstaller', raise_error = raise_error)
def which(clazz, program, raise_error=False): 'Same as unix which.' return which.which(program)
def vmrun_exe_path(clazz): 'The full path to the vmrun executable.' return which.which('vmrun')
def is_supported(clazz): 'Return True if this class is supported on the current platform.' return host.is_unix() and which.which('file') != None