port python2.x code to python3.x
[tools/itest-core.git] / imgdiff / diff.py
1 #!/usr/bin/env python
2 '''This script parse diff result from stdin filter out trivial differences
3 defined in config file and print out the left
4 '''
5 import re
6 import os
7 import sys
8 import argparse
9
10
11 from imgdiff.trivial import Conf, Rules
12 from imgdiff.unified import parse
13
14
15 PATTERN_PREFIX = re.compile(r'.*?img[12](%(sep)sroot)?(%(sep)s.*)' %
16                             {'sep': os.path.sep})
17
18
19 def strip_prefix(filename):
20     '''Strip prefix added by imgdiff script.
21     For example:
22     img1/partition_table.txt -> partition_table.txt
23     img1/root/tmp/file -> /tmp/file
24     '''
25     match = PATTERN_PREFIX.match(filename)
26     return match.group(2) if match else filename
27
28
29 def fix_filename(onefile):
30     '''Fix filename'''
31     onefile['filename'] = strip_prefix(onefile['filename'])
32     return onefile
33
34
35 class Mark(object):
36     '''Mark one file and its content as nontrivial
37     '''
38     def __init__(self, conf_filename):
39         self.rules = Rules(Conf.load(conf_filename))
40
41     def __call__(self, onefile):
42         self.rules.check_and_mark(onefile)
43         return onefile
44
45
46 def nontrivial(onefile):
47     '''Filter out nontrivial'''
48     return not('ignore' in onefile and onefile['ignore'])
49
50
51 def parse_and_mark(stream, conf_filename=None):
52     '''
53     Parse diff from stream and mark nontrivial defined
54     by conf_filename
55     '''
56     stream = parse(stream)
57     stream = map(fix_filename, stream)
58
59     if conf_filename:
60         mark_trivial = Mark(conf_filename)
61         stream = map(mark_trivial, stream)
62     return stream
63
64
65 def parse_args():
66     '''parse arguments'''
67     parser = argparse.ArgumentParser()
68     parser.add_argument('-c', '--conf-filename',
69                         help='conf for defining unimportant difference')
70     return parser.parse_args()
71
72
73 def main():
74     "Main"
75     args = parse_args()
76     stream = parse_and_mark(sys.stdin, args.conf_filename)
77     stream = filter(nontrivial, stream)
78     cnt = 0
79     for each in stream:
80         print(each)
81         cnt += 1
82     return cnt
83
84
85 if __name__ == '__main__':
86     try:
87         sys.exit(main())
88     except Exception:
89         # normally python exit 1 for exception
90         # we change it to 255 to avoid confusion with 1 difference
91         import traceback
92         traceback.print_exc()
93         sys.exit(255)