1cef7893435aa41160dd1255c43cb8498279738ccChris Craik# Copyright 2014 The Chromium Authors. All rights reserved.
2cef7893435aa41160dd1255c43cb8498279738ccChris Craik# Use of this source code is governed by a BSD-style license that can be
3cef7893435aa41160dd1255c43cb8498279738ccChris Craik# found in the LICENSE file.
4cef7893435aa41160dd1255c43cb8498279738ccChris Craik
547f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craikimport glob
6cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport os
7cef7893435aa41160dd1255c43cb8498279738ccChris Craik
8cef7893435aa41160dd1255c43cb8498279738ccChris Craikfrom telemetry.core import util
97332cdb42368a904cbf7418de329868989e592daChris Craikimport py_utils as catapult_util
10cef7893435aa41160dd1255c43cb8498279738ccChris Craik
117332cdb42368a904cbf7418de329868989e592daChris Craik# TODO(aiolos): Move these functions to catapult_util or here.
12cef7893435aa41160dd1255c43cb8498279738ccChris CraikGetBaseDir = util.GetBaseDir
13cef7893435aa41160dd1255c43cb8498279738ccChris CraikGetTelemetryDir = util.GetTelemetryDir
14cef7893435aa41160dd1255c43cb8498279738ccChris CraikGetUnittestDataDir = util.GetUnittestDataDir
15cef7893435aa41160dd1255c43cb8498279738ccChris CraikGetChromiumSrcDir = util.GetChromiumSrcDir
16cef7893435aa41160dd1255c43cb8498279738ccChris CraikGetBuildDirectories = util.GetBuildDirectories
17cef7893435aa41160dd1255c43cb8498279738ccChris Craik
18cef7893435aa41160dd1255c43cb8498279738ccChris CraikIsExecutable = catapult_util.IsExecutable
19cef7893435aa41160dd1255c43cb8498279738ccChris Craik
20cef7893435aa41160dd1255c43cb8498279738ccChris Craik
2147f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craikdef _HasWildcardCharacters(input_string):
2247f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik  # Could make this more precise.
2347f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik  return '*' in input_string or '+' in input_string
2447f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik
2547f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik
26cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef FindInstalledWindowsApplication(application_path):
27cef7893435aa41160dd1255c43cb8498279738ccChris Craik  """Search common Windows installation directories for an application.
28cef7893435aa41160dd1255c43cb8498279738ccChris Craik
29cef7893435aa41160dd1255c43cb8498279738ccChris Craik  Args:
30cef7893435aa41160dd1255c43cb8498279738ccChris Craik    application_path: Path to application relative from installation location.
31cef7893435aa41160dd1255c43cb8498279738ccChris Craik  Returns:
32cef7893435aa41160dd1255c43cb8498279738ccChris Craik    A string representing the full path, or None if not found.
33cef7893435aa41160dd1255c43cb8498279738ccChris Craik  """
34cef7893435aa41160dd1255c43cb8498279738ccChris Craik  search_paths = [os.getenv('PROGRAMFILES(X86)'),
35cef7893435aa41160dd1255c43cb8498279738ccChris Craik                  os.getenv('PROGRAMFILES'),
36cef7893435aa41160dd1255c43cb8498279738ccChris Craik                  os.getenv('LOCALAPPDATA')]
37cef7893435aa41160dd1255c43cb8498279738ccChris Craik  search_paths += os.getenv('PATH', '').split(os.pathsep)
38cef7893435aa41160dd1255c43cb8498279738ccChris Craik  for search_path in search_paths:
39cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if not search_path:
40cef7893435aa41160dd1255c43cb8498279738ccChris Craik      continue
41cef7893435aa41160dd1255c43cb8498279738ccChris Craik    path = os.path.join(search_path, application_path)
4247f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik    if _HasWildcardCharacters(path):
4347f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik      paths = glob.glob(path)
4447f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik    else:
4547f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik      paths = [path]
4647f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik    for p in paths:
4747f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik      if IsExecutable(p):
4847f0f1e200da8a481462f364f822c98fe1b1cd5bChris Craik        return p
49cef7893435aa41160dd1255c43cb8498279738ccChris Craik  return None
50cef7893435aa41160dd1255c43cb8498279738ccChris Craik
51cef7893435aa41160dd1255c43cb8498279738ccChris Craik
52cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef IsSubpath(subpath, superpath):
53cef7893435aa41160dd1255c43cb8498279738ccChris Craik  """Returns True iff subpath is or is in superpath."""
54cef7893435aa41160dd1255c43cb8498279738ccChris Craik  subpath = os.path.realpath(subpath)
55cef7893435aa41160dd1255c43cb8498279738ccChris Craik  superpath = os.path.realpath(superpath)
56cef7893435aa41160dd1255c43cb8498279738ccChris Craik
57cef7893435aa41160dd1255c43cb8498279738ccChris Craik  while len(subpath) >= len(superpath):
58cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if subpath == superpath:
59cef7893435aa41160dd1255c43cb8498279738ccChris Craik      return True
60cef7893435aa41160dd1255c43cb8498279738ccChris Craik    subpath = os.path.split(subpath)[0]
61cef7893435aa41160dd1255c43cb8498279738ccChris Craik  return False
62cef7893435aa41160dd1255c43cb8498279738ccChris Craik
63cef7893435aa41160dd1255c43cb8498279738ccChris Craik
64cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef ListFiles(base_directory, should_include_dir=lambda _: True,
65cef7893435aa41160dd1255c43cb8498279738ccChris Craik              should_include_file=lambda _: True):
66cef7893435aa41160dd1255c43cb8498279738ccChris Craik  matching_files = []
67cef7893435aa41160dd1255c43cb8498279738ccChris Craik  for root, dirs, files in os.walk(base_directory):
68cef7893435aa41160dd1255c43cb8498279738ccChris Craik    dirs[:] = [dir_name for dir_name in dirs if should_include_dir(dir_name)]
69cef7893435aa41160dd1255c43cb8498279738ccChris Craik    matching_files += [os.path.join(root, file_name)
70cef7893435aa41160dd1255c43cb8498279738ccChris Craik                       for file_name in files if should_include_file(file_name)]
71cef7893435aa41160dd1255c43cb8498279738ccChris Craik  return sorted(matching_files)
72