Skip to content

Commit

Permalink
feat: gradle support (#256)
Browse files Browse the repository at this point in the history
* feat: added Gradle support

Signed-off-by: Ilona Shishov <[email protected]>

* chore: added args to full stack analysis code action

Signed-off-by: Ilona Shishov <[email protected]>

* docs: add and update typeDoc annotations

Signed-off-by: Ilona Shishov <[email protected]>

* test: update unit tests

Signed-off-by: Ilona Shishov <[email protected]>

---------

Signed-off-by: Ilona Shishov <[email protected]>
  • Loading branch information
IlonaShishov authored May 2, 2024
1 parent 831cdd3 commit 0207aae
Show file tree
Hide file tree
Showing 16 changed files with 743 additions and 26 deletions.
14 changes: 10 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"dist"
],
"dependencies": {
"@RHEcosystemAppEng/exhort-javascript-api": "^0.1.1-ea.29",
"@RHEcosystemAppEng/exhort-javascript-api": "^0.1.1-ea.34",
"@xml-tools/ast": "^5.0.5",
"@xml-tools/parser": "^1.0.11",
"json-to-ast": "^2.1.0",
Expand Down
1 change: 1 addition & 0 deletions src/codeActionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ function generateFullStackAnalysisAction(): CodeAction {
command: {
title: 'Analytics Report',
command: globalConfig.stackAnalysisCommand,
arguments: ['', true],
}
};
}
Expand Down
18 changes: 18 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,21 @@ export const RHDA_DIAGNOSTIC_SOURCE = 'Red Hat Dependency Analytics Plugin';
* Placeholder used as a version for dependency templates.
*/
export const VERSION_PLACEHOLDER: string = '__VERSION__';
/**
* Represents provider ecosystem names.
*/
export const GRADLE = 'gradle';
export const MAVEN = 'maven';
export const GOLANG = 'golang';
export const NPM = 'npm';
export const PYPI = 'pypi';
/**
* An object mapping ecosystem names to their true ecosystems.
*/
export const ecosystemNameMappings: { [key: string]: string } = {
[GRADLE]: MAVEN,
[MAVEN]: MAVEN,
[GOLANG]: GOLANG,
[NPM]: NPM,
[PYPI]: PYPI,
};
24 changes: 21 additions & 3 deletions src/dependencyAnalysis/collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Range } from 'vscode-languageserver';

import { IPositionedString, IPositionedContext, IPosition } from '../positionTypes';
import { isDefined } from '../utils';
import { ecosystemNameMappings, GRADLE } from '../constants';

/**
* Represents a dependency specification.
Expand Down Expand Up @@ -35,8 +36,11 @@ export class Dependency implements IDependency {
*/
export class DependencyMap {
mapper: Map<string, IDependency>;
constructor(deps: IDependency[]) {
this.mapper = new Map(deps.map(d => [d.name.value, d]));
constructor(deps: IDependency[], ecosystem: string) {
this.mapper = new Map(deps.map(d => {
const key = ecosystem === GRADLE && d.version ? `${d.name.value}@${d.version.value}` : d.name.value;
return [key, d];
}));
}

/**
Expand Down Expand Up @@ -67,6 +71,12 @@ export interface IDependencyProvider {
* @returns The resolved name of the dependency.
*/
resolveDependencyFromReference(ref: string): string;

/**
* Gets the name of the providers ecosystem.
* @returns The name of the providers ecosystem.
*/
getEcosystem(): string;
}

/**
Expand All @@ -85,7 +95,15 @@ export class EcosystemDependencyResolver {
* @returns The resolved name of the dependency.
*/
resolveDependencyFromReference(ref: string): string {
return ref.replace(`pkg:${this.ecosystem}/`, '');
return ref.replace(`pkg:${ecosystemNameMappings[this.ecosystem]}/`, '');
}

/**
* Gets the name of the ecosystem this provider is configured for.
* @returns The name of the ecosystem.
*/
getEcosystem(): string {
return this.ecosystem;
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/dependencyAnalysis/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { IPositionedContext } from '../positionTypes';
import { executeComponentAnalysis, DependencyData } from './analysis';
import { Vulnerability } from '../vulnerability';
import { connection } from '../server';
import { VERSION_PLACEHOLDER } from '../constants';
import { VERSION_PLACEHOLDER, GRADLE } from '../constants';
import { clearCodeActionsMap, registerCodeAction, generateSwitchToRecommendedVersionAction } from '../codeActionHandler';
import { decodeUriPath } from '../utils';
import { AbstractDiagnosticsPipeline } from '../diagnosticsPipeline';
Expand All @@ -37,10 +37,11 @@ class DiagnosticsPipeline extends AbstractDiagnosticsPipeline<DependencyData> {
/**
* Runs diagnostics on dependencies.
* @param dependencies - A map containing dependency data by reference string.
* @param ecosystem - The name of the ecosystem in which dependencies are being analyzed.
*/
runDiagnostics(dependencies: Map<string, DependencyData[]>) {
runDiagnostics(dependencies: Map<string, DependencyData[]>, ecosystem: string) {
Object.entries(dependencies).map(([ref, dependencyData]) => {
const dependencyRef = ref.split('@')[0];
const dependencyRef = ecosystem === GRADLE ? ref : ref.split('@')[0];
const dependency = this.dependencyMap.get(dependencyRef);

if (dependency) {
Expand Down Expand Up @@ -101,7 +102,8 @@ class DiagnosticsPipeline extends AbstractDiagnosticsPipeline<DependencyData> {
async function performDiagnostics(diagnosticFilePath: string, contents: string, provider: IDependencyProvider) {
try {
const dependencies = await provider.collect(contents);
const dependencyMap = new DependencyMap(dependencies);
const ecosystem = provider.getEcosystem();
const dependencyMap = new DependencyMap(dependencies, ecosystem);

const diagnosticsPipeline = new DiagnosticsPipeline(dependencyMap, diagnosticFilePath);
diagnosticsPipeline.clearDiagnostics();
Expand All @@ -110,7 +112,7 @@ async function performDiagnostics(diagnosticFilePath: string, contents: string,

clearCodeActionsMap(diagnosticFilePath);

diagnosticsPipeline.runDiagnostics(response.dependencies);
diagnosticsPipeline.runDiagnostics(response.dependencies, ecosystem);

diagnosticsPipeline.reportDiagnostics();
} catch (error) {
Expand Down
5 changes: 3 additions & 2 deletions src/diagnosticsPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ interface IDiagnosticsPipeline<T> {
/**
* Runs diagnostics on dependencies.
* @param artifact - A map containing artifact data.
* @param ecosystem - The name of the ecosystem to analyze dependencies in.
*/
runDiagnostics(artifact: Map<string, T[]>);
runDiagnostics(artifact: Map<string, T[]>, ecosystem: string);
}

/**
Expand Down Expand Up @@ -66,7 +67,7 @@ abstract class AbstractDiagnosticsPipeline<T> implements IDiagnosticsPipeline<T>
});
}

abstract runDiagnostics(artifact: Map<string, T[]>): void;
abstract runDiagnostics(artifact: Map<string, T[]>, ecosystem: string): void;
}

export { AbstractDiagnosticsPipeline };
5 changes: 5 additions & 0 deletions src/fileHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { DependencyProvider as PackageJson } from './providers/package.json';
import { DependencyProvider as PomXml } from './providers/pom.xml';
import { DependencyProvider as GoMod } from './providers/go.mod';
import { DependencyProvider as RequirementsTxt } from './providers/requirements.txt';
import { DependencyProvider as BuildGradle } from './providers/build.gradle';
import { ImageProvider as Docker } from './providers/docker';

/**
Expand Down Expand Up @@ -120,6 +121,10 @@ files.on(EventStream.Diagnostics, '^requirements\\.txt$', (uri, contents) => {
dependencyDiagnostics.performDiagnostics(uri, contents, new RequirementsTxt());
});

files.on(EventStream.Diagnostics, '^build\\.gradle$', (uri, contents) => {
dependencyDiagnostics.performDiagnostics(uri, contents, new BuildGradle());
});

files.on(EventStream.Diagnostics, '^(Dockerfile|Containerfile)$', (uri, contents) => {
imageDiagnostics.performDiagnostics(uri, contents, new Docker());
});
Expand Down
Loading

0 comments on commit 0207aae

Please sign in to comment.