2828import os
2929from collections import OrderedDict
3030
31- from deltacode .models import File
32- from deltacode .models import Scan
3331from deltacode import utils
32+ from deltacode .exceptions import FileError as FileError
3433from commoncode import paths
3534from commoncode .resource import VirtualCodebase
3635
36+
3737from pkg_resources import get_distribution , DistributionNotFound
3838
3939try :
@@ -59,29 +59,31 @@ def __init__(self, new_path, old_path, options):
5959 self .deltas = []
6060 self .errors = []
6161
62- try :
62+ if os . path . isfile ( new_path ) and os . path . isfile ( old_path ) :
6363 self .codebase1 = VirtualCodebase (new_path )
6464 self .codebase2 = VirtualCodebase (old_path )
6565
66- except Exception as exception :
67- print (str (exception ))
68- self .errors .append (str (exception ))
69-
70- if self .codebase1 is not None or self .codebase2 is not None :
71- self .stats = Stat (
72- self .codebase1 .compute_counts (), self .codebase2 .compute_counts ()
66+ else :
67+ error_message = (
68+ "{} is expected to be a file" .format (new_path )
69+ if not os .path .isfile (new_path )
70+ else "{} is expected to be a file" .format (old_path )
7371 )
74- self .new_files_errors = []
75- self .old_files_errors = []
76- self .determine_delta ()
77- self .license_diff ()
78- self .copyright_diff ()
79- self .stats .calculate_stats ()
80- self .similarity ()
81- # Sort deltas by score, descending, i.e., high > low, and then by
82- # factors, alphabetically. Run the least significant sort first.
83- self .deltas .sort (key = lambda Delta : Delta .factors , reverse = False )
84- self .deltas .sort (key = lambda Delta : Delta .score , reverse = True )
72+ raise FileError (error_message )
73+ self .stats = Stat (
74+ self .codebase1 .compute_counts (), self .codebase2 .compute_counts ()
75+ )
76+ self .new_files_errors = []
77+ self .old_files_errors = []
78+ self .determine_delta ()
79+ self .license_diff ()
80+ self .copyright_diff ()
81+ self .stats .calculate_stats ()
82+ self .similarity ()
83+ # Sort deltas by score, descending, i.e., high > low, and then by
84+ # factors, alphabetically. Run the least significant sort first.
85+ self .deltas .sort (key = lambda Delta : Delta .factors , reverse = False )
86+ self .deltas .sort (key = lambda Delta : Delta .score , reverse = True )
8587
8688 def similarity (self ):
8789 """
@@ -94,18 +96,22 @@ def similarity(self):
9496 for delta in self .deltas :
9597 if delta .new_file == None or delta .old_file == None :
9698 continue
97- new_fingerprint = delta .new_file .fingerprint if hasattr (delta .new_file , "fingerprint" ) else None
98- old_fingerprint = delta .old_file .fingerprint if hasattr (delta .old_file , "fingerprint" ) else None
99-
100- if new_fingerprint == None or old_fingerprint == None :
101- continue
102- new_fingerprint = utils .bitarray_from_hex (
99+ new_fingerprint = (
103100 delta .new_file .fingerprint
101+ if hasattr (delta .new_file , "fingerprint" )
102+ else None
104103 )
105- old_fingerprint = utils . bitarray_from_hex (
104+ old_fingerprint = (
106105 delta .old_file .fingerprint
106+ if hasattr (delta .old_file , "fingerprint" )
107+ else None
107108 )
108109
110+ if new_fingerprint == None or old_fingerprint == None :
111+ continue
112+ new_fingerprint = utils .bitarray_from_hex (delta .new_file .fingerprint )
113+ old_fingerprint = utils .bitarray_from_hex (delta .old_file .fingerprint )
114+
109115 hamming_distance = utils .hamming_distance (new_fingerprint , old_fingerprint )
110116 if hamming_distance > 0 and hamming_distance <= SIMILARITY_LIMIT :
111117 delta .score += hamming_distance
@@ -127,7 +133,7 @@ def determine_delta(self):
127133 from either scan.
128134 """
129135
130- old_files_sha1_considered_in_deltas = dict ()
136+ old_resource_considered = dict ()
131137 try :
132138 Delta .NEW_CODEBASE_OFFSET , Delta .OLD_CODEBASE_OFFSET = utils .align_trees (
133139 self .codebase1 , self .codebase2
@@ -140,22 +146,37 @@ def determine_delta(self):
140146 path_new = "/" .join (
141147 paths .split (new_resource .path )[Delta .NEW_CODEBASE_OFFSET :]
142148 )
149+
150+ old_resource = self .codebase2 .get_resource_from_path (path_new )
151+
152+ if old_resource and old_resource .sha1 == new_resource .sha1 :
153+ old_resource_considered [old_resource .path ] = 1
154+ path_old = "/" .join (
155+ paths .split (old_resource .path )[Delta .OLD_CODEBASE_OFFSET :]
156+ )
157+ self .create_deltas (
158+ new_resource , old_resource , path_new , path_old , 0 , "unmodified" ,
159+ )
160+ self .stats .num_unmodified += 1
161+
162+ continue
163+
143164 ADDED = True
144165 for old_resource in self .codebase2 .walk ():
166+ if old_resource .path in old_resource_considered .keys ():
167+ continue
168+ path_old = "/" .join (
169+ paths .split (old_resource .path )[Delta .OLD_CODEBASE_OFFSET :]
170+ )
145171 if (
146172 old_resource .is_file
147- and not old_resource .sha1
148- in old_files_sha1_considered_in_deltas .keys ()
173+ and not old_resource .path in old_resource_considered .keys ()
149174 ):
150- path_old = "/" .join (
151- paths .split (old_resource .path )[Delta .OLD_CODEBASE_OFFSET :]
152- )
175+
153176 if path_new == path_old :
154177 ADDED = False
155178 if new_resource .sha1 == old_resource .sha1 :
156- old_files_sha1_considered_in_deltas [
157- old_resource .sha1
158- ] = 1
179+ old_resource_considered [old_resource .path ] = 1
159180 self .create_deltas (
160181 new_resource ,
161182 old_resource ,
@@ -167,9 +188,7 @@ def determine_delta(self):
167188 self .stats .num_unmodified += 1
168189 break
169190 else :
170- old_files_sha1_considered_in_deltas [
171- old_resource .sha1
172- ] = 1
191+ old_resource_considered [old_resource .path ] = 1
173192 self .create_deltas (
174193 new_resource ,
175194 old_resource ,
@@ -182,9 +201,7 @@ def determine_delta(self):
182201 break
183202 else :
184203 if new_resource .sha1 == old_resource .sha1 :
185- old_files_sha1_considered_in_deltas [
186- old_resource .sha1
187- ] = 1
204+ old_resource_considered [old_resource .path ] = 1
188205 ADDED = False
189206 self .create_deltas (
190207 new_resource ,
@@ -199,33 +216,22 @@ def determine_delta(self):
199216
200217 if ADDED :
201218 self .create_deltas (
202- new_resource ,
203- None ,
204- path_new ,
205- None ,
206- 100 ,
207- "added" ,
219+ new_resource , None , path_new , None , 100 , "added" ,
208220 )
209221 self .stats .num_added += 1
210222
211223 for old_resource_remaining in self .codebase2 .walk ():
212224 if (
213225 old_resource_remaining .is_file
214- and old_resource_remaining .sha1
215- not in old_files_sha1_considered_in_deltas .keys ()
226+ and old_resource_remaining .path not in old_resource_considered .keys ()
216227 ):
217228 path_old = "/" .join (
218229 paths .split (old_resource_remaining .path )[
219230 Delta .OLD_CODEBASE_OFFSET :
220231 ]
221232 )
222233 self .create_deltas (
223- None ,
224- old_resource_remaining ,
225- None ,
226- path_old ,
227- 0 ,
228- "removed" ,
234+ None , old_resource_remaining , None , path_old , 0 , "removed" ,
229235 )
230236 self .stats .num_removed += 1
231237
@@ -368,7 +374,7 @@ def licenses_to_dict(self, file):
368374 return []
369375
370376 def file_to_dict (self , deltacode , file , new_file = True ):
371-
377+
372378 path_offset = (
373379 Delta .NEW_CODEBASE_OFFSET if new_file else Delta .OLD_CODEBASE_OFFSET
374380 )
@@ -380,7 +386,10 @@ def file_to_dict(self, deltacode, file, new_file=True):
380386 ("name" , file .name ),
381387 ("size" , file .size ),
382388 ("sha1" , file .sha1 ),
383- ("fingerprint" , file .fingerprint if hasattr (file , "fingerprint" ) else "" ),
389+ (
390+ "fingerprint" ,
391+ file .fingerprint if hasattr (file , "fingerprint" ) else "" ,
392+ ),
384393 ("original_path" , file .path ),
385394 ("licenses" , self .licenses_to_dict (file )),
386395 ("copyrights" , self .copyrights_to_dict (file )),
@@ -392,7 +401,10 @@ def to_dict(self, deltacode):
392401 Return an OrderedDict comprising the 'factors', 'score' and new and old
393402 'path' attributes of the object.
394403 """
395- if not deltacode .options .get ("--all-delta-types" , "" ) == True and self .status == "unmodified" :
404+ if (
405+ not deltacode .options .get ("--all-delta-types" , "" ) == True
406+ and self .status == "unmodified"
407+ ):
396408 return
397409 if self .new_file :
398410 new_file = self .new_file .to_dict ()
0 commit comments