-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
63 lines (53 loc) · 2.53 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import json
import operator
import os
import subprocess
import sys
import tempfile
import functools
from enum import Flag, auto
class RuleType(Flag):
INFORMAL_PROPOSITION = auto()
IMPLEMENTER_AGREEMENT = auto()
ALL = INFORMAL_PROPOSITION | IMPLEMENTER_AGREEMENT
@staticmethod
def from_argv(argv):
try:
return functools.reduce(operator.or_, (v for nm, v in RuleType.__members__.items() if "--" + nm.lower().replace("_", "-") in argv))
except:
return RuleType.ALL
@functools.lru_cache(maxsize=16)
def get_remote(cwd):
return subprocess.check_output(['git', 'remote', 'get-url', 'origin'], cwd=cwd).decode('ascii').split('\n')[0]
@functools.lru_cache(maxsize=16)
def get_commits(cwd, feature_file):
return subprocess.check_output(['git', 'log', '--pretty=format:%h', feature_file], cwd=cwd).decode('ascii').split('\n')
def run(filename, instance_as_str=True, rule_type=RuleType.ALL):
cwd = os.path.dirname(__file__)
remote = get_remote(cwd)
fd, jsonfn = tempfile.mkstemp("pytest.json")
tag_filter = []
if rule_type != RuleType.ALL:
tag_filter.append(
'--tags=' + ' and '.join(['@'+nm.lower().replace("_", "-") for nm, v in RuleType.__members__.items() if v in rule_type])
)
subprocess.call([sys.executable, "-m", "behave", *tag_filter, "--define", f"input={os.path.abspath(filename)}", "-f", "json", "-o", jsonfn], cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
with open(jsonfn) as f:
log = json.load(f)
for item in log:
feature_name = item['name']
feature_file = item['location'].split(':')[0]
shas = get_commits(cwd, feature_file)
version = len(shas)
item['status'] == 'passed'
for el in item['elements']:
scenario_name = el['name']
for step in el['steps']:
step_name = step['name']
step_status = step.get('result', {}).get('status')
if step_status and step_status != 'passed':
for occurence in list(map(json.loads, step['result']['error_message'][1:])):
inst = occurence.get("inst") if instance_as_str else ((occurence["inst_id"], occurence["inst_type"]) if "inst_id" in occurence else None)
yield f"{feature_name}/{scenario_name}.v{version}", f"{remote}/blob/{shas[0]}/{feature_file}", f"{step_name}", inst, occurence["message"]
os.close(fd)
os.unlink(jsonfn)