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

Side by Side Diff: build/android/gyp/util/md5_check.py

Issue 1312483002: Add an environment variable that will cause md5_check.py to write .stamp file that is debuggable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: use colorama Created 5 years, 3 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import difflib
5 import hashlib 6 import hashlib
6 import os 7 import os
8 import re
9
10
11 # When set and a difference is detected, a diff of what changed is printed.
12 _PRINT_MD5_DIFFS = int(os.environ.get('PRINT_MD5_DIFFS', 0))
13
14 # Used to strip off temp dir prefix.
15 _TEMP_DIR_PATTERN = re.compile(r'^/tmp/.*?/')
7 16
8 17
9 def CallAndRecordIfStale( 18 def CallAndRecordIfStale(
10 function, record_path=None, input_paths=None, input_strings=None, 19 function, record_path=None, input_paths=None, input_strings=None,
11 force=False): 20 force=False):
12 """Calls function if the md5sum of the input paths/strings has changed. 21 """Calls function if the md5sum of the input paths/strings has changed.
13 22
14 The md5sum of the inputs is compared with the one stored in record_path. If 23 The md5sum of the inputs is compared with the one stored in record_path. If
15 this has changed (or the record doesn't exist), function will be called and 24 this has changed (or the record doesn't exist), function will be called and
16 the new md5sum will be recorded. 25 the new md5sum will be recorded.
17 26
18 If force is True, the function will be called regardless of whether the 27 If force is True, the function will be called regardless of whether the
19 md5sum is out of date. 28 md5sum is out of date.
20 """ 29 """
21 if not input_paths: 30 if not input_paths:
22 input_paths = [] 31 input_paths = []
23 if not input_strings: 32 if not input_strings:
24 input_strings = [] 33 input_strings = []
25 md5_checker = _Md5Checker( 34 md5_checker = _Md5Checker(
26 record_path=record_path, 35 record_path=record_path,
27 input_paths=input_paths, 36 input_paths=input_paths,
28 input_strings=input_strings) 37 input_strings=input_strings)
29 if force or md5_checker.IsStale(): 38
39 is_stale = md5_checker.old_digest != md5_checker.new_digest
40 if force or is_stale:
41 if is_stale and _PRINT_MD5_DIFFS:
42 import sys
jbudorick 2015/09/02 01:13:50 I would rather avoid local imports. I don't know o
agrieve 2015/09/02 15:01:08 Done.
43 from util import build_utils
44 if build_utils.COLORAMA_ROOT not in sys.path:
45 sys.path.append(build_utils.COLORAMA_ROOT)
46 import colorama
47
48 print '%sDifference found in %s:%s' % (
49 colorama.Fore.YELLOW, record_path, colorama.Fore.RESET)
50 print md5_checker.DescribeDifference()
30 function() 51 function()
31 md5_checker.Write() 52 md5_checker.Write()
32 53
33 54
34 def _UpdateMd5ForFile(md5, path, block_size=2**16): 55 def _UpdateMd5ForFile(md5, path, block_size=2**16):
35 with open(path, 'rb') as infile: 56 with open(path, 'rb') as infile:
36 while True: 57 while True:
37 data = infile.read(block_size) 58 data = infile.read(block_size)
38 if not data: 59 if not data:
39 break 60 break
40 md5.update(data) 61 md5.update(data)
41 62
42 63
43 def _UpdateMd5ForDirectory(md5, dir_path): 64 def _UpdateMd5ForDirectory(md5, dir_path):
44 for root, _, files in os.walk(dir_path): 65 for root, _, files in os.walk(dir_path):
45 for f in files: 66 for f in files:
46 _UpdateMd5ForFile(md5, os.path.join(root, f)) 67 _UpdateMd5ForFile(md5, os.path.join(root, f))
47 68
48 69
49 def _UpdateMd5ForPath(md5, path): 70 def _UpdateMd5ForPath(md5, path):
50 if os.path.isdir(path): 71 if os.path.isdir(path):
51 _UpdateMd5ForDirectory(md5, path) 72 _UpdateMd5ForDirectory(md5, path)
52 else: 73 else:
53 _UpdateMd5ForFile(md5, path) 74 _UpdateMd5ForFile(md5, path)
54 75
55 76
77 def _TrimPathPrefix(path):
78 """Attempts to remove temp dir prefix from the path.
79
80 Use this only for extended_info (not for the actual md5).
81 """
82 return _TEMP_DIR_PATTERN.sub('{TMP}', path)
83
84
56 class _Md5Checker(object): 85 class _Md5Checker(object):
57 def __init__(self, record_path=None, input_paths=None, input_strings=None): 86 def __init__(self, record_path=None, input_paths=None, input_strings=None):
58 if not input_paths: 87 if not input_paths:
59 input_paths = [] 88 input_paths = []
60 if not input_strings: 89 if not input_strings:
61 input_strings = [] 90 input_strings = []
62 91
63 assert record_path.endswith('.stamp'), ( 92 assert record_path.endswith('.stamp'), (
64 'record paths must end in \'.stamp\' so that they are easy to find ' 93 'record paths must end in \'.stamp\' so that they are easy to find '
65 'and delete') 94 'and delete')
66 95
67 self.record_path = record_path 96 self.record_path = record_path
68 97
69 md5 = hashlib.md5() 98 extended_info = []
99 outer_md5 = hashlib.md5()
70 for i in sorted(input_paths): 100 for i in sorted(input_paths):
71 _UpdateMd5ForPath(md5, i) 101 inner_md5 = hashlib.md5()
102 _UpdateMd5ForPath(inner_md5, i)
103 i = _TrimPathPrefix(i)
104 extended_info.append(i + '=' + inner_md5.hexdigest())
105 # Include the digest in the overall diff, but not the path
106 outer_md5.update(inner_md5.hexdigest())
107
72 for s in input_strings: 108 for s in input_strings:
73 md5.update(s) 109 outer_md5.update(s)
74 self.new_digest = md5.hexdigest() 110 extended_info.append(s)
111
112 self.new_digest = outer_md5.hexdigest()
113 self.new_extended_info = extended_info
75 114
76 self.old_digest = '' 115 self.old_digest = ''
116 self.old_extended_info = []
77 if os.path.exists(self.record_path): 117 if os.path.exists(self.record_path):
78 with open(self.record_path, 'r') as old_record: 118 with open(self.record_path, 'r') as old_record:
79 self.old_digest = old_record.read() 119 self.old_extended_info = [line.strip() for line in old_record]
80 120 self.old_digest = self.old_extended_info.pop(0)
81 def IsStale(self):
82 return self.old_digest != self.new_digest
83 121
84 def Write(self): 122 def Write(self):
85 with open(self.record_path, 'w') as new_record: 123 with open(self.record_path, 'w') as new_record:
86 new_record.write(self.new_digest) 124 new_record.write(self.new_digest)
125 new_record.write('\n' + '\n'.join(self.new_extended_info) + '\n')
126
127 def DescribeDifference(self):
128 if self.old_digest == self.new_digest:
129 return "There's no difference"
jbudorick 2015/09/02 01:13:50 supernit: "... difference."
agrieve 2015/09/02 15:01:08 Done.
130 if not self.old_digest:
131 return 'Previous stamp file not found.'
132 if not self.old_extended_info:
133 return 'Previous stamp file lacks extended info.'
134 diff = difflib.unified_diff(self.old_extended_info, self.new_extended_info)
135 return '\n'.join(diff)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698