-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #689 from forcedotcom/dev-3
@W-11163136@: Release activity for Scanner 3.1.0
- Loading branch information
Showing
712 changed files
with
94,028 additions
and
322 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ version: 2.1 | |
defaults: &defaults | ||
working_directory: ~/repo | ||
docker: | ||
- image: circleci/openjdk:11.0.2-jdk-node | ||
- image: cimg/openjdk:8.0-node | ||
|
||
orbs: | ||
win: circleci/[email protected] # The Windows orb give you everything you need to start using the Windows executor. | ||
|
@@ -543,7 +543,7 @@ workflows: | |
tag: latest-pilot-rc | ||
filters: | ||
<<: *publishing_filters | ||
context: | ||
context: | ||
- AWS | ||
- salesforce-cli | ||
# Step 3: Smoke test the release candidate on both Linux and Windows. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,3 +144,4 @@ build | |
|
||
pmd-cataloger/bin | ||
|
||
sfge*.log.gz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-bin.zip | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,334 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.dataTables.min.css"> | ||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> | ||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css"> | ||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.bootstrap4.min.css"> | ||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/Chart.min.css"> | ||
<style> | ||
/* Move the search box to the left */ | ||
.dataTables_filter { | ||
float: left !important; | ||
padding-left: 10px; | ||
padding-top: 10px; | ||
} | ||
/* Datatable should take up entire width */ | ||
.table { | ||
width:100% !important; | ||
} | ||
/* Datatable column */ | ||
.scannerSeverity { | ||
width: 10px; | ||
text-align: center; | ||
} | ||
/* Datatable column. Right justify numerics. */ | ||
.scannerLocation { | ||
text-align: right; | ||
} | ||
.summaryChartCell { | ||
background-color:white; | ||
} | ||
.summaryChartContainer { | ||
padding-left:10%; | ||
padding-right:10%; | ||
width:100%; | ||
background-color:white | ||
} | ||
h1, h4 { | ||
text-align: center; | ||
} | ||
#footer { | ||
padding-top: 10px; | ||
padding-bottom: 10px; | ||
background-color: #e0e0e0; | ||
font-size: 1.5em; | ||
text-align: center; | ||
} | ||
#reportTitle { | ||
margin: 25px; | ||
} | ||
#summaryFiles { | ||
margin-top: 25px; | ||
} | ||
</style> | ||
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script> | ||
<script type="text/javascript" language="javascript" | ||
src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script> | ||
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/rowgroup/1.1.2/js/dataTables.rowGroup.min.js"></script> | ||
<script type="text/javascript" language="javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/Chart.min.js"></script> | ||
<script type="text/javascript" class="init"> | ||
// BEGIN - Placeholders filled in by the scanner | ||
const violations = {{{violations}}}; | ||
// END - Placeholders filled in by the scanner | ||
// Global DataTable displayed in the report | ||
var dataTable = null; | ||
// Color if the severity is greater than 5 | ||
const unknownSeverityColor = '#cccccc'; | ||
// Background colors for severity | ||
// Palette from https://www.w3schools.com/colors/colors_palettes.asp | ||
// TODO: Accessibility | ||
function getSeverityColor(severity) { | ||
switch (parseInt(severity)) { | ||
case 1: | ||
return '#d96459'; | ||
case 2: | ||
return '#f2ae72'; | ||
case 3: | ||
return '#f2e394'; | ||
case 4: | ||
return '#588c7e'; | ||
case 5: | ||
return '#96ceb4'; | ||
default: | ||
return '#cccccc'; | ||
} | ||
} | ||
// Convert a map of severity->count to a structure consumable by the chart library | ||
// options.labelFormatter: function(severity, count) that returns a label | ||
function sevMapToChartData(sevMap, options) { | ||
var dataset = { | ||
data: [], | ||
backgroundColor: [] | ||
}; | ||
var dataLabels = []; | ||
// Sort the entries by key order | ||
sevMap = new Map([...sevMap.entries()].sort()); | ||
for (var severity of sevMap.keys()) { | ||
var count = sevMap.get(severity); | ||
dataset.data.push(count); | ||
dataset.backgroundColor.push(getSeverityColor(severity)); | ||
if (options && options.labelFormatter) { | ||
dataLabels.push(options.labelFormatter(severity, count)); | ||
} else { | ||
dataLabels.push(`Sev${severity}`); | ||
} | ||
} | ||
return { | ||
datasets: [dataset], | ||
labels: dataLabels | ||
}; | ||
} | ||
// Creates a horizontal bar chart below a grouping of rows. Called | ||
// asynchronously as the rows are added/removed by the search feature. | ||
function populateRowGroupChart(id, summary) { | ||
const ctx = $(`#${id}`); | ||
if (!ctx.length) { | ||
// This can happen when the user quickly types in the search field | ||
return; | ||
} | ||
const data = sevMapToChartData(summary); | ||
new Chart(ctx, { | ||
type: 'horizontalBar', | ||
data: data, | ||
options: { | ||
aspectRatio: 20, | ||
animation: { | ||
duration: 0 | ||
}, | ||
legend: { | ||
display: false | ||
}, | ||
scales: { | ||
xAxes: [{ | ||
ticks: { beginAtZero: true } | ||
}] | ||
} | ||
}, | ||
}); | ||
} | ||
function populateSummaryChart() { | ||
// The number of files is determined by finding the number of row groupings | ||
const numFiles = $('.dtrg-start').length; | ||
var text = `${numFiles} File`; | ||
if (numFiles !== 1) { | ||
text += 's' | ||
} | ||
$('#summaryFiles').text(text); | ||
// Number/type of violations is found by analyzing the visible data rows | ||
var summary = new Map(); | ||
dataTable.rows({ search: 'applied' }) | ||
.data() | ||
.pluck('severity') | ||
.each(function (value, index) { | ||
var count = summary.get(value); | ||
count = count ? (count + 1) : 1; | ||
summary.set(value, count); | ||
}); | ||
// Calculate the total number of violations, independent of severity | ||
const numViolations = Array.from(summary.values()).reduce((a, b) => a + b, 0); | ||
text = `${numViolations} Violation`; | ||
if (numViolations !== 1) { | ||
text += 's' | ||
} | ||
$('#summaryViolations').text(text); | ||
const data = sevMapToChartData(summary, { | ||
labelFormatter: function(severity, count) { | ||
return `Sev${severity} (${count})`; | ||
} | ||
}); | ||
// Create a new canvas, remove the previous canvas | ||
const canvas = $('<canvas/>'); | ||
$('#summaryChart').empty().append(canvas); | ||
new Chart(canvas, { | ||
type: 'doughnut', | ||
data: data, | ||
options: { | ||
aspectRatio: 6, | ||
animation: { | ||
duration: 0 | ||
}, | ||
legend: { | ||
display: true, | ||
position: 'bottom', | ||
// Prevent a click from modifying the chart | ||
onClick: (e) => e.stopPropagation(), | ||
labels: { | ||
fontSize: 18, | ||
fontStyle: 'bold' | ||
} | ||
} | ||
}, | ||
}); | ||
} | ||
// Create a table where the first column(fileName) is hidden but used for grouping. | ||
// Initial sort by fileName, severity, lineNumber | ||
// fileName is used in orderFixed to force all results to sort underneath the fileName grouping | ||
var rowSummaryIdCounter = 0; | ||
$(document).ready(function () { | ||
dataTable = $('#violations').DataTable({ | ||
columnDefs: [ | ||
{ 'visible': false, 'targets': [0] } | ||
], | ||
rowGroup: { | ||
dataSrc: ['fileName'], | ||
startRender: function (rows, group, level) { | ||
return $('<tr>' + | ||
`<td colspan="10">${group}</td>` + | ||
'</tr>' | ||
); | ||
}, | ||
endRender: function (rows, group, level) { | ||
var summary = new Map(); | ||
rows.data().pluck('severity').each( function(value, index) { | ||
var count = summary.get(value); | ||
count = count ? (count + 1) : 1; | ||
summary.set(value, count); | ||
}); | ||
const id = `summaryGroup${rowSummaryIdCounter++}`; | ||
window.setTimeout(function() { | ||
populateRowGroupChart(id, summary); | ||
}, 0); | ||
return $( | ||
'<tr>' + | ||
`<td colspan="10" class="summaryChartCell"><div class="summaryChartContainer"><canvas id="${id}"></canvas><div></td>` + | ||
'</tr>'); | ||
} | ||
}, | ||
orderFixed: [[0, 'asc']], | ||
order: [[1, 'asc'], [6, 'asc']], | ||
data: violations, | ||
paging: false, | ||
columns: [ | ||
{ data: 'fileName' }, | ||
{ data: 'severity', className: 'scannerSeverity' }, | ||
{ data: 'engine' }, | ||
{ data: 'category' }, | ||
{ data: 'ruleName', | ||
// Convert the ruleName to a hyperlink that displays the rule information | ||
'render': function(data, type, row, meta){ | ||
if(data && type === 'display'){ | ||
data = '<a href="' + row.url + '" target="__blank">' + data + '</a>'; | ||
} | ||
return data; | ||
} | ||
}, | ||
{ data: 'message' }, | ||
// 'defaultContent' provides information to the Datatables code in cases where the row | ||
// corresponds to something non file location specific. i.e. a tsconfig.json error | ||
{ data: 'line', className: 'scannerLocation', defaultContent: ''}, | ||
{ data: 'column', className: 'scannerLocation', defaultContent: ''}, | ||
{ data: 'sinkFileName', className: 'scannerLocation', defaultContent: ''}, | ||
{ data: 'sinkLine', className: 'scannerLocation', defaultContent: ''}, | ||
{ data: 'sinkColumn', className: 'scannerLocation', defaultContent: ''} | ||
], | ||
'rowCallback': function(row, data, index) { | ||
var severity = data['severity']; | ||
var bgColor = getSeverityColor(severity); | ||
if (bgColor) { | ||
$(row).find('td:eq(0)').css('background-color', bgColor); | ||
} | ||
}, | ||
'infoCallback': function( settings, start, end, max, total, pre ) { | ||
window.setTimeout(function() { | ||
populateSummaryChart(); | ||
}, 0); | ||
} | ||
}); | ||
}); | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<h1 id="reportTitle">Salesforce CLI Scanner Report</h1> | ||
<div id="summaryChart"/></div> | ||
<h4 id="summaryFiles"></h4> | ||
<h4 id="summaryViolations"></h4> | ||
<div class="fw-container"> | ||
<div class="fw-body"> | ||
<div class="content"> | ||
<table id="violations" class="table table-striped table-bordered"> | ||
<thead> | ||
<tr> | ||
<th>File Name</th> | ||
<th>Sev</th> | ||
<th>Engine</th> | ||
<th>Category</th> | ||
<th>Rule Name</th> | ||
<th>Message</th> | ||
<th>Line</th> | ||
<th>Column</th> | ||
<th>Sink File</th> | ||
<th>Sink Line</th> | ||
<th>Sink Column</th> | ||
</tr> | ||
</thead> | ||
<tbody/> | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
<div> | ||
<div id="footer">This report was generated with command <b><i>{{{commandLine}}}</i></b> from working directory <b><i>{{{workingDirectory}}}</i></b></div> | ||
</div> | ||
</body> | ||
|
||
</html> |
Oops, something went wrong.