Skip to content

Commit

Permalink
Merge pull request #129 from forcedotcom/jj/W-15639920
Browse files Browse the repository at this point in the history
NEW (Extension) @W-15639920@ Save SFGE run information in temporary location for use by delta run
  • Loading branch information
jag-j authored Sep 9, 2024
2 parents c145cfe + 222e8ed commit c71e7bb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
22 changes: 18 additions & 4 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import * as Constants from './lib/constants';
import * as path from 'path';
import { SIGKILL } from 'constants';
import * as ApexGuruFunctions from './apexguru/apex-guru-service'
import * as os from 'os';
import * as fs from 'fs';

export type RunInfo = {
diagnosticCollection?: vscode.DiagnosticCollection;
Expand All @@ -38,6 +40,8 @@ let customCancellationToken: vscode.CancellationTokenSource | null = null;

let outputChannel: vscode.LogOutputChannel;

let sfgeCachePath: string = null;

/**
* This method is invoked when the extension is first activated (this is currently configured to be when a sfdx project is loaded).
* The activation trigger can be changed by changing activationEvents in package.json
Expand Down Expand Up @@ -136,6 +140,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<vscode
}
});

sfgeCachePath = path.join(createTempDirectory(), 'sfca-graph-engine-cache.json');
const runDfaOnWorkspaceCmd = vscode.commands.registerCommand(Constants.COMMAND_RUN_DFA, async () => {
await _runDfa(context);
});
Expand Down Expand Up @@ -167,6 +172,16 @@ export async function activate(context: vscode.ExtensionContext): Promise<vscode
return Promise.resolve(context);
}

export function createTempDirectory(): string {
const tempFolderPrefix = path.join(os.tmpdir(), Constants.EXTENSION_PACK_ID);
try {
const folder = fs.mkdtempSync(tempFolderPrefix);
return folder;
} catch (err) {
throw new Error('Failed to create temporary directory');
}
}

async function _runDfa(context: vscode.ExtensionContext) {
if (violationsCacheExists()) {
const choice = await vscode.window.showQuickPick(
Expand Down Expand Up @@ -212,14 +227,13 @@ async function runDfaOnWorkspace(context: vscode.ExtensionContext) {
// We only have one project loaded on VSCode at once. So, projectDir should have only one entry and we use
// the root directory of that project as the projectDir argument to run DFA.
return _runAndDisplayDfa(context, {
commandName: Constants.COMMAND_RUN_DFA_ON_SELECTED_METHOD
commandName: Constants.COMMAND_RUN_DFA
}, customCancellationToken, null, targeting.getProjectDir());
});
}

function violationsCacheExists() {
// Returns true for now. Actual cache check will be performed as part of W-15639759.
return true;
return fs.existsSync(sfgeCachePath);
}

export function _removeDiagnosticsInRange(uri: vscode.Uri, range: vscode.Range, diagnosticCollection: vscode.DiagnosticCollection) {
Expand Down Expand Up @@ -364,7 +378,7 @@ export async function _runAndDisplayDfa(context:vscode.ExtensionContext ,runInfo
const startTime = Date.now();
try {
await verifyPluginInstallation();
const results = await new ScanRunner().runDfa([methodLevelTarget], projectDir, context);
const results = await new ScanRunner().runDfa([methodLevelTarget], projectDir, context, sfgeCachePath);
if (results.length > 0) {
const panel = vscode.window.createWebviewPanel(
'dfaResults',
Expand Down
12 changes: 9 additions & 3 deletions src/lib/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class ScanRunner {
* @param targets A list of files to be targeted by the scan
* @returns The results of the scan
*/

public async run(targets: string[]): Promise<RuleResult[]> {
// Create the arg array.
const args: string[] = await this.createPathlessArgArray(targets);
Expand All @@ -39,9 +40,9 @@ export class ScanRunner {
* @param projectDir The directory containing all files in the project to be scanned.
* @returns The HTML-formatted scan results, or an empty string if no violations were found.
*/
public async runDfa(targets: string[], projectDir: string, context: vscode.ExtensionContext): Promise<string> {
public async runDfa(targets: string[], projectDir: string, context: vscode.ExtensionContext, cacheFilePath?: string): Promise<string> {
// Create the arg array.
const args: string[] = this.createDfaArgArray(targets, projectDir);
const args: string[] = this.createDfaArgArray(targets, projectDir, cacheFilePath);

// Invoke the scanner.
const executionResult: ExecutionResult = await this.invokeDfaAnalyzer(args, context);
Expand All @@ -55,7 +56,7 @@ export class ScanRunner {
* @param targets The files/methods to be targeted.
* @param projectDir The root of the project to be scanned.
*/
private createDfaArgArray(targets: string[], projectDir: string): string[] {
private createDfaArgArray(targets: string[], projectDir: string, cacheFilePath?: string): string[] {
const args: string[] = [
'scanner', 'run', 'dfa',
`--projectdir`, projectDir,
Expand All @@ -73,6 +74,11 @@ export class ScanRunner {
args.push('--target', `${targets.join(',')}`);
}

if (cacheFilePath) {
args.push('--cachepath', cacheFilePath);
args.push('--enablecaching');
}

// There are a number of custom settings that we need to check too.
// First we should check whether warning violations are disabled.
if (SettingsManager.getGraphEngineDisableWarningViolations()) {
Expand Down
21 changes: 21 additions & 0 deletions src/test/suite/scanner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,27 @@ suite('ScanRunner', () => {
expect(args[10]).to.equal('--sfgejvmargs', 'Wrong arg');
expect(args[11]).to.equal(jvmArgs, 'Wrong arg');
});

test('Enable caching and include cache path', () => {
// ===== SETUP =====
Sinon.stub(SettingsManager, 'getGraphEngineDisableWarningViolations').returns(false);
Sinon.stub(SettingsManager, 'getGraphEngineThreadTimeout').returns(null);
Sinon.stub(SettingsManager, 'getGraphEnginePathExpansionLimit').returns(null);
Sinon.stub(SettingsManager, 'getGraphEngineJvmArgs').returns(null);
const emptyTargets = [];

// ===== TEST =====
// Call the test method helper.
const scanner: ScanRunner = new ScanRunner();
const args: string[] = (scanner as any).createDfaArgArray(emptyTargets, projectDir, 'some/path/file.json');

// ===== ASSERTIONS =====
// Verify that the right arguments were created.
expect(args).to.have.lengthOf(11, 'Wrong number of args');
expect(args[8]).to.equal('--cachepath', 'Wrong arg');
expect(args[9]).to.equal('some/path/file.json', 'Wrong arg');
expect(args[10]).to.equal('--enablecaching', 'Wrong arg');
});
});
});

Expand Down

0 comments on commit c71e7bb

Please sign in to comment.