Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/instructions/extractors_cds_tools_ts.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
applyTo: 'extractors/cds/tools/**/*.ts'
description: 'Instructions for CodeQL CDS extractor TypeScript source and test files.'
---

# Copilot Instructions for `extractors/cds/tools/**/*.ts` files

## PURPOSE

This file contains instructions for working with TypeScript source code files in the `extractors/cds/tools/` directory of the `codeql-sap-js` repository. This includes the main `cds-extractor.ts` entry-point, modular source files in `src/**/*.ts`, and comprehensive test files in `test/**/*.test.ts`.

## REQUIREMENTS

## COMMON REQUIREMENTS

- ALWAYS use modern TypeScript syntax and features compatible with the configured target (ES2020).
- ALWAYS follow best practices for implementing secure and efficient CodeQL extractor functionality.
- ALWAYS order imports, definitions, static lists, and similar constructs alphabetically.
- ALWAYS follow a test-driven development (TDD) approach by writing comprehensive tests for new features or bug fixes.
- ALWAYS fix lint errors by running `npm run lint:fix` from the `extractors/cds/tools/` directory before committing changes.
- ALWAYS maintain consistency between the CDS extractor's compilation behavior and the `extractors/cds/tools/test/cds-compilation-for-actions.test.sh` script to prevent CI/CD workflow failures.
- **ALWAYS run `npm run build:all` from the `extractors/cds/tools/` directory and ensure it passes completely before committing any changes. This is MANDATORY and includes lint checks, test coverage, and bundle validation.**

### CDS EXTRACTOR SOURCE REQUIREMENTS

The following requirements are specific to the CDS extractor main entry-point `cds-extractor.ts` and source files matching `extractors/cds/tools/src/**/*.ts`.

- ALWAYS keep the main entry-point `cds-extractor.ts` focused on orchestration, delegating specific tasks to well-defined modules in `src/`.
- ALWAYS gracefully handle extraction failures using tool-level diagnostics in order to avoid disrupting the overall CodeQL extraction process. Instead of exiting with a non-zero code, the CDS extractor should generate a diagnostic error (or warning) that points to the relative path (from source root) of the problematic source (e.g. `.cds`) file.

### CDS EXTRACTOR TESTING REQUIREMENTS

The following requirements are specific to the CDS extractor test files matching `extractors/cds/tools/test/**/*.test.ts`.

- ALWAYS write unit tests for new functions and classes in corresponding `test/src/**/*.test.ts` files.
- ALWAYS use Jest testing framework with the configured `ts-jest` preset.
- ALWAYS follow the AAA pattern (Arrange, Act, Assert) for test structure.
- ALWAYS mock external dependencies (filesystem, child processes, network calls) using Jest mocks or `mock-fs`.
- ALWAYS test both success and error scenarios with appropriate edge cases.
- ALWAYS maintain test coverage above the established threshold.
- **ALWAYS run `npm test` or `npm run test:coverage` from the `extractors/cds/tools/` directory and ensure all tests pass before committing changes.**

## PREFERENCES

- PREFER modular design with each major functionality implemented in its own dedicated file or module under `src/`.
- PREFER the existing architectural patterns:
- `src/cds/compiler/` for CDS compiler specific logic
- `src/cds/parser/` for CDS parser specific logic
- `src/logging/` for unified logging and performance tracking
- `src/packageManager/` for dependency management and caching
- `src/codeql.ts` for CodeQL JavaScript extractor integration
- `src/environment.ts` for environment setup and validation
- PREFER comprehensive error handling with diagnostic reporting through the `src/diagnostics.ts` module.
- PREFER performance-conscious implementations that minimize filesystem operations and dependency installations.
- PREFER project-aware processing that understands CDS file relationships and dependencies.

## CONSTRAINTS

- NEVER leave any trailing whitespace on any line.
- NEVER directly modify any compiled files in the `dist/` directory; all changes must be made in the corresponding `src/` files and built using the build process.
- NEVER commit changes without verifying that `npm run build:all` passes completely when run from the `extractors/cds/tools/` directory.
- NEVER modify compilation behavior without updating the corresponding test script `extractors/cds/tools/test/cds-compilation-for-actions.test.sh`.
- NEVER process CDS files in isolation - maintain project-aware context for accurate extraction.
- NEVER bypass the unified logging system - use `src/logging/` utilities for all output and diagnostics.
- NEVER commit extra documentation files that purely explain what has been changed and/or fixed; use git commit messages instead of adding any `.md` files that you have not explicitly been requested to create.
22 changes: 19 additions & 3 deletions extractors/cds/tools/cds-extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,12 @@ try {
if (!extractorResult.success && extractorResult.error) {
cdsExtractorLog('error', `Error running JavaScript extractor: ${extractorResult.error}`);
if (codeqlExePath) {
addJavaScriptExtractorDiagnostic(sourceRoot, extractorResult.error, codeqlExePath);
addJavaScriptExtractorDiagnostic(
sourceRoot,
extractorResult.error,
codeqlExePath,
sourceRoot,
);
}
logExtractorStop(false, 'JavaScript extractor failed');
} else {
Expand Down Expand Up @@ -223,7 +228,12 @@ try {
if (!extractorResult.success && extractorResult.error) {
cdsExtractorLog('error', `Error running JavaScript extractor: ${extractorResult.error}`);
if (codeqlExePath) {
addJavaScriptExtractorDiagnostic(sourceRoot, extractorResult.error, codeqlExePath);
addJavaScriptExtractorDiagnostic(
sourceRoot,
extractorResult.error,
codeqlExePath,
sourceRoot,
);
}
logExtractorStop(false, 'JavaScript extractor failed');
} else {
Expand Down Expand Up @@ -316,6 +326,7 @@ try {
cdsFilePathsToProcess[0], // Use first file as representative
`Compilation orchestration failed: ${String(error)}`,
codeqlExePath,
sourceRoot,
);
}
}
Expand Down Expand Up @@ -350,7 +361,12 @@ if (!extractorResult.success && extractorResult.error) {
// Use the first CDS file as a representative file for the diagnostic
const firstProject = Array.from(dependencyGraph.projects.values())[0];
const representativeFile = firstProject.cdsFiles[0] || sourceRoot;
addJavaScriptExtractorDiagnostic(representativeFile, extractorResult.error, codeqlExePath);
addJavaScriptExtractorDiagnostic(
representativeFile,
extractorResult.error,
codeqlExePath,
sourceRoot,
);
}

logExtractorStop(false, 'JavaScript extractor failed');
Expand Down
95 changes: 71 additions & 24 deletions extractors/cds/tools/dist/cds-extractor.bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions extractors/cds/tools/dist/cds-extractor.bundle.js.map

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion extractors/cds/tools/src/cds/compiler/retry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import type { CdsDependencyGraph, CdsProject } from '../parser';
* Add diagnostics only for tasks with `status: failed` in the {@link CdsDependencyGraph}.
* @param dependencyGraph The dependency graph to use as the source of truth for task status
* @param codeqlExePath Path to CodeQL executable used to add a diagnostic notification
* @param sourceRoot Source root directory to use for making file paths relative
*/
function addCompilationDiagnosticsForFailedTasks(
dependencyGraph: CdsDependencyGraph,
codeqlExePath: string,
sourceRoot: string,
): void {
for (const project of dependencyGraph.projects.values()) {
for (const task of project.compilationTasks) {
Expand All @@ -38,6 +40,7 @@ function addCompilationDiagnosticsForFailedTasks(
sourceFile,
task.errorSummary ?? 'Compilation failed',
codeqlExePath,
sourceRoot,
);
}
}
Expand Down Expand Up @@ -191,7 +194,11 @@ export function orchestrateRetryAttempts(
updateDependencyGraphWithRetryResults(dependencyGraph, result);

// Phase 5: Add diagnostics for definitively failed tasks.
addCompilationDiagnosticsForFailedTasks(dependencyGraph, codeqlExePath);
addCompilationDiagnosticsForFailedTasks(
dependencyGraph,
codeqlExePath,
dependencyGraph.sourceRootDir,
);

result.success = result.totalSuccessfulRetries > 0 || result.totalTasksRequiringRetry === 0;
} catch (error) {
Expand Down
Loading