xref: /aosp_15_r20/external/angle/build/util/lib/common/util.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker# Copyright 2013 The Chromium Authors
2*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
3*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
4*8975f5c5SAndroid Build Coastguard Worker
5*8975f5c5SAndroid Build Coastguard Worker"""Generic utilities for all python scripts."""
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Workerimport atexit
8*8975f5c5SAndroid Build Coastguard Workerimport httplib
9*8975f5c5SAndroid Build Coastguard Workerimport os
10*8975f5c5SAndroid Build Coastguard Workerimport signal
11*8975f5c5SAndroid Build Coastguard Workerimport stat
12*8975f5c5SAndroid Build Coastguard Workerimport subprocess
13*8975f5c5SAndroid Build Coastguard Workerimport sys
14*8975f5c5SAndroid Build Coastguard Workerimport tempfile
15*8975f5c5SAndroid Build Coastguard Workerimport urlparse
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Workerdef GetPlatformName():
19*8975f5c5SAndroid Build Coastguard Worker  """Return a string to be used in paths for the platform."""
20*8975f5c5SAndroid Build Coastguard Worker  if IsWindows():
21*8975f5c5SAndroid Build Coastguard Worker    return 'win'
22*8975f5c5SAndroid Build Coastguard Worker  if IsMac():
23*8975f5c5SAndroid Build Coastguard Worker    return 'mac'
24*8975f5c5SAndroid Build Coastguard Worker  if IsLinux():
25*8975f5c5SAndroid Build Coastguard Worker    return 'linux'
26*8975f5c5SAndroid Build Coastguard Worker  raise NotImplementedError('Unknown platform "%s".' % sys.platform)
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Workerdef IsWindows():
30*8975f5c5SAndroid Build Coastguard Worker  return sys.platform == 'cygwin' or sys.platform.startswith('win')
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Workerdef IsLinux():
34*8975f5c5SAndroid Build Coastguard Worker  return sys.platform.startswith('linux')
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Workerdef IsMac():
38*8975f5c5SAndroid Build Coastguard Worker  return sys.platform.startswith('darwin')
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Workerdef _DeleteDir(path):
42*8975f5c5SAndroid Build Coastguard Worker  """Deletes a directory recursively, which must exist."""
43*8975f5c5SAndroid Build Coastguard Worker  # Don't use shutil.rmtree because it can't delete read-only files on Win.
44*8975f5c5SAndroid Build Coastguard Worker  for root, dirs, files in os.walk(path, topdown=False):
45*8975f5c5SAndroid Build Coastguard Worker    for name in files:
46*8975f5c5SAndroid Build Coastguard Worker      filename = os.path.join(root, name)
47*8975f5c5SAndroid Build Coastguard Worker      os.chmod(filename, stat.S_IWRITE)
48*8975f5c5SAndroid Build Coastguard Worker      os.remove(filename)
49*8975f5c5SAndroid Build Coastguard Worker    for name in dirs:
50*8975f5c5SAndroid Build Coastguard Worker      os.rmdir(os.path.join(root, name))
51*8975f5c5SAndroid Build Coastguard Worker  os.rmdir(path)
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker
54*8975f5c5SAndroid Build Coastguard Workerdef Delete(path):
55*8975f5c5SAndroid Build Coastguard Worker  """Deletes the given file or directory (recursively), which must exist."""
56*8975f5c5SAndroid Build Coastguard Worker  if os.path.isdir(path):
57*8975f5c5SAndroid Build Coastguard Worker    _DeleteDir(path)
58*8975f5c5SAndroid Build Coastguard Worker  else:
59*8975f5c5SAndroid Build Coastguard Worker    os.remove(path)
60*8975f5c5SAndroid Build Coastguard Worker
61*8975f5c5SAndroid Build Coastguard Worker
62*8975f5c5SAndroid Build Coastguard Workerdef MaybeDelete(path):
63*8975f5c5SAndroid Build Coastguard Worker  """Deletes the given file or directory (recurisvely), if it exists."""
64*8975f5c5SAndroid Build Coastguard Worker  if os.path.exists(path):
65*8975f5c5SAndroid Build Coastguard Worker    Delete(path)
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Workerdef MakeTempDir(parent_dir=None):
69*8975f5c5SAndroid Build Coastguard Worker  """Creates a temporary directory and returns an absolute path to it.
70*8975f5c5SAndroid Build Coastguard Worker
71*8975f5c5SAndroid Build Coastguard Worker  The temporary directory is automatically deleted when the python interpreter
72*8975f5c5SAndroid Build Coastguard Worker  exits normally.
73*8975f5c5SAndroid Build Coastguard Worker
74*8975f5c5SAndroid Build Coastguard Worker  Args:
75*8975f5c5SAndroid Build Coastguard Worker    parent_dir: the directory to create the temp dir in. If None, the system
76*8975f5c5SAndroid Build Coastguard Worker                temp dir is used.
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker  Returns:
79*8975f5c5SAndroid Build Coastguard Worker    The absolute path to the temporary directory.
80*8975f5c5SAndroid Build Coastguard Worker  """
81*8975f5c5SAndroid Build Coastguard Worker  path = tempfile.mkdtemp(dir=parent_dir)
82*8975f5c5SAndroid Build Coastguard Worker  atexit.register(MaybeDelete, path)
83*8975f5c5SAndroid Build Coastguard Worker  return path
84*8975f5c5SAndroid Build Coastguard Worker
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Workerdef Unzip(zip_path, output_dir):
87*8975f5c5SAndroid Build Coastguard Worker  """Unzips the given zip file using a system installed unzip tool.
88*8975f5c5SAndroid Build Coastguard Worker
89*8975f5c5SAndroid Build Coastguard Worker  Args:
90*8975f5c5SAndroid Build Coastguard Worker    zip_path: zip file to unzip.
91*8975f5c5SAndroid Build Coastguard Worker    output_dir: directory to unzip the contents of the zip file. The directory
92*8975f5c5SAndroid Build Coastguard Worker                must exist.
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker  Raises:
95*8975f5c5SAndroid Build Coastguard Worker    RuntimeError if the unzip operation fails.
96*8975f5c5SAndroid Build Coastguard Worker  """
97*8975f5c5SAndroid Build Coastguard Worker  if IsWindows():
98*8975f5c5SAndroid Build Coastguard Worker    unzip_cmd = ['C:\\Program Files\\7-Zip\\7z.exe', 'x', '-y']
99*8975f5c5SAndroid Build Coastguard Worker  else:
100*8975f5c5SAndroid Build Coastguard Worker    unzip_cmd = ['unzip', '-o']
101*8975f5c5SAndroid Build Coastguard Worker  unzip_cmd += [zip_path]
102*8975f5c5SAndroid Build Coastguard Worker  if RunCommand(unzip_cmd, output_dir) != 0:
103*8975f5c5SAndroid Build Coastguard Worker    raise RuntimeError('Unable to unzip %s to %s' % (zip_path, output_dir))
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Workerdef Kill(pid):
107*8975f5c5SAndroid Build Coastguard Worker  """Terminate the given pid."""
108*8975f5c5SAndroid Build Coastguard Worker  if IsWindows():
109*8975f5c5SAndroid Build Coastguard Worker    subprocess.call(['taskkill.exe', '/T', '/F', '/PID', str(pid)])
110*8975f5c5SAndroid Build Coastguard Worker  else:
111*8975f5c5SAndroid Build Coastguard Worker    os.kill(pid, signal.SIGTERM)
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Workerdef RunCommand(cmd, cwd=None):
115*8975f5c5SAndroid Build Coastguard Worker  """Runs the given command and returns the exit code.
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker  Args:
118*8975f5c5SAndroid Build Coastguard Worker    cmd: list of command arguments.
119*8975f5c5SAndroid Build Coastguard Worker    cwd: working directory to execute the command, or None if the current
120*8975f5c5SAndroid Build Coastguard Worker         working directory should be used.
121*8975f5c5SAndroid Build Coastguard Worker
122*8975f5c5SAndroid Build Coastguard Worker  Returns:
123*8975f5c5SAndroid Build Coastguard Worker    The exit code of the command.
124*8975f5c5SAndroid Build Coastguard Worker  """
125*8975f5c5SAndroid Build Coastguard Worker  process = subprocess.Popen(cmd, cwd=cwd)
126*8975f5c5SAndroid Build Coastguard Worker  process.wait()
127*8975f5c5SAndroid Build Coastguard Worker  return process.returncode
128*8975f5c5SAndroid Build Coastguard Worker
129*8975f5c5SAndroid Build Coastguard Worker
130*8975f5c5SAndroid Build Coastguard Workerdef DoesUrlExist(url):
131*8975f5c5SAndroid Build Coastguard Worker  """Determines whether a resource exists at the given URL.
132*8975f5c5SAndroid Build Coastguard Worker
133*8975f5c5SAndroid Build Coastguard Worker  Args:
134*8975f5c5SAndroid Build Coastguard Worker    url: URL to be verified.
135*8975f5c5SAndroid Build Coastguard Worker
136*8975f5c5SAndroid Build Coastguard Worker  Returns:
137*8975f5c5SAndroid Build Coastguard Worker    True if url exists, otherwise False.
138*8975f5c5SAndroid Build Coastguard Worker  """
139*8975f5c5SAndroid Build Coastguard Worker  parsed = urlparse.urlparse(url)
140*8975f5c5SAndroid Build Coastguard Worker  try:
141*8975f5c5SAndroid Build Coastguard Worker    conn = httplib.HTTPConnection(parsed.netloc)
142*8975f5c5SAndroid Build Coastguard Worker    conn.request('HEAD', parsed.path)
143*8975f5c5SAndroid Build Coastguard Worker    response = conn.getresponse()
144*8975f5c5SAndroid Build Coastguard Worker  except (socket.gaierror, socket.error):
145*8975f5c5SAndroid Build Coastguard Worker    return False
146*8975f5c5SAndroid Build Coastguard Worker  finally:
147*8975f5c5SAndroid Build Coastguard Worker    conn.close()
148*8975f5c5SAndroid Build Coastguard Worker  # Follow both permanent (301) and temporary (302) redirects.
149*8975f5c5SAndroid Build Coastguard Worker  if response.status == 302 or response.status == 301:
150*8975f5c5SAndroid Build Coastguard Worker    return DoesUrlExist(response.getheader('location'))
151*8975f5c5SAndroid Build Coastguard Worker  return response.status == 200
152