3333import os
3434
3535from commoncode import paths
36+ from collections import OrderedDict
37+
3638
3739def update_from_license_info (delta , unique_categories ):
3840 """
@@ -53,19 +55,20 @@ def update_added_from_license_info(delta, unique_categories):
5355 one or more categories to its 'factors' attribute if there has
5456 been a license change.
5557 """
56- new_licenses = delta .new_file .licenses or []
57- new_categories = set (license .category for license in new_licenses )
58-
59- if delta .new_file .has_licenses ():
60- delta .update (20 , 'license info added' )
58+ new_licenses = (
59+ delta .new_file .licenses if hasattr (delta .new_file , "licenses" ) else []
60+ )
6161
62+ new_categories = set (license ["category" ] for license in new_licenses )
63+ if hasattr (delta .new_file , "licenses" ):
64+ delta .update (20 , "license info added" )
6265 for category in new_categories :
6366 # no license ==> 'Copyleft Limited'or higher
6467 if category in unique_categories :
65- delta .update (20 , category .lower () + ' added' )
68+ delta .update (20 , category .lower () + " added" )
6669 # no license ==> 'Permissive' or 'Public Domain'
6770 else :
68- delta .update (0 , category .lower () + ' added' )
71+ delta .update (0 , category .lower () + " added" )
6972 return
7073
7174
@@ -75,44 +78,50 @@ def update_modified_from_license_info(delta, unique_categories):
7578 one or more categories to its 'factors' attribute if there has
7679 been a license change.
7780 """
78- if not delta .new_file .has_licenses () and delta .old_file .has_licenses ():
79- delta .update (15 , 'license info removed' )
80- return
8181
82- new_licenses = delta .new_file .licenses or []
83- old_licenses = delta .old_file .licenses or []
82+ new_licenses = (
83+ delta .new_file .licenses if hasattr (delta .new_file , "licenses" ) else []
84+ )
85+ old_licenses = (
86+ delta .old_file .licenses if hasattr (delta .old_file , "licenses" ) else []
87+ )
88+
89+ if not new_licenses and old_licenses :
90+ delta .update (15 , "license info removed" )
91+ return
8492
85- new_categories = set (license .category for license in new_licenses )
86- old_categories = set (license .category for license in old_licenses )
93+ new_categories = set (license .get ( " category" , "" ) for license in new_licenses )
94+ old_categories = set (license .get ( " category" , "" ) for license in old_licenses )
8795
88- if delta . new_file . has_licenses () and not delta . old_file . has_licenses () :
89- delta .update (20 , ' license info added' )
96+ if new_licenses and not old_licenses :
97+ delta .update (20 , " license info added" )
9098
9199 for category in new_categories :
92100 # no license ==> 'Copyleft Limited'or higher
93101 if category in unique_categories :
94- delta .update (20 , category .lower () + ' added' )
102+ delta .update (20 , category .lower () + " added" )
95103 # no license ==> 'Permissive' or 'Public Domain'
96104 else :
97- delta .update (0 , category .lower () + ' added' )
105+ delta .update (0 , category .lower () + " added" )
98106 return
99107
100- new_keys = set (license .key for license in new_licenses )
101- old_keys = set (license .key for license in old_licenses )
108+ new_keys = set (license .get ( " key" , "" ) for license in new_licenses )
109+ old_keys = set (license .get ( " key" , "" ) for license in old_licenses )
102110
103111 if new_keys != old_keys :
104- delta .update (10 , 'license change' )
112+
113+ delta .update (10 , "license change" )
105114 for category in new_categories - old_categories :
106115 unique_categories_in_old_file = len (old_categories & unique_categories )
107116 # 'Permissive' or 'Public Domain' ==> 'Copyleft Limited' or higher
108117 if unique_categories_in_old_file == 0 and category in unique_categories :
109- delta .update (20 , category .lower () + ' added' )
118+ delta .update (20 , category .lower () + " added" )
110119 # at least 1 category in the old file was 'Copyleft Limited' or higher ==> 'Copyleft Limited' or higher
111120 elif unique_categories_in_old_file != 0 and category in unique_categories :
112- delta .update (10 , category .lower () + ' added' )
121+ delta .update (10 , category .lower () + " added" )
113122 # 'Permissive' or 'Public Domain' ==> 'Permissive' or 'Public Domain' if not in old_categories
114123 elif category not in unique_categories :
115- delta .update (0 , category .lower () + ' added' )
124+ delta .update (0 , category .lower () + " added" )
116125
117126
118127def update_from_copyright_info (delta ):
@@ -134,8 +143,9 @@ def update_added_from_copyright_info(delta):
134143 one or more categories to its 'factors' attribute if there has
135144 been a copyright change.
136145 """
137- if delta .new_file .has_copyrights ():
138- delta .update (10 , 'copyright info added' )
146+
147+ if hasattr (delta .new_file , "copyrights" ):
148+ delta .update (10 , "copyright info added" )
139149 return
140150
141151
@@ -145,27 +155,39 @@ def update_modified_from_copyright_info(delta):
145155 one or more categories to its 'factors' attribute if there has
146156 been a copyright change.
147157 """
148- new_copyrights = delta .new_file .copyrights or []
149- old_copyrights = delta .old_file .copyrights or []
150158
151- if delta .new_file .has_copyrights () and not delta .old_file .has_copyrights ():
152- delta .update (10 , 'copyright info added' )
159+ new_copyrights = (
160+ delta .new_file .copyrights if hasattr (delta .new_file , "copyrights" ) else []
161+ )
162+ old_copyrights = (
163+ delta .old_file .copyrights if hasattr (delta .old_file , "copyrights" ) else []
164+ )
165+
166+ if new_copyrights and not old_copyrights :
167+ delta .update (10 , "copyright info added" )
153168 return
154- if not delta . new_file . has_copyrights () and delta . old_file . has_copyrights () :
155- delta .update (10 , ' copyright info removed' )
169+ if not new_copyrights and old_copyrights :
170+ delta .update (10 , " copyright info removed" )
156171 return
157172
158- new_holders = set (holder for copyright in new_copyrights for holder in copyright .holders )
159- old_holders = set (holder for copyright in old_copyrights for holder in copyright .holders )
160-
173+ new_holders = set (
174+ holder
175+ for copyright in new_copyrights
176+ for holder in copyright .get ("holders" , [])
177+ )
178+ old_holders = set (
179+ holder
180+ for copyright in old_copyrights
181+ for holder in copyright .get ("holders" , [])
182+ )
161183 if new_holders != old_holders :
162- delta .update (5 , ' copyright change' )
184+ delta .update (5 , " copyright change" )
163185
164186
165187def collect_errors (deltacode ):
166188 errors = []
167- errors .extend (deltacode .new . errors )
168- errors .extend (deltacode .old . errors )
189+ errors .extend (deltacode .new_files_errors )
190+ errors .extend (deltacode .old_files_errors )
169191 errors .extend (deltacode .errors )
170192
171193 return errors
@@ -179,39 +201,57 @@ def deltas(deltacode, all_delta_types=False):
179201 """
180202 for delta in deltacode .deltas :
181203 if all_delta_types is True :
182- yield delta .to_dict ()
183- elif not delta .is_unmodified ():
184- yield delta .to_dict ()
204+ yield delta .to_dict (deltacode )
205+ elif not delta .status == "unmodified" :
206+ yield delta .to_dict (deltacode )
207+
185208
186209def calculate_percent (value , total ):
187210 """
188211 Return the rounded value percentage of total.
189212 """
190- ratio = (value / total ) * 100
191- return round (ratio , 2 )
213+ try :
214+ ratio = (value / total ) * 100
215+ return round (ratio , 2 )
216+ except ZeroDivisionError :
217+ return 0
218+
192219
193220class AlignmentException (Exception ):
194221 """
195222 Named exception for alignment errors.
196223 """
224+
197225 pass
198226
199- def align_trees (a_files , b_files ):
227+
228+ class FileError (Exception ):
200229 """
201- Given two sequences of File objects 'a' and 'b', return a tuple of
202- two integers that represent the number path segments to remove
203- respectively from a File path in 'a' or a File path in 'b' to obtain the
204- equal paths for two files that are the same in 'a' and 'b'.
230+ Named Exception for handling errors which could be raised due to
231+ unsupported errors in the json file
232+ """
233+ def __init__ (self , * args ):
234+ if args :
235+ self .message = args [0 ]
236+ else :
237+ self .message = None
238+
239+ def __str__ (self ):
240+ return self .message
241+
242+
243+ def align_trees (codebase1 , codebase2 ):
244+ """
245+ Aligns the path of the two codebases
205246 """
206- # we need to find one uniquly named file that exists in 'a' and 'b'.
207247 a_names = defaultdict (list )
208- for a_file in a_files :
209- a_names [a_file .name ].append (a_file )
248+ for resource in codebase1 . walk () :
249+ a_names [resource .name ].append (resource )
210250 a_uniques = {k : v [0 ] for k , v in a_names .items () if len (v ) == 1 }
211251
212252 b_names = defaultdict (list )
213- for b_file in b_files :
214- b_names [b_file .name ].append (b_file )
253+ for resource in codebase2 . walk () :
254+ b_names [resource .name ].append (resource )
215255 b_uniques = {k : v [0 ] for k , v in b_names .items () if len (v ) == 1 }
216256
217257 candidate_found = False
@@ -228,59 +268,31 @@ def align_trees(a_files, b_files):
228268 if a_unique .path == b_unique .path :
229269 return 0 , 0
230270
231- common_suffix , common_segments = paths .common_path_suffix (a_unique .path , b_unique .path )
271+ common_suffix , common_segments = paths .common_path_suffix (
272+ a_unique .path , b_unique .path
273+ )
232274 a_segments = len (paths .split (a_unique .path ))
233275 b_segments = len (paths .split (b_unique .path ))
234276
235277 return a_segments - common_segments , b_segments - common_segments
236278
237279
238- def fix_trees (a_files , b_files ):
239- """
240- Given two sequences of File objects 'a' and 'b', use the tuple of two
241- integers returned by align_trees() to remove the number of path segments
242- required to create equal paths for two files that are the same in 'a' and
243- 'b'.
244- """
245- a_offset , b_offset = align_trees (a_files , b_files )
246- for a_file in a_files :
247- a_file .original_path = a_file .path
248- a_file .path = '/' .join (paths .split (a_file .path )[a_offset :])
249-
250- for b_file in b_files :
251- b_file .original_path = b_file .path
252- b_file .path = '/' .join (paths .split (b_file .path )[b_offset :])
253-
254-
255- def check_moved (added_sha1 , added_deltas , removed_sha1 , removed_deltas ):
256- """
257- Return True if there is only one pair of matching 'added' and 'removed'
258- Delta objects and their respective File objects have the same 'name' attribute.
259- """
260- if added_sha1 != removed_sha1 :
261- return False
262- if len (added_deltas ) != 1 or len (removed_deltas ) != 1 :
263- return False
264- if added_deltas [0 ].new_file .name == removed_deltas [0 ].old_file .name :
265- return True
266-
267-
268280def get_notice ():
269281 """
270282 Retrieve the notice text from the NOTICE file for display in the JSON output.
271283 """
272- notice_path = os .path .join (os .path .abspath (os .path .dirname (__file__ )), ' NOTICE' )
284+ notice_path = os .path .join (os .path .abspath (os .path .dirname (__file__ )), " NOTICE" )
273285 notice_text = open (notice_path ).read ()
274286
275- delimiter = ' \n \n \n '
287+ delimiter = " \n \n \n "
276288 [notice_text , extra_notice_text ] = notice_text .split (delimiter , 1 )
277289 extra_notice_text = delimiter + extra_notice_text
278290
279- delimiter = ' \n \n '
291+ delimiter = " \n \n "
280292 [notice_text , acknowledgment_text ] = notice_text .split (delimiter , 1 )
281293 acknowledgment_text = delimiter + acknowledgment_text
282294
283- notice = acknowledgment_text .strip ().replace (' ' , '' )
295+ notice = acknowledgment_text .strip ().replace (" " , "" )
284296
285297 return notice
286298
@@ -296,6 +308,7 @@ def hamming_distance(fingerprint1, fingerprint2):
296308
297309 return result
298310
311+
299312def bitarray_from_hex (fingerprint_hex ):
300313 """
301314 Return bitarray from a hex string.
@@ -305,11 +318,12 @@ def bitarray_from_hex(fingerprint_hex):
305318
306319 return result
307320
321+
308322def bitarray_from_bytes (b ):
309323 """
310324 Return bitarray from a byte string, interpreted as machine values.
311325 """
312326 a = bitarray ()
313327 a .frombytes (b )
314328
315- return a
329+ return a
0 commit comments