Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: tools/isolate/tree_creator.py

Issue 9638020: Refactor isolate.py to be more functional and extensible (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More extensive testing, saner mode saving, etc Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« tools/isolate/isolate_test.py ('K') | « tools/isolate/isolate_test.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/isolate/tree_creator.py
diff --git a/tools/isolate/tree_creator.py b/tools/isolate/tree_creator.py
index 3c7e0c235d0bc978cf3666dd1d13efdd8d72098f..ad0990cc63d6d7ec0c5705924e34db4d3ab7e8aa 100644
--- a/tools/isolate/tree_creator.py
+++ b/tools/isolate/tree_creator.py
@@ -2,13 +2,20 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""Creates a tree of hardlinks, symlinks or copy the inputs files."""
+"""File related utility functions.
+
+Creates a tree of hardlinks, symlinks or copy the inputs files. Calculate files
+hash.
+"""
import ctypes
+import hashlib
import logging
import os
import shutil
+import stat
import sys
+import time
# Types of action accepted by recreate_tree().
@@ -30,20 +37,9 @@ def os_link(source, link_name):
os.link(source, link_name)
-def preprocess_inputs(indir, infiles, blacklist):
- """Reads the infiles and expands the directories and applies the blacklist.
-
- Returns the normalized indir and infiles. Converts infiles with a trailing
- slash as the list of its files.
- """
- logging.debug('preprocess_inputs(%s, %s, %s)' % (indir, infiles, blacklist))
- # Both need to be a local path.
- indir = os.path.normpath(indir)
- if not os.path.isdir(indir):
- raise MappingError('%s is not a directory' % indir)
-
- # Do not call abspath until it was verified the directory exists.
- indir = os.path.abspath(indir)
+def expand_directories(indir, infiles, blacklist):
+ """Expands the directories, applies the blacklist and verifies files exist."""
+ logging.debug('expand_directories(%s, %s, %s)' % (indir, infiles, blacklist))
outfiles = []
for relfile in infiles:
if os.path.isabs(relfile):
@@ -68,10 +64,40 @@ def preprocess_inputs(indir, infiles, blacklist):
if not os.path.isfile(infile):
raise MappingError('Input file %s doesn\'t exist' % infile)
outfiles.append(relfile)
- return outfiles, indir
+ return outfiles
-def process_file(outfile, infile, action):
+def process_inputs(indir, infiles, need_hash, read_only):
+ """Returns a dictionary of input files, populated with the files' mode and
+ hash.
+
+ The file mode is manipulated if read_only is True. In practice, we only save
+ one of 4 modes: 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r).
+ """
+ outdict = {}
+ for infile in infiles:
+ filepath = os.path.join(indir, infile)
+ filemode = stat.S_IMODE(os.stat(filepath).st_mode)
+ # Remove write access for non-owner.
+ filemode &= ~(stat.S_IWGRP | stat.S_IWOTH)
+ if read_only:
+ filemode &= ~stat.S_IWUSR
+ if filemode & stat.S_IXUSR:
+ filemode |= (stat.S_IXGRP | stat.S_IXOTH)
+ else:
+ filemode &= ~(stat.S_IXGRP | stat.S_IXOTH)
+ outdict[infile] = {
+ 'mode': filemode,
+ }
+ if need_hash:
+ h = hashlib.sha1()
+ with open(filepath, 'rb') as f:
+ h.update(f.read())
+ outdict[infile]['sha-1'] = h.hexdigest()
+ return outdict
+
+
+def link_file(outfile, infile, action):
"""Links a file. The type of link depends on |action|."""
logging.debug('Mapping %s to %s' % (infile, outfile))
if os.path.isfile(outfile):
@@ -98,10 +124,9 @@ def recreate_tree(outdir, indir, infiles, action):
"""Creates a new tree with only the input files in it.
Arguments:
- outdir: Temporary directory to create the files in.
+ outdir: Output directory to create the files in.
indir: Root directory the infiles are based in.
- infiles: List of files to map from |indir| to |outdir|. Must have been
- sanitized with preprocess_inputs().
+ infiles: List of files to map from |indir| to |outdir|.
action: See assert below.
"""
logging.debug(
@@ -122,7 +147,7 @@ def recreate_tree(outdir, indir, infiles, action):
outsubdir = os.path.dirname(outfile)
if not os.path.isdir(outsubdir):
os.makedirs(outsubdir)
- process_file(outfile, infile, action)
+ link_file(outfile, infile, action)
def _set_write_bit(path, read_only):
@@ -148,3 +173,19 @@ def make_writable(root, read_only):
for dirname in dirnames:
_set_write_bit(os.path.join(dirpath, dirname), read_only)
+
+
+def rmtree(root):
+ """Wrapper around shutil.rmtree() to retry automatically on Windows."""
+ if sys.platform == 'win32':
+ for i in range(3):
+ try:
+ shutil.rmtree(root)
+ break
+ except WindowsError: # pylint: disable=E0602
+ delay = (i+1)*2
+ print >> sys.stderr, (
+ 'The test has subprocess outliving it. Sleep %d seconds.' % delay)
+ time.sleep(delay)
+ else:
+ shutil.rmtree(root)
« tools/isolate/isolate_test.py ('K') | « tools/isolate/isolate_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698