Skip to content

Commit

Permalink
Merge pull request #2989 from csordasmarton/auto_generated_other_comp…
Browse files Browse the repository at this point in the history
…onent

[web] Introduce a default other component
  • Loading branch information
csordasmarton authored Nov 5, 2020
2 parents d1604bb + ad5a973 commit 9557fe0
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 45 deletions.
15 changes: 15 additions & 0 deletions web/client/codechecker_client/source_component_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
# Needs to be set in the handler functions.
LOG = None

GEN_OTHER_COMPONENT_NAME = "Other (auto-generated)"


def init_logger(level, stream=None, logger_name='system'):
logger.setup_logger(level, stream)
Expand All @@ -34,6 +36,11 @@ def handle_add_component(args):

client = setup_client(args.product_url)

if args.name == GEN_OTHER_COMPONENT_NAME:
LOG.error("'%s' is a special virtual component which can not be "
"modified.", GEN_OTHER_COMPONENT_NAME)
sys.exit(1)

with open(args.component_file, 'r',
encoding="utf-8", errors="ignore") as component_file:
value = component_file.read().strip()
Expand Down Expand Up @@ -77,6 +84,9 @@ def handle_list_components(args):
header = ['Name', 'Value', 'Description']
rows = []
for res in components:
if res.name == GEN_OTHER_COMPONENT_NAME:
res.value = ''

for idx, value in enumerate(res.value.split('\n')):
name = res.name if idx == 0 else ''
description = res.description \
Expand All @@ -92,6 +102,11 @@ def handle_del_component(args):

client = setup_client(args.product_url)

if args.name == GEN_OTHER_COMPONENT_NAME:
LOG.error("'%s' is a special virtual component which can not be "
"removed.", GEN_OTHER_COMPONENT_NAME)
sys.exit(1)

# Check that the given source component is exists.
source_component = client.getSourceComponents([args.name])

Expand Down
114 changes: 84 additions & 30 deletions web/server/codechecker_server/api/report_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@

LOG = get_logger('server')

GEN_OTHER_COMPONENT_NAME = "Other (auto-generated)"


class CommentKindValue(object):
USER = 0
Expand Down Expand Up @@ -317,32 +319,8 @@ def process_report_filter(session, run_ids, report_filter, cmp_data=None):
AND.append(or_(*OR))

if report_filter.componentNames:
OR = []

for component_name in report_filter.componentNames:
skip, include = get_component_values(session, component_name)

if skip and include:
include_q = select([File.id]) \
.where(or_(*[
File.filepath.like(conv(fp)) for fp in include])) \
.distinct()

skip_q = select([File.id]) \
.where(or_(*[
File.filepath.like(conv(fp)) for fp in skip])) \
.distinct()

OR.append(or_(File.id.in_(
include_q.except_(skip_q))))
elif include:
include_q = [File.filepath.like(conv(fp)) for fp in include]
OR.append(or_(*include_q))
elif skip:
skip_q = [not_(File.filepath.like(conv(fp))) for fp in skip]
OR.append(and_(*skip_q))

AND.append(or_(*OR))
AND.append(process_source_component_filter(
session, report_filter.componentNames))

if report_filter.bugPathLength is not None:
min_path_length = report_filter.bugPathLength.min
Expand All @@ -357,6 +335,67 @@ def process_report_filter(session, run_ids, report_filter, cmp_data=None):
return filter_expr


def process_source_component_filter(session, component_names):
""" Process source component filter.
The virtual auto-generated Other component will be handled separately and
the query part will be added to the filter.
"""
OR = []

for component_name in component_names:
if component_name == GEN_OTHER_COMPONENT_NAME:
OR.append(or_(*get_other_source_component_file_query(session)))
continue

OR.append(or_(*get_source_component_file_query(session,
component_name)))

return or_(*OR)


def get_source_component_file_query(session, component_name):
""" Get filter query for a single source component. """
skip, include = get_component_values(session, component_name)

if skip and include:
include_q = select([File.id]) \
.where(or_(*[
File.filepath.like(conv(fp)) for fp in include])) \
.distinct()

skip_q = select([File.id]) \
.where(or_(*[
File.filepath.like(conv(fp)) for fp in skip])) \
.distinct()

return [File.id.in_(include_q.except_(skip_q))]
elif include:
return [File.filepath.like(conv(fp)) for fp in include]
elif skip:
return [not_(File.filepath.like(conv(fp))) for fp in skip]


def get_other_source_component_file_query(session):
""" Get filter query for the auto-generated Others component. """
OR = []

component_names = session.query(SourceComponent.name).all()

# If there are no user defined source components we don't have to filter.
if not component_names:
return []

for (component_name, ) in component_names:
OR.extend(get_source_component_file_query(session, component_name))

q = select([File.id]) \
.where(or_(*OR)) \
.distinct()

return [File.id.notin_(q)]


def get_open_reports_date_filter_query(tbl=Report, date=RunHistory.time):
""" Get open reports date filter. """
return and_(tbl.detected_at <= date,
Expand Down Expand Up @@ -2372,16 +2411,31 @@ def getSourceComponents(self, component_filter):
with DBSession(self.__Session) as session:
q = session.query(SourceComponent)

if component_filter and component_filter:
if component_filter:
sql_component_filter = [SourceComponent.name.ilike(conv(cf))
for cf in component_filter]
q = q.filter(*sql_component_filter)

q = q.order_by(SourceComponent.name)

return list([SourceComponentData(c.name,
c.value.decode('utf-8'),
c.description) for c in q])
components = [SourceComponentData(c.name, c.value.decode('utf-8'),
c.description) for c in q]

# If no filter is set or the auto generated component name can
# be found in the filter list we will return with this
# component too.
if not component_filter or \
GEN_OTHER_COMPONENT_NAME in component_filter:
component_other = \
SourceComponentData(GEN_OTHER_COMPONENT_NAME, None,
"Special auto-generated source "
"component which contains files that "
"are uncovered by the rest of the "
"components.")

components.append(component_other)

return components

@exc_to_thrift_reqfail
@timeit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default {
return {
id : component.name,
title: component.name,
value: component.value
value: component.value || component.description
};
}));
this.loading = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ export default {
this.loading = true;
ccService.getClient().getSourceComponents(null,
handleThriftError(components => {
this.components = components;
this.components = components.filter(c =>
!c.name.includes("auto-generated"));
this.loading = false;
}));
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
<v-list-item
v-for="v in value.split('\n')"
:key="v"
:class="[ v[0] === '+' ? 'include' : 'exclude' ]"
:class="[
v[0] === '+' ? 'include' : v[0] === '-' ? 'exclude': 'other'
]"
dense
>
{{ v }}
Expand Down Expand Up @@ -49,6 +51,10 @@ export default {
&.exclude {
color: red !important;
}
&.other {
color: black !important;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export default {
return {
component : component.name,
value : component.value,
value : component.value || component.description,
reports : initDiffField(res[0]),
unreviewed : initDiffField(res[1]),
confirmed : initDiffField(res[2]),
Expand All @@ -166,7 +166,7 @@ export default {
this.statistics = this.components.map(component => ({
component : component.name,
value : component.value,
value : component.value || component.description,
reports : initDiffField(undefined),
unreviewed : initDiffField(undefined),
confirmed : initDiffField(undefined),
Expand Down
Loading

0 comments on commit 9557fe0

Please sign in to comment.