-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
diff.py
104 lines (90 loc) · 5.49 KB
/
diff.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ====================================================
# Copyright 2018 Christopher Simpkins
# MIT License
# ====================================================
import os
import sys
from git import Repo
from ufodiff.utilities.ufo import Ufo
class Diff(object):
"""
Diff class performs git diff on repository with filters for the UFO specification, cleans diff reports for
improved readability and prepends branch names to the report for branch vs. branch analyses. Supports git diff
reports with ANSI color codes and without ANSI color codes.
:param gitrepo_path: (string) path to root of git repository
:param color_diff: (boolean) indicator for request for color diff (True) or uncolored diff (False)
"""
def __init__(self, gitrepo_path, color_diff=False):
self.gitrepo_path = gitrepo_path # root path for git repository
self.is_color_diff = color_diff # is request for color diff = True
self.repo = Repo(self.gitrepo_path) # GitPython Repo object
self.git = self.repo.git # GitPython Repo.git object
self.ufo = Ufo() # ufodiff.utilities.ufo.Ufo object
self.current_branch = self.git.rev_parse('--abbrev-ref', 'HEAD') # current git branch automatically detected
# PRIVATE METHODS
def _clean_diff_string(self, dirty_diff_string):
"""
'Cleans' the raw git diff string to improve readability and eliminate data that was not felt to be warranted in
ufodiff text diff reports.
:param dirty_diff_string: (string) the raw git diff string
:return: (string) the cleaned git diff string
"""
dirty_diffstring_list = dirty_diff_string.split('\n')
clean_diff_string = ""
for a_string in dirty_diffstring_list:
if a_string.startswith("\x1b[1mdiff --git") or a_string.startswith("diff --git"):
clean_a_string = a_string.replace('diff --git', '')
clean_a_string = clean_a_string.replace(' ', os.linesep)
clean_diff_string += clean_a_string + os.linesep
elif '100644' in a_string:
clean_a_string = a_string.replace('100644', '')
clean_a_string = clean_a_string.replace('mode', '')
clean_diff_string += clean_a_string + os.linesep
else:
clean_diff_string += a_string + os.linesep
# remove two lead lines from text diffs (unnecessary duplication of the two files)
if "---" in clean_diff_string and "+++" in clean_diff_string:
clean_diff_string_list = clean_diff_string.split(os.linesep)
purged_head_paths_diff_string_list = clean_diff_string_list[3:]
clean_diff_string = "" # reset the diff string to empty string and start again
for line in purged_head_paths_diff_string_list:
clean_diff_string += line + os.linesep
return clean_diff_string
# PUBLIC METHODS
def get_diff_string_generator(self, git_user_diff_string):
"""
Creates a Python generator that returns individual diff reports for filepaths that match UFO spec filters.
Generator used as the creation of diff string across large numbers of *.glif file changes can take time to
create.
:param git_user_diff_string: (string) the string provided as third argument in user command (ufodiff diff [arg3])
:return: (Python generator of strings) iterable list of diff text strings intended for standard output
"""
ufo_file_list = self.ufo.get_valid_file_filterlist_for_diff() # valid UFO files
is_branch_test = False # default is a test between commits, not a test between branches, modified below
if git_user_diff_string.startswith("commits:"):
commits_list = git_user_diff_string.split(":")
commits_number = commits_list[1]
diff_arg_string = "HEAD~" + commits_number
elif git_user_diff_string.startswith("branch:"):
is_branch_test = True
diff_arg_string = git_user_diff_string[7:] + ".." + self.current_branch
else:
diff_arg_string = git_user_diff_string
if self.is_color_diff is True:
for ufo_file in ufo_file_list:
dirty_diff_string = self.git.diff(diff_arg_string, '--minimal', '--color', '--', ufo_file)
cleaned_diff_string = self._clean_diff_string(dirty_diff_string)
if len(cleaned_diff_string) > 1: # eliminates diff filters that did not include identified files
if is_branch_test is True:
cleaned_diff_string = "branch " + diff_arg_string + os.linesep + cleaned_diff_string
yield cleaned_diff_string
else:
for ufo_file in ufo_file_list:
dirty_diff_string = self.git.diff(diff_arg_string, '--minimal', '--', ufo_file)
cleaned_diff_string = self._clean_diff_string(dirty_diff_string)
if len(cleaned_diff_string) > 1: # eliminates diff filters that did not include identified files
if is_branch_test is True: # add branch descriptions to the output from the diff
cleaned_diff_string = "branch " + diff_arg_string + os.linesep + cleaned_diff_string
yield cleaned_diff_string