Skip to content

Commit 0842f31

Browse files
committed
CDS extractor cleanup checkpoint 3
1 parent 581c29b commit 0842f31

File tree

14 files changed

+751
-272
lines changed

14 files changed

+751
-272
lines changed

extractors/cds/tools/cds-extractor.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { addCompilationDiagnostic } from './src/diagnostics';
99
import { configureLgtmIndexFilters, setupAndValidateEnvironment } from './src/environment';
1010
import {
1111
cdsExtractorLog,
12+
generateStatusReport,
1213
logExtractorStart,
1314
logExtractorStop,
1415
logPerformanceMilestone,
@@ -85,7 +86,7 @@ let dependencyGraph;
8586

8687
try {
8788
logPerformanceTrackingStart('Dependency Graph Build');
88-
dependencyGraph = buildCdsProjectDependencyGraph(sourceRoot, __dirname);
89+
dependencyGraph = buildCdsProjectDependencyGraph(sourceRoot);
8990
logPerformanceTrackingStop('Dependency Graph Build');
9091

9192
logPerformanceMilestone(
@@ -234,18 +235,36 @@ configureLgtmIndexFilters();
234235
// Run CodeQL's JavaScript extractor to process the .cds source files and
235236
// the compiled .cds.json files.
236237
logPerformanceTrackingStart('JavaScript Extraction');
238+
const extractionStartTime = Date.now();
237239
const extractorResult = runJavaScriptExtractor(sourceRoot, autobuildScriptPath, codeqlExePath);
240+
const extractionEndTime = Date.now();
238241
logPerformanceTrackingStop('JavaScript Extraction');
239242

243+
// Update the dependency graph's performance metrics with the extraction duration
244+
dependencyGraph.statusSummary.performance.extractionDurationMs =
245+
extractionEndTime - extractionStartTime;
246+
247+
// Calculate total duration by summing all phases
248+
const totalDuration =
249+
dependencyGraph.statusSummary.performance.parsingDurationMs +
250+
dependencyGraph.statusSummary.performance.compilationDurationMs +
251+
dependencyGraph.statusSummary.performance.extractionDurationMs;
252+
dependencyGraph.statusSummary.performance.totalDurationMs = totalDuration;
253+
240254
if (!extractorResult.success && extractorResult.error) {
241255
cdsExtractorLog('error', `Error running JavaScript extractor: ${extractorResult.error}`);
242256
logExtractorStop(false, 'JavaScript extractor failed');
243257
} else {
244258
logExtractorStop(true, 'CDS extraction completed successfully');
245259
}
246260

261+
cdsExtractorLog(
262+
'info',
263+
'CDS Extractor Status Report : Final...\n' + generateStatusReport(dependencyGraph),
264+
);
265+
247266
// Use the `cds-extractor.js` name in the log message as that is the name of the script
248267
// that is actually run by the `codeql database index-files` command. This TypeScript
249268
// file is where the code/logic is edited/implemented, but the runnable script is
250269
// generated by the TypeScript compiler and is named `cds-extractor.js`.
251-
console.log(`Completed run of cds-extractor.js script for CDS extractor.`);
270+
console.log(`Completed run of the cds-extractor.js script for the CDS extractor.`);

extractors/cds/tools/src/cds/compiler/command.ts

Lines changed: 1 addition & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,7 @@ import { fileExists } from '../../filesystem';
88
import { cdsExtractorLog } from '../../logging';
99

1010
/**
11-
* Interface for detailed CDS command analysis results
12-
*/
13-
export interface CdsCommandAnalysis {
14-
selectedCommand: string;
15-
selectedVersion?: string;
16-
availableCommands: Array<{
17-
strategy: string;
18-
command: string;
19-
version?: string;
20-
error?: string;
21-
}>;
22-
}
23-
24-
/**
25-
* Cache for CDS command test results to avoid repeated testing
11+
* Cache for CDS command test results to avoid running the same CLI commands repeatedly.
2612
*/
2713
interface CdsCommandCache {
2814
/** Map of command strings to their test results */
@@ -145,94 +131,6 @@ function getBestCdsCommand(cacheDir: string | undefined, sourceRoot: string): st
145131
return 'npx -y --package @sap/cds-dk cds';
146132
}
147133

148-
/**
149-
* Get detailed command analysis for debug purposes
150-
* This replaces the old performComprehensiveAnalysis function
151-
*/
152-
export function getCommandAnalysisForDebug(
153-
cacheDir: string | undefined,
154-
sourceRoot: string,
155-
): CdsCommandAnalysis {
156-
try {
157-
initializeCdsCommandCache(sourceRoot);
158-
159-
const availableCommands: CdsCommandAnalysis['availableCommands'] = [];
160-
let selectedCommand: string | null = null;
161-
let selectedVersion: string | undefined;
162-
163-
// Test cache directory if provided
164-
if (cacheDir) {
165-
const localCdsBin = join(cacheDir, 'node_modules', '.bin', 'cds');
166-
const result = testCdsCommand(localCdsBin, sourceRoot);
167-
168-
availableCommands.push({
169-
strategy: 'provided-cache',
170-
command: localCdsBin,
171-
version: result.version,
172-
error: result.error,
173-
});
174-
175-
if (result.works && !selectedCommand) {
176-
selectedCommand = localCdsBin;
177-
selectedVersion = result.version;
178-
}
179-
}
180-
181-
// Test all available cache directories
182-
for (const availableCacheDir of cdsCommandCache.availableCacheDirs) {
183-
const localCdsBin = join(availableCacheDir, 'node_modules', '.bin', 'cds');
184-
const result = testCdsCommand(localCdsBin, sourceRoot);
185-
186-
availableCommands.push({
187-
strategy: 'cached-local',
188-
command: localCdsBin,
189-
version: result.version,
190-
error: result.error,
191-
});
192-
193-
if (result.works && !selectedCommand) {
194-
selectedCommand = localCdsBin;
195-
selectedVersion = result.version;
196-
}
197-
}
198-
199-
// Test global commands
200-
const globalCommands = [
201-
{ command: 'cds', strategy: 'global-cds' },
202-
{ command: 'npx -y --package @sap/cds-dk cds', strategy: 'npx-cds-dk' },
203-
{ command: 'npx -y --package @sap/cds cds', strategy: 'npx-cds' },
204-
];
205-
206-
for (const { command, strategy } of globalCommands) {
207-
const result = testCdsCommand(command, sourceRoot);
208-
209-
availableCommands.push({
210-
strategy,
211-
command,
212-
version: result.version,
213-
error: result.error,
214-
});
215-
216-
if (result.works && !selectedCommand) {
217-
selectedCommand = command;
218-
selectedVersion = result.version;
219-
}
220-
}
221-
222-
if (!selectedCommand) {
223-
throw new Error(`No working CDS command found. Tested ${availableCommands.length} options.`);
224-
}
225-
226-
return {
227-
selectedCommand,
228-
selectedVersion,
229-
availableCommands,
230-
};
231-
} catch (error) {
232-
throw new Error(`Failed to analyze CDS commands: ${String(error)}`);
233-
}
234-
}
235-
236134
/**
237135
* Initialize the CDS command cache by testing global commands
238136
* @param sourceRoot The source root directory

extractors/cds/tools/src/cds/compiler/graph.ts

Lines changed: 26 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ import { determineCdsCommand } from './command';
22
import { compileCdsToJson } from './compile';
33
import { CompilationAttempt, CompilationTask, CompilationConfig } from './types';
44
import { addCompilationDiagnostic } from '../../diagnostics';
5-
import { cdsExtractorLog } from '../../logging';
5+
import { cdsExtractorLog, generateStatusReport } from '../../logging';
66
import { CdsDependencyGraph, CdsProject } from '../parser/types';
77

8-
/**
9-
* Attempt compilation with a specific command and configuration
10-
*/
8+
/** Attempt compilation with a specific command and configuration. */
119
function attemptCompilation(
1210
task: CompilationTask,
1311
cdsCommand: string,
@@ -92,7 +90,6 @@ function createCompilationTask(
9290
expectedOutputFiles: string[],
9391
projectDir: string,
9492
useProjectLevelCompilation: boolean,
95-
priority: number = 0,
9693
): CompilationTask {
9794
return {
9895
id: `${type}_${projectDir}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
@@ -103,7 +100,6 @@ function createCompilationTask(
103100
projectDir,
104101
attempts: [],
105102
useProjectLevelCompilation,
106-
priority,
107103
dependencies: [],
108104
};
109105
}
@@ -171,18 +167,18 @@ function executeCompilationTask(
171167
}
172168

173169
/**
174-
* Execute all compilation tasks for the dependency graph
170+
* Executes all compilation tasks for the provided {@link CdsDependencyGraph}.
171+
* Uses the provided `codeqlExePath` to run the CodeQL CLI, as needed, for
172+
* generating diagnositic warnings and/or errors for problems encountered while
173+
* running the CodeQL CDS extractor.
175174
*/
176-
export function executeCompilationTasks(
177-
dependencyGraph: CdsDependencyGraph,
178-
codeqlExePath: string,
179-
): void {
175+
function executeCompilationTasks(dependencyGraph: CdsDependencyGraph, codeqlExePath: string): void {
180176
cdsExtractorLog('info', 'Starting compilation execution for all projects...');
181177

182178
dependencyGraph.currentPhase = 'compiling';
183179
const compilationStartTime = new Date();
184180

185-
// Collect all tasks and sort by priority
181+
// Collect all compilation tasks from all projects.
186182
const allTasks: Array<{ task: CompilationTask; project: CdsProject }> = [];
187183

188184
for (const project of dependencyGraph.projects.values()) {
@@ -191,10 +187,9 @@ export function executeCompilationTasks(
191187
}
192188
}
193189

194-
// Sort by priority (higher priority first)
195-
allTasks.sort((a, b) => b.task.priority - a.task.priority);
196-
197-
// Execute tasks sequentially (could be parallelized in the future)
190+
// Execute compilation tasks sequentially. There is room for optimization in the future.
191+
// For now, we keep it simple to ensure consistent debug information collection.
192+
cdsExtractorLog('info', `Executing ${allTasks.length} compilation task(s)...`);
198193
for (const { task, project } of allTasks) {
199194
try {
200195
executeCompilationTask(task, project, dependencyGraph, codeqlExePath);
@@ -239,79 +234,26 @@ export function executeCompilationTasks(
239234
}
240235

241236
/**
242-
* Generate a comprehensive status report for the dependency graph
243-
* Supports both normal execution and debug modes
244-
*/
245-
export function generateStatusReport(dependencyGraph: CdsDependencyGraph): string {
246-
const summary = dependencyGraph.statusSummary;
247-
const lines: string[] = [];
248-
249-
lines.push('='.repeat(80));
250-
lines.push(`CDS EXTRACTOR STATUS REPORT`);
251-
lines.push('='.repeat(80));
252-
lines.push('');
253-
254-
// Overall summary
255-
lines.push('OVERALL SUMMARY:');
256-
lines.push(` Status: ${summary.overallSuccess ? 'SUCCESS' : 'FAILED'}`);
257-
lines.push(` Current Phase: ${dependencyGraph.currentPhase.toUpperCase()}`);
258-
lines.push(` Projects: ${summary.totalProjects}`);
259-
lines.push(` CDS Files: ${summary.totalCdsFiles}`);
260-
lines.push(` JSON Files Generated: ${summary.jsonFilesGenerated}`);
261-
lines.push('');
262-
263-
// Compilation summary
264-
lines.push('COMPILATION SUMMARY:');
265-
lines.push(` Total Tasks: ${summary.totalCompilationTasks}`);
266-
lines.push(` Successful: ${summary.successfulCompilations}`);
267-
lines.push(` Failed: ${summary.failedCompilations}`);
268-
lines.push(` Skipped: ${summary.skippedCompilations}`);
269-
lines.push('');
270-
271-
// Performance metrics
272-
lines.push('PERFORMANCE:');
273-
lines.push(` Total Duration: ${summary.performance.totalDurationMs}ms`);
274-
lines.push(` Parsing: ${summary.performance.parsingDurationMs}ms`);
275-
lines.push(` Compilation: ${summary.performance.compilationDurationMs}ms`);
276-
lines.push(` Extraction: ${summary.performance.extractionDurationMs}ms`);
277-
lines.push('');
278-
279-
// Errors and warnings
280-
if (summary.criticalErrors.length > 0) {
281-
lines.push('CRITICAL ERRORS:');
282-
for (const error of summary.criticalErrors) {
283-
lines.push(` - ${error}`);
284-
}
285-
lines.push('');
286-
}
287-
288-
if (summary.warnings.length > 0) {
289-
lines.push('WARNINGS:');
290-
for (const warning of summary.warnings) {
291-
lines.push(` - ${warning}`);
292-
}
293-
lines.push('');
294-
}
295-
296-
lines.push('='.repeat(80));
297-
298-
return lines.join('\n');
299-
}
300-
301-
/**
302-
* Main compilation orchestration function to replace the big for loop in cds-extractor.ts
303-
* Now supports consistent debug information collection
237+
* Orchestrates the compilation process for CDS files based on a dependency graph.
238+
*
239+
* This function coordinates the planning and execution of compilation tasks,
240+
* tracks the compilation status, and generates a post-compilation report.
241+
*
242+
* @param dependencyGraph - The {@link CdsDependencyGraph} representing the CDS projects,
243+
* project dependencies, expected compilation tasks, and their statuses.
244+
* @param projectCacheDirMap - A map from project identifiers to their cache directory paths.
245+
* @param codeqlExePath - The path to the CodeQL executable. Used for generating diagnostic
246+
* messages as part of the broader CodeQL (JavaScript) extraction process.
247+
* @throws Will rethrow any errors encountered during compilation, after logging them.
304248
*/
305249
export function orchestrateCompilation(
306250
dependencyGraph: CdsDependencyGraph,
307251
projectCacheDirMap: Map<string, string>,
308252
codeqlExePath: string,
309253
): void {
310254
try {
311-
// Plan compilation tasks
312255
planCompilationTasks(dependencyGraph, projectCacheDirMap);
313256

314-
// Execute compilation tasks
315257
executeCompilationTasks(dependencyGraph, codeqlExePath);
316258

317259
// Update overall status
@@ -322,9 +264,9 @@ export function orchestrateCompilation(
322264
dependencyGraph.statusSummary.overallSuccess = !hasFailures;
323265
dependencyGraph.currentPhase = hasFailures ? 'failed' : 'completed';
324266

325-
// Generate and log status report
267+
// Generate and log a "Post-Compilation" status report, aka before the JavaScript extractor runs.
326268
const statusReport = generateStatusReport(dependencyGraph);
327-
cdsExtractorLog('info', 'Final Status Report:\n' + statusReport);
269+
cdsExtractorLog('info', 'CDS Extractor Status Report : Post-Compilation...\n' + statusReport);
328270
} catch (error) {
329271
const errorMessage = `Compilation orchestration failed: ${String(error)}`;
330272
cdsExtractorLog('error', errorMessage);
@@ -343,10 +285,8 @@ export function orchestrateCompilation(
343285
}
344286
}
345287

346-
/**
347-
* Plan compilation tasks for all projects in the dependency graph
348-
*/
349-
export function planCompilationTasks(
288+
/** Plan compilation tasks for all projects in the dependency graph. */
289+
function planCompilationTasks(
350290
dependencyGraph: CdsDependencyGraph,
351291
projectCacheDirMap: Map<string, string>,
352292
): void {
@@ -379,7 +319,6 @@ export function planCompilationTasks(
379319
project.expectedOutputFiles,
380320
projectDir,
381321
true,
382-
10, // Higher priority for project-level compilation
383322
);
384323
project.compilationTasks = [task];
385324
} else {
@@ -393,7 +332,6 @@ export function planCompilationTasks(
393332
[expectedOutput],
394333
projectDir,
395334
false,
396-
5, // Lower priority for individual files
397335
);
398336
tasks.push(task);
399337
}
Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
1-
export { determineCdsCommand, getCommandAnalysisForDebug, resetCdsCommandCache } from './command';
2-
export type { CdsCommandAnalysis } from './command';
1+
export { determineCdsCommand, resetCdsCommandCache } from './command';
32
export { compileCdsToJson } from './compile';
4-
export {
5-
executeCompilationTasks,
6-
generateStatusReport,
7-
orchestrateCompilation,
8-
planCompilationTasks,
9-
} from './graph';
3+
export { orchestrateCompilation } from './graph';
104
export { findProjectForCdsFile } from './project';
11-
export type {
12-
CdsCompilationResult,
13-
CompilationAttempt,
14-
CompilationStatus,
15-
CompilationTask,
16-
CompilationConfig,
17-
} from './types';
185
export { getCdsVersion } from './version';

0 commit comments

Comments
 (0)