Skip to content

Commit 7ce3734

Browse files
committed
Remove references to summary in tallies.py
* Remove redundant code in summarizer.py Reference: #2842 Signed-off-by: Jono Yang <jyang@nexb.com>
1 parent 5afa8f2 commit 7ce3734

14 files changed

Lines changed: 1723 additions & 451 deletions

src/summarycode/copyright_tallies.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,20 +227,20 @@ def tally_persons(texts):
227227
Return a list of mapping of {value:string, count:int} given a
228228
list of holders strings or Text() objects.
229229
"""
230-
texts = []
230+
texts_to_tally = []
231231
no_detection_counter = 0
232232
for text in texts:
233233
if not text:
234234
no_detection_counter += 1
235235
continue
236236
# Keep Text objects as-is
237237
if isinstance(text, Text):
238-
texts.append(text)
238+
texts_to_tally.append(text)
239239
else:
240240
cano = canonical_holder(text)
241-
texts.append(Text(cano, cano))
241+
texts_to_tally.append(Text(cano, cano))
242242

243-
counter = tally(texts)
243+
counter = tally(texts_to_tally)
244244

245245
if no_detection_counter:
246246
counter[None] = no_detection_counter

src/summarycode/summarizer.py

Lines changed: 28 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@
1212
import attr
1313
import fingerprints
1414
from commoncode.cliutils import POST_SCAN_GROUP, PluggableCommandLineOption
15-
from plugincode.post_scan import PostScanPlugin, post_scan_impl
1615
from license_expression import Licensing
16+
from plugincode.post_scan import PostScanPlugin, post_scan_impl
17+
1718
from cluecode.copyrights import CopyrightDetector
1819
from packagedcode.utils import combine_expressions
19-
from summarycode.copyright_summary import canonical_holder
2020
from summarycode.score import (compute_license_score,
2121
get_field_values_from_codebase_resources,
2222
unique)
23-
from summarycode.utils import (get_resource_summary, set_resource_summary,
24-
sorted_counter)
23+
from summarycode.tallies import compute_codebase_tallies
24+
2525

2626
# Tracing flags
27-
TRACE = False
27+
TRACE = True
2828
TRACE_LIGHT = False
2929

3030

@@ -72,11 +72,11 @@ def is_enabled(self, summary, **kwargs):
7272
def process_codebase(self, codebase, summary, **kwargs):
7373
if TRACE_LIGHT: logger_debug('ScanSummary:process_codebase')
7474

75-
# Get summary data
76-
summary = summarize_codebase(codebase, keep_details=False, **kwargs)
77-
license_expressions_summary = summary.get('license_expressions') or []
78-
holders_summary = summary.get('holders') or []
79-
programming_language_summary = summary.get('programming_language') or []
75+
# Get tallies
76+
tallies = compute_codebase_tallies(codebase, keep_details=False, **kwargs)
77+
license_expressions_tallies = tallies.get('license_expressions') or []
78+
holders_tallies = tallies.get('holders') or []
79+
programming_language_tallies = tallies.get('programming_language') or []
8080

8181
# Get Package data from key files
8282
key_files_package_data = get_field_values_from_codebase_resources(
@@ -100,15 +100,15 @@ def process_codebase(self, codebase, summary, **kwargs):
100100
# If we did not get a declared license expression from detected
101101
# package data, then we use the results from `compute_license_score`
102102
scoring_elements, declared_license_expression = compute_license_score(codebase)
103-
other_license_expressions = remove_from_summary(declared_license_expression, license_expressions_summary)
103+
other_license_expressions = remove_from_tallies(declared_license_expression, license_expressions_tallies)
104104

105105
if not declared_holder:
106-
declared_holder = get_declared_holder(codebase, holders_summary)
107-
other_holders = remove_from_summary(declared_holder, holders_summary)
106+
declared_holder = get_declared_holder(codebase, holders_tallies)
107+
other_holders = remove_from_tallies(declared_holder, holders_tallies)
108108

109109
if not primary_language:
110-
primary_language = get_primary_language(programming_language_summary)
111-
other_languages = remove_from_summary(primary_language, programming_language_summary)
110+
primary_language = get_primary_language(programming_language_tallies)
111+
other_languages = remove_from_tallies(primary_language, programming_language_tallies)
112112

113113
# Save summary info to codebase
114114
codebase.attributes.summary['declared_license_expression'] = declared_license_expression
@@ -120,215 +120,23 @@ def process_codebase(self, codebase, summary, **kwargs):
120120
codebase.attributes.summary['other_languages'] = other_languages
121121

122122

123-
def remove_from_summary(entry, summary_data):
123+
def remove_from_tallies(entry, tallies):
124124
"""
125-
Return an list containing the elements of `summary_data`, without `entry`
125+
Return an list containing the elements of `tallies`, without `entry`
126126
"""
127-
pruned_summary_data = []
128-
for s in summary_data:
127+
pruned_tallies = []
128+
for t in tallies:
129129
if (
130-
isinstance(entry, dict) and s == entry
131-
or isinstance(entry, (list, tuple)) and s in entry
132-
or s.get('value') == entry
130+
isinstance(entry, dict) and t == entry
131+
or isinstance(entry, (list, tuple)) and t in entry
132+
or t.get('value') == entry
133133
):
134134
continue
135-
pruned_summary_data.append(s)
136-
return pruned_summary_data
137-
138-
139-
def summarize_codebase(codebase, keep_details, **kwargs):
140-
"""
141-
Summarize a scan at the codebase level for available scans.
142-
143-
If `keep_details` is True, also keep file and directory details in the
144-
`summary` file attribute for every file and directory.
145-
146-
If `legacy` is True, summarize copyrights, authors, programming languages,
147-
and packages.
148-
"""
149-
from summarycode.copyright_summary import holder_summarizer
150-
151-
attrib_summarizers = [
152-
('license_expressions', license_summarizer),
153-
('holders', holder_summarizer),
154-
('programming_language', language_summarizer),
155-
]
156-
157-
# find which attributes are available for summarization by checking the root
158-
# resource
159-
root = codebase.root
160-
summarizers = [s for a, s in attrib_summarizers if hasattr(root, a)]
161-
if TRACE: logger_debug('summarize_codebase with summarizers:', summarizers)
162-
163-
# collect and set resource-level summaries
164-
for resource in codebase.walk(topdown=False):
165-
children = resource.children(codebase)
166-
167-
for summarizer in summarizers:
168-
_summary_data = summarizer(resource, children, keep_details=keep_details)
169-
if TRACE: logger_debug('summary for:', resource.path, 'after summarizer:', summarizer, 'is:', _summary_data)
170-
171-
codebase.save_resource(resource)
172-
173-
# set the summary from the root resource at the codebase level
174-
if keep_details:
175-
summary = root.summary
176-
else:
177-
summary = root.extra_data.get('summary', {})
178-
179-
if TRACE: logger_debug('codebase summary:', summary)
180-
181-
return summary
182-
183-
184-
def license_summarizer(resource, children, keep_details=False):
185-
"""
186-
Populate a license_expressions list of mappings such as
187-
{value: "expression", count: "count of occurences"}
188-
sorted by decreasing count.
189-
"""
190-
LIC_EXP = 'license_expressions'
191-
license_expressions = []
192-
193-
# Collect current data
194-
lic_expressions = getattr(resource, LIC_EXP , [])
195-
if not lic_expressions and resource.is_file:
196-
# also count files with no detection
197-
license_expressions.append(None)
198-
else:
199-
license_expressions.extend(lic_expressions)
200-
201-
# Collect direct children expression summary
202-
for child in children:
203-
child_summaries = get_resource_summary(child, key=LIC_EXP, as_attribute=keep_details) or []
204-
for child_summary in child_summaries:
205-
# TODO: review this: this feels rather weird
206-
child_sum_val = child_summary.get('value')
207-
if child_sum_val:
208-
values = [child_sum_val] * child_summary['count']
209-
license_expressions.extend(values)
210-
211-
# summarize proper
212-
licenses_counter = summarize_licenses(license_expressions)
213-
summarized = sorted_counter(licenses_counter)
214-
set_resource_summary(resource, key=LIC_EXP, value=summarized, as_attribute=keep_details)
215-
return summarized
216-
217-
218-
def summarize_licenses(license_expressions):
219-
"""
220-
Given a list of license expressions, return a mapping of {expression: count
221-
of occurences}
222-
"""
223-
# TODO: we could normalize and/or sort each license_expression before
224-
# summarization and consider other equivalence or containment checks
225-
return Counter(license_expressions)
226-
227-
228-
def language_summarizer(resource, children, keep_details=False):
229-
"""
230-
Populate a programming_language summary list of mappings such as
231-
{value: "programming_language", count: "count of occurences"}
232-
sorted by decreasing count.
233-
"""
234-
PROG_LANG = 'programming_language'
235-
languages = []
236-
prog_lang = getattr(resource, PROG_LANG , [])
237-
if not prog_lang:
238-
if resource.is_file:
239-
# also count files with no detection
240-
languages.append(None)
241-
else:
242-
languages.append(prog_lang)
243-
244-
# Collect direct children expression summaries
245-
for child in children:
246-
child_summaries = get_resource_summary(child, key=PROG_LANG, as_attribute=keep_details) or []
247-
for child_summary in child_summaries:
248-
child_sum_val = child_summary.get('value')
249-
if child_sum_val:
250-
values = [child_sum_val] * child_summary['count']
251-
languages.extend(values)
252-
253-
# summarize proper
254-
languages_counter = summarize_languages(languages)
255-
summarized = sorted_counter(languages_counter)
256-
set_resource_summary(resource, key=PROG_LANG, value=summarized, as_attribute=keep_details)
257-
return summarized
258-
259-
260-
def summarize_languages(languages):
261-
"""
262-
Given a list of languages, return a mapping of {language: count
263-
of occurences}
264-
"""
265-
# TODO: consider aggregating related langauges (C/C++, etc)
266-
return Counter(languages)
267-
268-
269-
SUMMARIZABLE_ATTRS = set([
270-
'license_expressions',
271-
'copyrights',
272-
'holders',
273-
'authors',
274-
'programming_language',
275-
# 'packages',
276-
])
277-
278-
279-
def add_files(packages, resource):
280-
"""
281-
Update in-place every package mapping in the `packages` list by updating or
282-
creating the the "files" attribute from the `resource`. Yield back the
283-
packages.
284-
"""
285-
for package in packages:
286-
files = package['files'] = package.get('files') or []
287-
fil = resource.to_dict(skinny=True)
288-
if fil not in files:
289-
files.append(fil)
290-
yield package
291-
292-
293-
def package_summarizer(resource, children, keep_details=False):
294-
"""
295-
Populate a packages summary list of packages mappings.
296-
297-
Note: `keep_details` is never used, as we are not keeping details of
298-
packages as this has no value.
299-
"""
300-
packages = []
301-
302-
# Collect current data
303-
current_packages = getattr(resource, 'packages') or []
304-
305-
if TRACE_LIGHT and current_packages:
306-
from packagedcode.models import Package
307-
packs = [Package.create(**p) for p in current_packages]
308-
logger_debug('package_summarizer: for:', resource,
309-
'current_packages are:', packs)
310-
311-
current_packages = add_files(current_packages, resource)
312-
packages.extend(current_packages)
313-
314-
if TRACE_LIGHT and packages:
315-
logger_debug()
316-
from packagedcode.models import Package # NOQA
317-
packs = [Package.create(**p) for p in packages]
318-
logger_debug('package_summarizer: for:', resource,
319-
'packages are:', packs)
320-
321-
# Collect direct children packages summary
322-
for child in children:
323-
child_summaries = get_resource_summary(child, key='packages', as_attribute=False) or []
324-
packages.extend(child_summaries)
325-
326-
# summarize proper
327-
set_resource_summary(resource, key='packages', value=packages, as_attribute=False)
328-
return packages
135+
pruned_tallies.append(t)
136+
return pruned_tallies
329137

330138

331-
def get_declared_holder(codebase, holders_summary):
139+
def get_declared_holder(codebase, holders_tallies):
332140
"""
333141
Determine the declared holders of a codebase from the holders detected from
334142
key files.
@@ -338,7 +146,7 @@ def get_declared_holder(codebase, holders_summary):
338146
"""
339147
entry_by_holders = {
340148
fingerprints.generate(entry['value']): entry
341-
for entry in holders_summary if entry['value']
149+
for entry in holders_tallies if entry['value']
342150
}
343151
key_file_holders = get_field_values_from_codebase_resources(codebase, 'holders', key_files_only=True)
344152
entry_by_key_file_holders = {
@@ -367,13 +175,13 @@ def get_declared_holder(codebase, holders_summary):
367175
return declared_holder
368176

369177

370-
def get_primary_language(programming_language_summary):
178+
def get_primary_language(programming_language_tallies):
371179
"""
372180
Return the most common detected programming language as the primary language.
373181
"""
374182
programming_languages_by_count = {
375183
entry['count']: entry['value']
376-
for entry in programming_language_summary
184+
for entry in programming_language_tallies
377185
}
378186
primary_language = ''
379187
if programming_languages_by_count:

0 commit comments

Comments
 (0)