• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
2# reserved. Use of this source code is governed by a BSD-style license that
3# can be found in the LICENSE file.
4
5from __future__ import absolute_import
6from glob import iglob
7from io import open
8import os
9import fnmatch
10import shutil
11import sys
12import time
13
14
15def read_file(name, normalize=True):
16  """ Read a file. """
17  try:
18    with open(name, 'r', encoding='utf-8') as f:
19      # read the data
20      data = f.read()
21      if normalize:
22        # normalize line endings
23        data = data.replace("\r\n", "\n")
24      return data
25  except IOError as e:
26    (errno, strerror) = e.args
27    sys.stderr.write('Failed to read file ' + name + ': ' + strerror)
28    raise
29
30
31def write_file(name, data):
32  """ Write a file. """
33  try:
34    with open(name, 'w', encoding='utf-8') as f:
35      # write the data
36      if sys.version_info.major == 2:
37        f.write(data.decode('utf-8'))
38      else:
39        f.write(data)
40  except IOError as e:
41    (errno, strerror) = e.args
42    sys.stderr.write('Failed to write file ' + name + ': ' + strerror)
43    raise
44
45
46def path_exists(name):
47  """ Returns true if the path currently exists. """
48  return os.path.exists(name)
49
50
51def write_file_if_changed(name, data):
52  """ Write a file if the contents have changed. Returns True if the file was written. """
53  if path_exists(name):
54    old_contents = read_file(name)
55  else:
56    old_contents = ''
57
58  if (data != old_contents):
59    write_file(name, data)
60    return True
61  return False
62
63
64def backup_file(name):
65  """ Rename the file to a name that includes the current time stamp. """
66  move_file(name, name + '.' + time.strftime('%Y-%m-%d-%H-%M-%S'))
67
68
69def copy_file(src, dst, quiet=True):
70  """ Copy a file. """
71  try:
72    shutil.copy2(src, dst)
73    if not quiet:
74      sys.stdout.write('Transferring ' + src + ' file.\n')
75  except IOError as e:
76    (errno, strerror) = e.args
77    sys.stderr.write('Failed to copy file from ' + src + ' to ' + dst + ': ' +
78                     strerror)
79    raise
80
81
82def move_file(src, dst, quiet=True):
83  """ Move a file. """
84  try:
85    shutil.move(src, dst)
86    if not quiet:
87      sys.stdout.write('Moving ' + src + ' file.\n')
88  except IOError as e:
89    (errno, strerror) = e.args
90    sys.stderr.write('Failed to move file from ' + src + ' to ' + dst + ': ' +
91                     strerror)
92    raise
93
94
95def copy_files(src_glob, dst_folder, quiet=True):
96  """ Copy multiple files. """
97  for fname in iglob(src_glob):
98    dst = os.path.join(dst_folder, os.path.basename(fname))
99    if os.path.isdir(fname):
100      copy_dir(fname, dst, quiet)
101    else:
102      copy_file(fname, dst, quiet)
103
104
105def remove_file(name, quiet=True):
106  """ Remove the specified file. """
107  try:
108    if path_exists(name):
109      os.remove(name)
110      if not quiet:
111        sys.stdout.write('Removing ' + name + ' file.\n')
112  except IOError as e:
113    (errno, strerror) = e.args
114    sys.stderr.write('Failed to remove file ' + name + ': ' + strerror)
115    raise
116
117
118def copy_dir(src, dst, quiet=True):
119  """ Copy a directory tree. """
120  try:
121    remove_dir(dst, quiet)
122    shutil.copytree(src, dst)
123    if not quiet:
124      sys.stdout.write('Transferring ' + src + ' directory.\n')
125  except IOError as e:
126    (errno, strerror) = e.args
127    sys.stderr.write('Failed to copy directory from ' + src + ' to ' + dst +
128                     ': ' + strerror)
129    raise
130
131
132def remove_dir(name, quiet=True):
133  """ Remove the specified directory. """
134  try:
135    if path_exists(name):
136      shutil.rmtree(name)
137      if not quiet:
138        sys.stdout.write('Removing ' + name + ' directory.\n')
139  except IOError as e:
140    (errno, strerror) = e.args
141    sys.stderr.write('Failed to remove directory ' + name + ': ' + strerror)
142    raise
143
144
145def make_dir(name, quiet=True):
146  """ Create the specified directory. """
147  try:
148    if not path_exists(name):
149      if not quiet:
150        sys.stdout.write('Creating ' + name + ' directory.\n')
151      os.makedirs(name)
152  except IOError as e:
153    (errno, strerror) = e.args
154    sys.stderr.write('Failed to create directory ' + name + ': ' + strerror)
155    raise
156
157
158def get_files(search_glob):
159  """ Returns all files matching |search_glob|. """
160  recursive_glob = '**' + os.path.sep
161  if recursive_glob in search_glob:
162    if sys.version_info >= (3, 5):
163      result = iglob(search_glob, recursive=True)
164    else:
165      # Polyfill for recursive glob pattern matching added in Python 3.5.
166      result = get_files_recursive(*search_glob.split(recursive_glob))
167  else:
168    result = iglob(search_glob)
169
170  # Sort the result for consistency across platforms.
171  return sorted(result)
172
173
174def get_files_recursive(directory, pattern):
175  """ Returns all files in |directory| matching |pattern| recursively. """
176  for root, dirs, files in os.walk(directory):
177    for basename in files:
178      if fnmatch.fnmatch(basename, pattern):
179        filename = os.path.join(root, basename)
180        yield filename
181
182
183def read_version_file(file, args):
184  """ Read and parse a version file (key=value pairs, one per line). """
185  lines = read_file(file).split("\n")
186  for line in lines:
187    parts = line.split('=', 1)
188    if len(parts) == 2:
189      args[parts[0]] = parts[1]
190
191
192def eval_file(src):
193  """ Loads and evaluates the contents of the specified file. """
194  return eval(read_file(src), {'__builtins__': None}, None)
195
196
197def normalize_path(path):
198  """ Normalizes the path separator to match the Unix standard. """
199  if sys.platform == 'win32':
200    return path.replace('\\', '/')
201  return path
202