OLD | NEW |
---|---|
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 hashlib | 5 import hashlib |
6 import os | 6 import os |
7 | 7 |
8 | 8 |
9 # When set, record_path will include a per-file breakdown of md5s so that it is | |
10 # possible to see exactly which file changed. | |
11 _RECORD_EXTRA_INFO = int(os.environ.get('RECORD_EXTRA_MD5_INFO', 0)) | |
12 | |
13 | |
9 def CallAndRecordIfStale( | 14 def CallAndRecordIfStale( |
10 function, record_path=None, input_paths=None, input_strings=None, | 15 function, record_path=None, input_paths=None, input_strings=None, |
11 force=False): | 16 force=False): |
12 """Calls function if the md5sum of the input paths/strings has changed. | 17 """Calls function if the md5sum of the input paths/strings has changed. |
13 | 18 |
14 The md5sum of the inputs is compared with the one stored in record_path. If | 19 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 | 20 this has changed (or the record doesn't exist), function will be called and |
16 the new md5sum will be recorded. | 21 the new md5sum will be recorded. |
17 | 22 |
18 If force is True, the function will be called regardless of whether the | 23 If force is True, the function will be called regardless of whether the |
19 md5sum is out of date. | 24 md5sum is out of date. |
20 """ | 25 """ |
21 if not input_paths: | 26 if not input_paths: |
22 input_paths = [] | 27 input_paths = [] |
23 if not input_strings: | 28 if not input_strings: |
24 input_strings = [] | 29 input_strings = [] |
25 md5_checker = _Md5Checker( | 30 md5_checker = _Md5Checker( |
26 record_path=record_path, | 31 record_path=record_path, |
27 input_paths=input_paths, | 32 input_paths=input_paths, |
28 input_strings=input_strings) | 33 input_strings=input_strings) |
29 if force or md5_checker.IsStale(): | 34 if force or md5_checker.IsStale(): |
30 function() | 35 function() |
31 md5_checker.Write() | 36 md5_checker.Write() |
37 elif _RECORD_EXTRA_INFO: | |
38 md5_checker.Write() | |
32 | 39 |
33 | 40 |
34 def _UpdateMd5ForFile(md5, path, block_size=2**16): | 41 def _UpdateMd5ForFile(md5, path, block_size=2**16): |
35 with open(path, 'rb') as infile: | 42 with open(path, 'rb') as infile: |
36 while True: | 43 while True: |
37 data = infile.read(block_size) | 44 data = infile.read(block_size) |
38 if not data: | 45 if not data: |
39 break | 46 break |
40 md5.update(data) | 47 md5.update(data) |
41 | 48 |
(...skipping 18 matching lines...) Expand all Loading... | |
60 if not input_strings: | 67 if not input_strings: |
61 input_strings = [] | 68 input_strings = [] |
62 | 69 |
63 assert record_path.endswith('.stamp'), ( | 70 assert record_path.endswith('.stamp'), ( |
64 'record paths must end in \'.stamp\' so that they are easy to find ' | 71 'record paths must end in \'.stamp\' so that they are easy to find ' |
65 'and delete') | 72 'and delete') |
66 | 73 |
67 self.record_path = record_path | 74 self.record_path = record_path |
68 | 75 |
69 md5 = hashlib.md5() | 76 md5 = hashlib.md5() |
77 extended_info = [] | |
70 for i in sorted(input_paths): | 78 for i in sorted(input_paths): |
71 _UpdateMd5ForPath(md5, i) | 79 _UpdateMd5ForPath(md5, i) |
80 extended_info.append(i + '=' + md5.hexdigest()) | |
81 | |
72 for s in input_strings: | 82 for s in input_strings: |
73 md5.update(s) | 83 md5.update(s) |
84 extended_info.append(s) | |
85 | |
74 self.new_digest = md5.hexdigest() | 86 self.new_digest = md5.hexdigest() |
87 self.extended_info = extended_info | |
75 | 88 |
76 self.old_digest = '' | 89 self.old_digest = '' |
77 if os.path.exists(self.record_path): | 90 if os.path.exists(self.record_path): |
78 with open(self.record_path, 'r') as old_record: | 91 with open(self.record_path, 'r') as old_record: |
79 self.old_digest = old_record.read() | 92 for line in old_record: |
jbudorick
2015/08/23 02:31:01
self.old_digest = old_record.readline().strip()
?
| |
93 self.old_digest = line.strip() | |
94 break | |
80 | 95 |
81 def IsStale(self): | 96 def IsStale(self): |
82 return self.old_digest != self.new_digest | 97 return self.old_digest != self.new_digest |
83 | 98 |
84 def Write(self): | 99 def Write(self): |
85 with open(self.record_path, 'w') as new_record: | 100 with open(self.record_path, 'w') as new_record: |
86 new_record.write(self.new_digest) | 101 new_record.write(self.new_digest) |
102 if _RECORD_EXTRA_INFO: | |
103 new_record.write('\n' + '\n'.join(self.extended_info)) | |
OLD | NEW |