@@ -58,8 +58,10 @@ def __init__(self, new_path, old_path, options):
5858 self .determine_moved ()
5959 self .license_diff ()
6060 self .copyright_diff ()
61- # Sort deltas by score, descending, i.e., high > low.
61+ # Sort deltas by score, descending, i.e., high > low, and then by
62+ # factors, alphabetically.
6263 self .deltas .sort (key = lambda Delta : Delta .score , reverse = True )
64+ self .deltas .sort (key = lambda Delta : Delta .factors , reverse = False )
6365
6466 def align_scans (self ):
6567 """
@@ -134,7 +136,7 @@ def determine_delta(self):
134136 # This file already classified so do nothing
135137 new_index [path ]
136138 except KeyError :
137- delta = Delta (10 , None , old_file )
139+ delta = Delta (0 , None , old_file )
138140 delta .factors .append ('removed' )
139141 self .deltas .append (delta )
140142 continue
@@ -158,10 +160,10 @@ def determine_moved(self):
158160 both indices with the same 'sha1' and File 'name' attributes, and
159161 converting each such pair of 'added' and 'removed' Delta objects to a
160162 'moved' Delta object. The 'added' and 'removed' indices are defined by
161- the 'score' attribute of the Delta objects .
163+ the presence/absence of the object's 'old_file' and 'new_file' .
162164 """
163- added = self .index_deltas ('sha1' , [i for i in self .deltas if i .score == 100 ])
164- removed = self .index_deltas ('sha1' , [i for i in self .deltas if i .score == 10 ])
165+ added = self .index_deltas ('sha1' , [i for i in self .deltas if i .old_file is None and i . new_file ])
166+ removed = self .index_deltas ('sha1' , [i for i in self .deltas if i .old_file and i . new_file is None ])
165167
166168 # TODO: should it be iteritems() or items()
167169 for added_sha1 , added_deltas in added .iteritems ():
@@ -177,7 +179,7 @@ def update_deltas(self, added, removed):
177179 'moved' Delta object -- passing the appropriate 'score' during object
178180 creation -- and delete the 'added' and 'removed' objects.
179181 """
180- delta = Delta (5 , added .new_file , removed .old_file )
182+ delta = Delta (0 , added .new_file , removed .old_file )
181183 delta .factors .append ('moved' )
182184 self .deltas .append (delta )
183185 self .deltas .remove (added )
@@ -187,30 +189,48 @@ def license_diff(self):
187189 """
188190 Compare the license details for a pair of 'new' and 'old' File objects
189191 in a Delta object and change the Delta object's 'score' attribute --
190- and add an appropriate category (e.g., 'license info removed', 'license
191- info added' or 'license change') to the Delta object's 'factors'
192- attribute -- if there has been a license change and depending on the
193- nature of that change.
192+ and add one or more appropriate categories (e.g., 'license change',
193+ 'copyleft added') to the Delta object's 'factors' attribute -- if there
194+ has been a license change and depending on the nature of that change.
194195 """
196+ unique_categories = set ([
197+ 'Commercial' ,
198+ 'Copyleft' ,
199+ 'Copyleft Limited' ,
200+ 'Free Restricted' ,
201+ 'Patent License' ,
202+ 'Proprietary Free'
203+ ])
204+
195205 for delta in self .deltas :
196- if 20 <= delta .score < 100 :
206+ if delta .is_modified ():
207+ if not delta .new_file .has_licenses () and delta .old_file .has_licenses ():
208+ delta .update (15 , 'license info removed' )
209+ return
197210
198211 new_licenses = delta .new_file .licenses or []
199212 old_licenses = delta .old_file .licenses or []
200213
201- if len (delta .new_file .licenses ) > 0 and delta .old_file .licenses == []:
202- delta .update (20 , 'license info added' )
203- return
214+ new_categories = set (license .category for license in new_licenses )
215+ old_categories = set (license .category for license in old_licenses )
204216
205- if delta .new_file .licenses == [] and len (delta .old_file .licenses ) > 0 :
206- delta .update (15 , 'license info removed' )
217+ if delta .new_file .has_licenses () and not delta .old_file .has_licenses ():
218+ delta .update (20 , 'license info added' )
219+ # no license ==> 'Copyleft Limited'or higher
220+ for category in new_categories :
221+ if category in unique_categories :
222+ delta .update (20 , category .lower () + ' added' )
207223 return
208224
209225 new_keys = set (license .key for license in new_licenses )
210226 old_keys = set (license .key for license in old_licenses )
211227
212228 if new_keys != old_keys :
213229 delta .update (10 , 'license change' )
230+ for category in new_categories - old_categories :
231+ # 'Permissive' or 'Public Domain' ==> 'Copyleft Limited' or higher
232+ if len (old_categories & unique_categories ) == 0 and category in unique_categories :
233+ delta .update (20 , category .lower () + ' added' )
214234
215235 def copyright_diff (self ):
216236 """
@@ -222,15 +242,14 @@ def copyright_diff(self):
222242 nature of that change.
223243 """
224244 for delta in self .deltas :
225- if 20 <= delta .score < 100 :
226-
245+ if delta .is_modified ():
227246 new_copyrights = delta .new_file .copyrights or []
228247 old_copyrights = delta .old_file .copyrights or []
229248
230- if len ( delta .new_file .copyrights ) > 0 and delta .old_file .copyrights == [] :
249+ if delta .new_file .has_copyrights () and not delta .old_file .has_copyrights () :
231250 delta .update (10 , 'copyright info added' )
232251 return
233- elif delta .new_file .copyrights == [] and len ( delta .old_file .copyrights ) > 0 :
252+ if not delta .new_file .has_copyrights () and delta .old_file .has_copyrights () :
234253 delta .update (10 , 'copyright info removed' )
235254 return
236255
@@ -289,6 +308,26 @@ def update(self, score=0, factor=''):
289308 self .factors .append (factor )
290309 self .score += score
291310
311+ def is_modified (self ):
312+ """
313+ Identify a Delta object meriting attention to possible changes in its
314+ license or copyright content because the File object has been modified.
315+ """
316+ if self .score > 0 and self .old_file :
317+ return True
318+
319+ def is_unmodified (self ):
320+ """
321+ Since 'unmodified' is no longer the only category/factor with a
322+ score = 0, test the Delta object's attributes for categories/factors
323+ other than 'unmodified' and return True if all but 'unmodified' are
324+ ruled out.
325+ """
326+ if (self .old_file and self .new_file and
327+ self .old_file .sha1 == self .new_file .sha1 and
328+ self .old_file .path == self .new_file .path ):
329+ return True
330+
292331 def to_dict (self ):
293332 """
294333 Return an OrderedDict comprising the 'factors', 'score' and new and old
0 commit comments