sfdx-hardis 5.5.0 → 5.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/lib/commands/hardis/doc/project2markdown.js +16 -2
- package/lib/commands/hardis/doc/project2markdown.js.map +1 -1
- package/lib/commands/hardis/org/diagnose/unused-apex-classes.d.ts +23 -0
- package/lib/commands/hardis/org/diagnose/unused-apex-classes.js +243 -0
- package/lib/commands/hardis/org/diagnose/unused-apex-classes.js.map +1 -0
- package/lib/commands/hardis/org/monitor/all.d.ts +7 -0
- package/lib/commands/hardis/org/monitor/all.js +102 -81
- package/lib/commands/hardis/org/monitor/all.js.map +1 -1
- package/lib/commands/hardis/org/user/activateinvalid.js +1 -1
- package/lib/commands/hardis/org/user/activateinvalid.js.map +1 -1
- package/lib/common/notifProvider/index.d.ts +1 -1
- package/lib/common/notifProvider/index.js.map +1 -1
- package/lib/common/utils/apiUtils.js +10 -2
- package/lib/common/utils/apiUtils.js.map +1 -1
- package/lib/common/utils/docUtils.js +0 -1
- package/lib/common/utils/docUtils.js.map +1 -1
- package/oclif.lock +895 -706
- package/oclif.manifest.json +212 -3
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
Note: Can be used with `sfdx plugins:install sfdx-hardis@beta` and docker image `hardisgroupcom/sfdx-hardis@beta`
|
|
6
6
|
|
|
7
|
+
## [5.6.1] 2024-11-11
|
|
8
|
+
|
|
9
|
+
- Fix hardis:org:user:activateinvalid interactive mode
|
|
10
|
+
- Update Dockerfile email address
|
|
11
|
+
- Upgrade default Grafana Dashboards to add Unused Apex Classes indicator
|
|
12
|
+
- Update hardis:org:diagnose:unused-apex-classes and hardis:doc:packagexml2markdown documentation
|
|
13
|
+
|
|
14
|
+
## [5.6.0] 2024-11-09
|
|
15
|
+
|
|
16
|
+
- New command hardis:org:diagnose:unused-apex-classes, to detect Apex classes (Batch,Queueable,Schedulable) that has not been called for more than 365 days, that might be deleted to improve apex tests performances
|
|
17
|
+
- hardis:doc:project2markdown: Update documentation
|
|
18
|
+
- Polish CI/CD home doc
|
|
19
|
+
- Refactor the build of [hardis:org:monitor:all](https://sfdx-hardis.cloudity.com/hardis/org/monitor/all/) documentation
|
|
20
|
+
- Fix issue with ToolingApi calls: handle paginated results instead of only the first 200 records.
|
|
21
|
+
|
|
7
22
|
## [5.5.0] 2024-11-03
|
|
8
23
|
|
|
9
24
|
- hardis:doc:packagexml2markdown: Generate markdown documentation from a package.xml file
|
|
@@ -16,7 +16,21 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
|
16
16
|
const messages = Messages.loadMessages('sfdx-hardis', 'org');
|
|
17
17
|
export default class Project2Markdown extends SfCommand {
|
|
18
18
|
static title = 'SFDX Project to Markdown';
|
|
19
|
-
static description = `Generates a markdown documentation from a SFDX project
|
|
19
|
+
static description = `Generates a markdown documentation from a SFDX project
|
|
20
|
+
|
|
21
|
+
- Package.xml files
|
|
22
|
+
- Source Packages
|
|
23
|
+
- sfdx-hardis configuration
|
|
24
|
+
- Installed packages
|
|
25
|
+
|
|
26
|
+
Can work on any sfdx project, no need for it to be a sfdx-hardis flavored one.
|
|
27
|
+
|
|
28
|
+
Generated markdown files will be written in **docs** folder (except README.md where a link to doc index is added)
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
`;
|
|
20
34
|
static examples = [
|
|
21
35
|
'$ sf hardis:doc:project2markdown',
|
|
22
36
|
];
|
|
@@ -233,7 +247,7 @@ export default class Project2Markdown extends SfCommand {
|
|
|
233
247
|
// Monitoring package files
|
|
234
248
|
{
|
|
235
249
|
path: "manifest/package-all-org-items.xml",
|
|
236
|
-
description: "Contains the entire list of metadatas that are present in the monitored
|
|
250
|
+
description: "Contains the entire list of metadatas that are present in the monitored org (not all of them are in the git backup)"
|
|
237
251
|
},
|
|
238
252
|
{
|
|
239
253
|
path: "manifest/package-backup-items.xml",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project2markdown.js","sourceRoot":"","sources":["../../../../src/commands/hardis/doc/project2markdown.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,CAAC,MAAM,OAAO,CAAC;AACtB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACtH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AAE7D,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,SAAc;IACnD,MAAM,CAAC,KAAK,GAAG,0BAA0B,CAAC;IAE1C,MAAM,CAAC,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"project2markdown.js","sourceRoot":"","sources":["../../../../src/commands/hardis/doc/project2markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { AnyJson } from '@salesforce/ts-types';
|
|
3
|
+
export default class DiagnoseUnusedApexClasses extends SfCommand<any> {
|
|
4
|
+
static title: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: any;
|
|
8
|
+
static requiresProject: boolean;
|
|
9
|
+
protected debugMode: boolean;
|
|
10
|
+
protected outputFile: any;
|
|
11
|
+
protected outputFilesRes: any;
|
|
12
|
+
protected lastNdays: number;
|
|
13
|
+
protected asyncClassList: any[];
|
|
14
|
+
protected unusedNumber: number;
|
|
15
|
+
protected statusCode: number;
|
|
16
|
+
run(): Promise<AnyJson>;
|
|
17
|
+
private findCronTriggers;
|
|
18
|
+
private displaySummaryOutput;
|
|
19
|
+
private matchClassesWithJobs;
|
|
20
|
+
private findLatestApexJobsForEachClass;
|
|
21
|
+
private listAsyncApexClasses;
|
|
22
|
+
private manageNotifications;
|
|
23
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/* jscpd:ignore-start */
|
|
2
|
+
import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core';
|
|
3
|
+
import { Messages } from '@salesforce/core';
|
|
4
|
+
import c from 'chalk';
|
|
5
|
+
import { uxLog } from '../../../../common/utils/index.js';
|
|
6
|
+
import { soqlQuery, soqlQueryTooling } from '../../../../common/utils/apiUtils.js';
|
|
7
|
+
import { generateCsvFile, generateReportPath } from '../../../../common/utils/filesUtils.js';
|
|
8
|
+
import { NotifProvider } from '../../../../common/notifProvider/index.js';
|
|
9
|
+
import { getNotificationButtons, getOrgMarkdown, getSeverityIcon } from '../../../../common/utils/notifUtils.js';
|
|
10
|
+
import { CONSTANTS } from '../../../../config/index.js';
|
|
11
|
+
import moment from 'moment';
|
|
12
|
+
import columnify from 'columnify';
|
|
13
|
+
import sortArray from 'sort-array';
|
|
14
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
15
|
+
const messages = Messages.loadMessages('sfdx-hardis', 'org');
|
|
16
|
+
export default class DiagnoseUnusedApexClasses extends SfCommand {
|
|
17
|
+
static title = 'Detect unused Apex classes in an org';
|
|
18
|
+
static description = `List all async Apex classes (Batch,Queueable,Schedulable) that has not been called for more than 365 days.
|
|
19
|
+
|
|
20
|
+
The result class list probably can be removed from the project, and that will improve your test classes performances :)
|
|
21
|
+
|
|
22
|
+
The number of unused day is overridable using --days option.
|
|
23
|
+
|
|
24
|
+
The command uses queries on AsyncApexJob and CronTrigger technical tables to build the result.
|
|
25
|
+
|
|
26
|
+
This command is part of [sfdx-hardis Monitoring](${CONSTANTS.DOC_URL_ROOT}/salesforce-monitoring-unused-apex-classes/) and can output Grafana, Slack and MsTeams Notifications.
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
`;
|
|
30
|
+
static examples = [
|
|
31
|
+
'$ sf hardis:org:diagnose:unused-apex-classes',
|
|
32
|
+
'$ sf hardis:org:diagnose:unused-apex-classes --days 700'
|
|
33
|
+
];
|
|
34
|
+
//Comment default values to test the prompts
|
|
35
|
+
static flags = {
|
|
36
|
+
outputfile: Flags.string({
|
|
37
|
+
char: 'f',
|
|
38
|
+
description: 'Force the path and name of output report file. Must end with .csv',
|
|
39
|
+
}),
|
|
40
|
+
days: Flags.integer({
|
|
41
|
+
char: 't',
|
|
42
|
+
description: 'Extracts the users that have been inactive for the amount of days specified. In CI, default is 180 days',
|
|
43
|
+
}),
|
|
44
|
+
debug: Flags.boolean({
|
|
45
|
+
char: 'd',
|
|
46
|
+
default: false,
|
|
47
|
+
description: messages.getMessage('debugMode'),
|
|
48
|
+
}),
|
|
49
|
+
websocket: Flags.string({
|
|
50
|
+
description: messages.getMessage('websocket'),
|
|
51
|
+
}),
|
|
52
|
+
skipauth: Flags.boolean({
|
|
53
|
+
description: 'Skip authentication check when a default username is required',
|
|
54
|
+
}),
|
|
55
|
+
'target-org': requiredOrgFlagWithDeprecations,
|
|
56
|
+
};
|
|
57
|
+
// Set this to true if your command requires a project workspace; 'requiresProject' is false by default
|
|
58
|
+
static requiresProject = false;
|
|
59
|
+
debugMode = false;
|
|
60
|
+
outputFile;
|
|
61
|
+
outputFilesRes = {};
|
|
62
|
+
lastNdays;
|
|
63
|
+
asyncClassList = [];
|
|
64
|
+
unusedNumber = 0;
|
|
65
|
+
statusCode = 0;
|
|
66
|
+
/* jscpd:ignore-end */
|
|
67
|
+
async run() {
|
|
68
|
+
const { flags } = await this.parse(DiagnoseUnusedApexClasses);
|
|
69
|
+
this.debugMode = flags.debug || false;
|
|
70
|
+
this.outputFile = flags.outputfile || null;
|
|
71
|
+
this.lastNdays = Number(flags.days || 365);
|
|
72
|
+
// Calculate lastNdays to use
|
|
73
|
+
const conn = flags['target-org'].getConnection();
|
|
74
|
+
// Retrieve the list of Apex class that are BatchApex, ScheduledApex or Queueable
|
|
75
|
+
await this.listAsyncApexClasses(conn);
|
|
76
|
+
// Find latest AsyncJob for each class
|
|
77
|
+
const latestJobs = await this.findLatestApexJobsForEachClass(conn);
|
|
78
|
+
const jobTriggers = await this.findCronTriggers(conn);
|
|
79
|
+
// Aggregate results
|
|
80
|
+
this.matchClassesWithJobs(latestJobs, jobTriggers);
|
|
81
|
+
// Generate output CSV file
|
|
82
|
+
this.outputFile = await generateReportPath('unused-apex-classes', this.outputFile);
|
|
83
|
+
this.outputFilesRes = await generateCsvFile(this.asyncClassList, this.outputFile);
|
|
84
|
+
if ((this.argv || []).includes('unused-apex-classes')) {
|
|
85
|
+
process.exitCode = this.statusCode;
|
|
86
|
+
}
|
|
87
|
+
// Manage notifications
|
|
88
|
+
await this.manageNotifications();
|
|
89
|
+
// Build result text
|
|
90
|
+
const summary = this.displaySummaryOutput();
|
|
91
|
+
// Return an object to be displayed with --json
|
|
92
|
+
return {
|
|
93
|
+
status: this.statusCode,
|
|
94
|
+
summary: summary,
|
|
95
|
+
asyncClassList: this.asyncClassList,
|
|
96
|
+
csvLogFile: this.outputFile,
|
|
97
|
+
xlsxLogFile: this.outputFilesRes.xlsxFile,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async findCronTriggers(conn) {
|
|
101
|
+
const cronTriggersQuery = `SELECT Id, CronJobDetail.JobType, CronJobDetail.Name, State, NextFireTime FROM CronTrigger WHERE State IN ('WAITING', 'ACQUIRED')`;
|
|
102
|
+
const cronTriggersResult = await soqlQuery(cronTriggersQuery, conn);
|
|
103
|
+
return cronTriggersResult.records;
|
|
104
|
+
}
|
|
105
|
+
displaySummaryOutput() {
|
|
106
|
+
let summary = `All async apex classes have been called during the latest ${this.lastNdays} days.`;
|
|
107
|
+
if (this.unusedNumber > 0) {
|
|
108
|
+
summary = `${this.unusedNumber} apex classes might not be used anymore.`;
|
|
109
|
+
const summaryClasses = this.asyncClassList.map(apexClass => {
|
|
110
|
+
return {
|
|
111
|
+
name: apexClass.Name,
|
|
112
|
+
latestJobDate: apexClass.latestJobDate ? moment(apexClass.latestJobDate).format('YYYY-MM-DD hh:mm') : "Not found",
|
|
113
|
+
latestJobRunDays: apexClass.latestJobRunDays,
|
|
114
|
+
nextJobDate: apexClass.nextJobDate ? moment(apexClass.nextJobDate).format('YYYY-MM-DD hh:mm') : "None",
|
|
115
|
+
queued: apexClass.queued,
|
|
116
|
+
AsyncType: apexClass.AsyncType,
|
|
117
|
+
severity: `${apexClass.severityIcon} ${apexClass.severity}`
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
uxLog(this, c.yellow("\n" + columnify(summaryClasses)));
|
|
121
|
+
}
|
|
122
|
+
if (this.unusedNumber > 0) {
|
|
123
|
+
uxLog(this, c.yellow(summary));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
uxLog(this, c.green(summary));
|
|
127
|
+
}
|
|
128
|
+
return summary;
|
|
129
|
+
}
|
|
130
|
+
matchClassesWithJobs(latestJobsAll, cronTriggers) {
|
|
131
|
+
this.asyncClassList = this.asyncClassList.map(apexClass => {
|
|
132
|
+
const futureJobs = cronTriggers.filter(cronJob => apexClass.Name === cronJob.CronJobDetail.Name);
|
|
133
|
+
apexClass.nextJobDate = "";
|
|
134
|
+
apexClass.queued = false;
|
|
135
|
+
if (futureJobs.length > 0) {
|
|
136
|
+
apexClass.nextJobDate = futureJobs[0].NextFireTime;
|
|
137
|
+
}
|
|
138
|
+
const relatedJobs = latestJobsAll.filter(job => job.ApexClassId === apexClass.Id);
|
|
139
|
+
if (relatedJobs.length === 0) {
|
|
140
|
+
apexClass.latestJobDate = "";
|
|
141
|
+
apexClass.latestJobRunDays = 99999;
|
|
142
|
+
if (apexClass.nextJobDate === "") {
|
|
143
|
+
apexClass.severity = "error";
|
|
144
|
+
this.unusedNumber++;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const queuedJobs = relatedJobs.filter(job => job.Status === "Queued");
|
|
149
|
+
if (queuedJobs.length > 0) {
|
|
150
|
+
apexClass.queued = true;
|
|
151
|
+
}
|
|
152
|
+
apexClass.latestJobDate = relatedJobs[0].expr0;
|
|
153
|
+
const today = moment();
|
|
154
|
+
apexClass.latestJobRunDays = today.diff(apexClass.latestJobDate, 'days');
|
|
155
|
+
if (apexClass.latestJobRunDays > this.lastNdays && apexClass.nextJobDate === "" && apexClass.queued === false) {
|
|
156
|
+
apexClass.severity = "warning";
|
|
157
|
+
this.unusedNumber++;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
apexClass.severity = "info";
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
apexClass.severityIcon = getSeverityIcon(apexClass.severity);
|
|
164
|
+
delete apexClass.Id;
|
|
165
|
+
return apexClass;
|
|
166
|
+
});
|
|
167
|
+
this.asyncClassList = sortArray(this.asyncClassList, { by: ['latestJobRunDays', 'Name'], order: ['desc', 'asc'] });
|
|
168
|
+
if (this.unusedNumber > 0) {
|
|
169
|
+
this.statusCode = 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async findLatestApexJobsForEachClass(conn) {
|
|
173
|
+
const classIds = this.asyncClassList.map(apexClass => apexClass.Id);
|
|
174
|
+
const query = `SELECT ApexClassId, Status, MAX(CreatedDate)` +
|
|
175
|
+
` FROM AsyncApexJob` +
|
|
176
|
+
` WHERE JobType IN ('BatchApex', 'ScheduledApex', 'Queueable') AND ApexClassId IN ('${classIds.join("','")}') GROUP BY ApexClassId, Status`;
|
|
177
|
+
const latestJobQueryRes = await soqlQuery(query, conn);
|
|
178
|
+
const latestJobs = latestJobQueryRes.records;
|
|
179
|
+
return latestJobs;
|
|
180
|
+
}
|
|
181
|
+
async listAsyncApexClasses(conn) {
|
|
182
|
+
const classListRes = await soqlQueryTooling("SELECT Id, Name, Body FROM ApexClass WHERE ManageableState ='unmanaged' ORDER BY Name ASC", conn);
|
|
183
|
+
const allClassList = classListRes.records || [];
|
|
184
|
+
for (const classItem of allClassList) {
|
|
185
|
+
if (classItem.Body.includes("implements Database.Batchable")) {
|
|
186
|
+
this.asyncClassList.push({ Id: classItem.Id, Name: classItem.Name, AsyncType: "Database.Batchable" });
|
|
187
|
+
}
|
|
188
|
+
else if (classItem.Body.includes("implements Queueable")) {
|
|
189
|
+
this.asyncClassList.push({ Id: classItem.Id, Name: classItem.Name, AsyncType: "Queueable" });
|
|
190
|
+
}
|
|
191
|
+
else if (classItem.Body.includes("implements Schedulable")) {
|
|
192
|
+
this.asyncClassList.push({ Id: classItem.Id, Name: classItem.Name, AsyncType: "Schedulable" });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async manageNotifications() {
|
|
197
|
+
const { flags } = await this.parse(DiagnoseUnusedApexClasses);
|
|
198
|
+
// Build notification
|
|
199
|
+
const orgMarkdown = await getOrgMarkdown(flags['target-org']?.getConnection()?.instanceUrl);
|
|
200
|
+
const notifButtons = await getNotificationButtons();
|
|
201
|
+
let notifSeverity = 'log';
|
|
202
|
+
let notifText = `All async apex classes of org ${orgMarkdown} have been called during the latest ${this.lastNdays} days.`;
|
|
203
|
+
let attachments = [];
|
|
204
|
+
if (this.unusedNumber > 0) {
|
|
205
|
+
notifSeverity = 'warning';
|
|
206
|
+
notifText = `${this.unusedNumber} apex classes might not be used anymore.`;
|
|
207
|
+
const notifDetailText = this.asyncClassList
|
|
208
|
+
.filter(apexClass => ["warning", "error"].includes(apexClass.severity))
|
|
209
|
+
.map(apexClass => {
|
|
210
|
+
if (apexClass.nextJobDate) {
|
|
211
|
+
return `• *${apexClass.Name}*: Will run on ${moment(apexClass.nextJobDate.format('YYYY-MM-DD hh:mm'))}`;
|
|
212
|
+
}
|
|
213
|
+
else if (apexClass.queued) {
|
|
214
|
+
return `• *${apexClass.Name}*: A future job is queued`;
|
|
215
|
+
}
|
|
216
|
+
else if (apexClass.latestJobRunDays < 99999) {
|
|
217
|
+
return `• *${apexClass.Name}*: ${apexClass.latestJobRunDays} days`;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
return `• *${apexClass.Name}*: No job found`;
|
|
221
|
+
}
|
|
222
|
+
}).join("\n");
|
|
223
|
+
attachments = [{ text: notifDetailText }];
|
|
224
|
+
}
|
|
225
|
+
/* jscpd:ignore-start */
|
|
226
|
+
// Send notifications
|
|
227
|
+
globalThis.jsForceConn = flags['target-org']?.getConnection(); // Required for some notifications providers like Email
|
|
228
|
+
NotifProvider.postNotifications({
|
|
229
|
+
type: 'UNUSED_APEX_CLASSES',
|
|
230
|
+
text: notifText,
|
|
231
|
+
attachments: attachments,
|
|
232
|
+
buttons: notifButtons,
|
|
233
|
+
severity: notifSeverity,
|
|
234
|
+
attachedFiles: this.outputFilesRes.xlsxFile ? [this.outputFilesRes.xlsxFile] : [],
|
|
235
|
+
logElements: this.asyncClassList,
|
|
236
|
+
data: { metric: this.unusedNumber },
|
|
237
|
+
metrics: { unusedApexClasses: this.unusedNumber },
|
|
238
|
+
});
|
|
239
|
+
/* jscpd:ignore-end */
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=unused-apex-classes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unused-apex-classes.js","sourceRoot":"","sources":["../../../../../src/commands/hardis/org/diagnose/unused-apex-classes.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,11 +2,18 @@ import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
|
2
2
|
import { AnyJson } from '@salesforce/ts-types';
|
|
3
3
|
export default class MonitorAll extends SfCommand<any> {
|
|
4
4
|
static title: string;
|
|
5
|
+
static monitoringCommandsDefault: {
|
|
6
|
+
key: string;
|
|
7
|
+
title: string;
|
|
8
|
+
command: string;
|
|
9
|
+
frequency: string;
|
|
10
|
+
}[];
|
|
5
11
|
static description: string;
|
|
6
12
|
static examples: string[];
|
|
7
13
|
static flags: any;
|
|
8
14
|
static requiresProject: boolean;
|
|
9
15
|
protected static triggerNotification: boolean;
|
|
10
16
|
protected debugMode: boolean;
|
|
17
|
+
static getDefaultCommandsMarkdown(): string;
|
|
11
18
|
run(): Promise<AnyJson>;
|
|
12
19
|
}
|
|
@@ -8,6 +8,92 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
|
8
8
|
const messages = Messages.loadMessages('sfdx-hardis', 'org');
|
|
9
9
|
export default class MonitorAll extends SfCommand {
|
|
10
10
|
static title = 'Monitor org';
|
|
11
|
+
static monitoringCommandsDefault = [
|
|
12
|
+
{
|
|
13
|
+
key: 'AUDIT_TRAIL',
|
|
14
|
+
title: 'Detect suspect setup actions in major org',
|
|
15
|
+
command: 'sf hardis:org:diagnose:audittrail',
|
|
16
|
+
frequency: 'daily',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: 'LEGACY_API',
|
|
20
|
+
title: 'Detect calls to deprecated API versions',
|
|
21
|
+
command: 'sf hardis:org:diagnose:legacyapi',
|
|
22
|
+
frequency: 'daily',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'ORG_LIMITS',
|
|
26
|
+
title: 'Detect if org limits are close to be reached',
|
|
27
|
+
command: 'sf hardis:org:monitor:limits',
|
|
28
|
+
frequency: 'daily',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: 'LICENSES',
|
|
32
|
+
title: 'Extract licenses information',
|
|
33
|
+
command: 'sf hardis:org:diagnose:licenses',
|
|
34
|
+
frequency: 'weekly',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'LINT_ACCESS',
|
|
38
|
+
title: 'Detect custom elements with no access rights defined in permission sets',
|
|
39
|
+
command: 'sf hardis:lint:access',
|
|
40
|
+
frequency: 'weekly',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
key: 'UNUSED_LICENSES',
|
|
44
|
+
title: 'Detect permission set licenses that are assigned to users that do not need them',
|
|
45
|
+
command: 'sf hardis:org:diagnose:unusedlicenses',
|
|
46
|
+
frequency: 'weekly',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
key: 'UNUSED_USERS',
|
|
50
|
+
title: 'Detect active users without recent logins',
|
|
51
|
+
command: 'sf hardis:org:diagnose:unusedusers',
|
|
52
|
+
frequency: 'weekly',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
key: 'ACTIVE_USERS',
|
|
56
|
+
title: 'Detect active users with recent logins',
|
|
57
|
+
command: 'sf hardis:org:diagnose:unusedusers --returnactiveusers',
|
|
58
|
+
frequency: 'weekly',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
key: 'ORG_INFO',
|
|
62
|
+
title: 'Get org info + SF instance info + next major upgrade date',
|
|
63
|
+
command: 'sf hardis:org:diagnose:instanceupgrade',
|
|
64
|
+
frequency: 'weekly',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
key: 'RELEASE_UPDATES',
|
|
68
|
+
title: 'Gather warnings about incoming and overdue Release Updates',
|
|
69
|
+
command: 'sf hardis:org:diagnose:releaseupdates',
|
|
70
|
+
frequency: 'weekly',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: 'UNUSED_METADATAS',
|
|
74
|
+
title: 'Detect custom labels and custom permissions that are not in use',
|
|
75
|
+
command: 'sf hardis:lint:unusedmetadatas',
|
|
76
|
+
frequency: 'weekly',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
key: 'UNUSED_APEX_CLASSES',
|
|
80
|
+
title: 'Detect unused Apex classes in an org',
|
|
81
|
+
command: 'sf hardis:org:diagnose:unused-apex-classes',
|
|
82
|
+
frequency: 'weekly',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
key: 'METADATA_STATUS',
|
|
86
|
+
title: 'Detect inactive metadata',
|
|
87
|
+
command: 'sf hardis:lint:metadatastatus',
|
|
88
|
+
frequency: 'weekly',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
key: 'MISSING_ATTRIBUTES',
|
|
92
|
+
title: 'Detect missing description on custom field',
|
|
93
|
+
command: 'sf hardis:lint:missingattributes',
|
|
94
|
+
frequency: 'weekly',
|
|
95
|
+
},
|
|
96
|
+
];
|
|
11
97
|
static description = `Monitor org, generate reports and sends notifications
|
|
12
98
|
|
|
13
99
|
You can disable some commands defining either a **monitoringDisable** property in \`.sfdx-hardis.yml\`, or a comma separated list in env variable **MONITORING_DISABLE**
|
|
@@ -41,6 +127,10 @@ monitoringCommands:
|
|
|
41
127
|
|
|
42
128
|
You can force the daily run of all commands by defining env var \`MONITORING_IGNORE_FREQUENCY=true\`
|
|
43
129
|
|
|
130
|
+
The default list of commands is the following:
|
|
131
|
+
|
|
132
|
+
${this.getDefaultCommandsMarkdown()}
|
|
133
|
+
|
|
44
134
|
`;
|
|
45
135
|
static examples = ['$ sf hardis:org:monitor:all'];
|
|
46
136
|
static flags = {
|
|
@@ -63,93 +153,24 @@ You can force the daily run of all commands by defining env var \`MONITORING_IGN
|
|
|
63
153
|
static triggerNotification = true;
|
|
64
154
|
debugMode = false;
|
|
65
155
|
/* jscpd:ignore-end */
|
|
156
|
+
static getDefaultCommandsMarkdown() {
|
|
157
|
+
const mdLines = [
|
|
158
|
+
"| Key | Description | Command | Frequency |",
|
|
159
|
+
"| :---: | :---- | :---- | :-----: |",
|
|
160
|
+
];
|
|
161
|
+
for (const cmd of MonitorAll.monitoringCommandsDefault) {
|
|
162
|
+
const commandDocUrl = `${CONSTANTS.DOC_URL_ROOT}/${cmd.command.split(" ")[1].replaceAll(":", "/")}`;
|
|
163
|
+
mdLines.push(`| [${cmd.key}](${commandDocUrl}) | ${cmd.title} | [${cmd.command}](${commandDocUrl}) | ${cmd.frequency} |`);
|
|
164
|
+
}
|
|
165
|
+
return mdLines.join("\n");
|
|
166
|
+
}
|
|
66
167
|
async run() {
|
|
67
168
|
const { flags } = await this.parse(MonitorAll);
|
|
68
169
|
this.debugMode = flags.debug || false;
|
|
69
170
|
// Build target org full manifest
|
|
70
171
|
uxLog(this, c.cyan('Running monitoring scripts for org ' + c.bold(flags['target-org'].getConnection().instanceUrl)) + ' ...');
|
|
71
|
-
const monitoringCommandsDefault = [
|
|
72
|
-
{
|
|
73
|
-
key: 'AUDIT_TRAIL',
|
|
74
|
-
title: 'Detect suspect setup actions in major org',
|
|
75
|
-
command: 'sf hardis:org:diagnose:audittrail',
|
|
76
|
-
frequency: 'daily',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
key: 'LEGACY_API',
|
|
80
|
-
title: 'Detect calls to deprecated API versions',
|
|
81
|
-
command: 'sf hardis:org:diagnose:legacyapi',
|
|
82
|
-
frequency: 'daily',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
key: 'ORG_LIMITS',
|
|
86
|
-
title: 'Detect if org limits are close to be reached',
|
|
87
|
-
command: 'sf hardis:org:monitor:limits',
|
|
88
|
-
frequency: 'daily',
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
key: 'LICENSES',
|
|
92
|
-
title: 'Extract licenses information',
|
|
93
|
-
command: 'sf hardis:org:diagnose:licenses',
|
|
94
|
-
frequency: 'weekly',
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
key: 'LINT_ACCESS',
|
|
98
|
-
title: 'Detect custom elements with no access rights defined in permission sets',
|
|
99
|
-
command: 'sf hardis:lint:access',
|
|
100
|
-
frequency: 'weekly',
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
key: 'UNUSED_LICENSES',
|
|
104
|
-
title: 'Detect permission set licenses that are assigned to users that do not need them',
|
|
105
|
-
command: 'sf hardis:org:diagnose:unusedlicenses',
|
|
106
|
-
frequency: 'weekly',
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
key: 'UNUSED_USERS',
|
|
110
|
-
title: 'Detect active users without recent logins',
|
|
111
|
-
command: 'sf hardis:org:diagnose:unusedusers',
|
|
112
|
-
frequency: 'weekly',
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
key: 'ACTIVE_USERS',
|
|
116
|
-
title: 'Detect active users with recent logins',
|
|
117
|
-
command: 'sf hardis:org:diagnose:unusedusers --returnactiveusers',
|
|
118
|
-
frequency: 'weekly',
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
key: 'ORG_INFO',
|
|
122
|
-
title: 'Get org info + SF instance info + next major upgrade date',
|
|
123
|
-
command: 'sf hardis:org:diagnose:instanceupgrade',
|
|
124
|
-
frequency: 'weekly',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
key: 'RELEASE_UPDATES',
|
|
128
|
-
title: 'Gather warnings about incoming and overdue Release Updates',
|
|
129
|
-
command: 'sf hardis:org:diagnose:releaseupdates',
|
|
130
|
-
frequency: 'weekly',
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
key: 'UNUSED_METADATAS',
|
|
134
|
-
title: 'Detect custom labels and custom permissions that are not in use',
|
|
135
|
-
command: 'sf hardis:lint:unusedmetadatas',
|
|
136
|
-
frequency: 'weekly',
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
key: 'METADATA_STATUS',
|
|
140
|
-
title: 'Detect inactive metadata',
|
|
141
|
-
command: 'sf hardis:lint:metadatastatus',
|
|
142
|
-
frequency: 'weekly',
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
key: 'MISSING_ATTRIBUTES',
|
|
146
|
-
title: 'Detect missing description on custom field',
|
|
147
|
-
command: 'sf hardis:lint:missingattributes',
|
|
148
|
-
frequency: 'weekly',
|
|
149
|
-
},
|
|
150
|
-
];
|
|
151
172
|
const config = await getConfig('user');
|
|
152
|
-
const commands = monitoringCommandsDefault.concat(config.monitoringCommands || []);
|
|
173
|
+
const commands = MonitorAll.monitoringCommandsDefault.concat(config.monitoringCommands || []);
|
|
153
174
|
const monitoringDisable = config.monitoringDisable ?? (process.env?.MONITORING_DISABLE ? process.env.MONITORING_DISABLE.split(',') : []);
|
|
154
175
|
let success = true;
|
|
155
176
|
const commandsSummary = [];
|