Passed
Push — master ( 08276c...0e1758 )
by srz
07:55 queued 01:29
created

xml2file.write_result()   A

Complexity

Conditions 5

Size

Total Lines 18
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 17
nop 4
dl 0
loc 18
rs 9.0833
c 0
b 0
f 0
1
#!/usr/bin/env python
2
#
3
# xml2file.py
4
#
5
# Copyright (C) 2019, Takazumi Shirayanagi
6
# This software is released under the new BSD License,
7
# see LICENSE
8
#
9
10
import os
11
import errno
12
import json
13
import codecs
14
import shutil
15
import xml.etree.ElementTree as ET
16
17
from argparse import ArgumentParser
18
19
# command line option
20 View Code Duplication
def parse_command_line():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
21
    parser = ArgumentParser()
22
    parser.add_argument(
23
        '-v',
24
        '--version',
25
        action='version',
26
        version=u'%(prog)s version 0.1'
27
    )
28
    parser.add_argument(
29
        '-o',
30
        '--output',
31
        default=None,
32
        help='output file path.'
33
    )
34
    parser.add_argument(
35
        '--no-time',
36
        action='store_true',
37
        help='no output time attribute'
38
    )
39
    parser.add_argument(
40
        '--verbose',
41
        action='store_true',
42
        help='log verbose'
43
    )
44
    parser.add_argument(
45
        '--encoding',
46
        default=None,
47
        help='output file encoding.'
48
    )
49
    parser.add_argument(
50
        '--debug',
51
        action='store_true',
52
        help='log debug'
53
    )
54
    parser.add_argument(
55
        'file',
56
        metavar='FILE',
57
        nargs='+',
58
        help='test result xml files'
59
    )
60
    options = parser.parse_args()
61
    return options
62
63
cmdline_options = None
64
65
66
def log(msg):
67
    if cmdline_options.verbose:
68
        print(msg)
69
70
71
def logd(msg):
72
    if cmdline_options.debug:
73
        print(msg)
74
75
76
def mkdir_p(path):
77
    try:
78
        os.makedirs(path)
79
    except OSError as exc:  # Python >2.5
80
        if exc.errno == errno.EEXIST and os.path.isdir(path):
81
            pass
82
        else:
83
            raise
84
85
86
def clean_dir(path):
87
    if os.path.exists(path):
88
        shutil.rmtree(path)
89
90
91
def fopen(path):
92
    dir = os.path.dirname(path)
93
    mkdir_p(dir)
94
    f = codecs.open(path, 'w', cmdline_options.encoding)
95
    return f
96
97
98
def make_rootpath(xml_filename, testsuites):
99
    # root_name = testsuites.attrib['name']
100
    root_name = xml_filename
101
    path = os.path.join(cmdline_options.output, root_name)
102
    return path
103
104
105
def make_path(root_path, testsuite, testcase):
106
    suite_name = testsuite.attrib['name']
107
    case_name = testcase.attrib['name']
108
    ext = '.json'
109
    return os.path.join(os.path.join(root_path, suite_name), case_name + ext)
110
111
112
def _get_user_properties(node, system_attributes):
113
    users = {}
114
    for a in node.attrib:
115
        if a not in system_attributes:
116
            users[a] = node.attrib[a]
117
    return users
118
119
120
def get_user_properties(node):
121
    system_attributes = {
122
        "testsuites": [
123
            "name", "tests", "failures", "disabled", "skip", "errors", "time", "timestamp", "random_seed"
124
        ],
125
        "testsuite": [
126
            "name", "tests", "failures", "disabled", "skip", "errors", "time", "timestamp", "random_seed"
127
        ],
128
        "testcase": [
129
            "name", "status", "time", "classname", "type_param", "value_param"
130
        ]
131
    }
132
    for k,v in system_attributes.items():
133
        if node.tag == k:
134
            return _get_user_properties(node, v)
135
    return node.attrib
136
137
138
def write_result(f, testsuites_user_attrib, testsuite_user_attrib, testcase):
139
    d = testcase.attrib
140
    if cmdline_options.no_time:
141
        if 'time' in d:
142
            del d['time']
143
    d['testsuites_attrib'] = testsuites_user_attrib
144
    d['testsuite_attrib'] = testsuite_user_attrib
145
    # failure and skipped ...
146
    for child in testcase:
147
        tag = child.tag
148
        if tag not in d:
149
            d[tag] = []
150
        fd = child.attrib
151
        fd['text'] = child.text
152
        d[tag].append(fd)
153
    jt = json.dumps(d, indent=4, ensure_ascii=False)
154
    logd(jt)
155
    f.write(jt)
156
157
158
def xml2file(path):
159
    tree = ET.parse(path)
160
    root = tree.getroot()
161
    testsuites = root
162
163
    basename = os.path.basename(path)
164
    filename = os.path.splitext(basename)[0]
165
    root_path = make_rootpath(filename, testsuites)
166
    clean_dir(root_path)
167
168
    log(basename)
169
    testsuites_user_attrib = get_user_properties(testsuites)
170
    for testsuite in testsuites:
171
        log("  " + testsuite.attrib['name'])
172
        testsuite_user_attrib = get_user_properties(testsuite)
173
        for testcase in testsuite:
174
            log("    " + testcase.attrib['name'])
175
            f = fopen(make_path(root_path, testsuite, testcase))
176
            write_result(f, testsuites_user_attrib, testsuite_user_attrib, testcase)
177
            f.close()
178
179
180
def main():
181
    global cmdline_options
182
    cmdline_options = parse_command_line()
183
    for path in cmdline_options.file:
184
        xml2file(path)
185
186
187
if __name__ == '__main__':
188
    main()
189