2828from __future__ import unicode_literals
2929
3030from collections import Counter
31+ from collections import defaultdict
3132from collections import OrderedDict
3233
3334import attr
@@ -67,6 +68,10 @@ class OriginSummary(PostScanPlugin):
6768 Summarize copyright holders and license expressions to the directory level if a copyright holder
6869 or license expression is detected in 75% or more of total files in a directory
6970 """
71+ codebase_attributes = dict (
72+ summarized_directories = attr .ib (default = attr .Factory (OrderedDict ))
73+ )
74+
7075 resource_attributes = dict (
7176 origin_summary = attr .ib (default = attr .Factory (OrderedDict )),
7277 summarized_to = attr .ib (default = None , type = str )
@@ -93,6 +98,9 @@ def process_codebase(self, codebase, **kwargs):
9398 # TODO: Raise warning(?) if these fields are not there
9499 return
95100
101+ summarized_dirs_by_license_and_holder = defaultdict (list )
102+
103+ # Pass 1: summarize origin clues to directory level and tag summarized Resources
96104 for resource in codebase .walk (topdown = False ):
97105 # TODO: Consider facets for later
98106
@@ -105,7 +113,6 @@ def process_codebase(self, codebase, **kwargs):
105113
106114 origin_count = Counter ()
107115 child_rids = []
108-
109116 for child in children :
110117 if child .is_file :
111118 license_expression = combine_expressions (child .license_expressions )
@@ -125,14 +132,18 @@ def process_codebase(self, codebase, **kwargs):
125132 if origin_count :
126133 resource .extra_data ['origin_count' ] = origin_count
127134 resource .save (codebase )
128- (holders , license_expression ), top_count = origin_count .most_common (1 )[0 ]
135+ origin , top_count = origin_count .most_common (1 )[0 ]
136+ holders , license_expression = origin
129137 # TODO: Check for contradictions when performing summarizations
130138 if is_majority (top_count , resource .files_count ):
131139 resource .origin_summary ['license_expression' ] = license_expression
132140 resource .origin_summary ['holders' ] = holders
133141 resource .origin_summary ['count' ] = top_count
134142 codebase .save_resource (resource )
135143
144+ if resource .is_dir :
145+ summarized_dirs_by_license_and_holder [origin ].append (resource .path )
146+
136147 for child_rid in child_rids :
137148 child = codebase .get_resource (child_rid )
138149 if child .is_file :
@@ -145,6 +156,13 @@ def process_codebase(self, codebase, **kwargs):
145156 child .summarized_to = resource .path
146157 child .save (codebase )
147158
159+ for (holders , license_expression ), summarized_dirs in summarized_dirs_by_license_and_holder .items ():
160+ holder = ', ' .join (holders )
161+ if holder in codebase .attributes .summarized_directories :
162+ codebase .attributes .summarized_directories [holder ][license_expression ].extend (sorted (summarized_dirs ))
163+ else :
164+ codebase .attributes .summarized_directories [holder ] = {license_expression : sorted (summarized_dirs )}
165+
148166
149167def is_majority (count , files_count ):
150168 """
0 commit comments