@( projectsWithSelection: ProjectsWithSelection, vulnerableDependencies: Seq[GroupedDependency], allDependenciesCount: Int, reports: DependencyCheckReportsParser.Result )(implicit header: DefaultRequest) @main( title = s"Vulnerable libraries for ${projectsWithSelection.projectNameText} (${vulnerableDependencies.size} deps, ${vulnerableDependencies.flatMap(_.cpeIdentifiers.map(_.toCpeIdentifierOption.get)).toSet.size} CPEs)", projectsOption = Some((projectsWithSelection, routes.Statistics.vulnerableLibraries(_))) ){ @healthReport(reports.failedProjects)

Plot

List

Libraries are sorted:

  1. by total score (max vulnerability score × number of affected dependencies) if vulnerability score is defined for at least one vulnerability
  2. by affected dependency count if the score above is not defined
  3. by number of vulnerabilities
  4. by affected project count

Note that the number of affected projects is calculated from the current view, not from all projects (unless all projects are selected).

@dependencyList( "vulnerable", vulnerableDependencies.sortBy(d => ( d.ysdssScore.map(-_), // total score is the king if(d.ysdssScore.isEmpty) Some(-d.dependencies.size) else None, // more affected dependencies if no vulnerability has defined severity -d.vulnerabilities.size, // more vulnerabilities -d.projects.size, // more affected projects d.cpeIdentifiers.map(_.toCpeIdentifierOption.get).toSeq.sorted.mkString(" ")) // at least make the order deterministic ), selectorOption = projectsWithSelection.selectorString, expandByDefault = false, addButtons = false ) }