Move sarif parser and tests, build completing

This commit is contained in:
marcnjaramillo 2021-11-19 17:21:42 -08:00
Родитель d53abd815d
Коммит 0bb1501e72
8 изменённых файлов: 57 добавлений и 72 удалений

Просмотреть файл

@ -16,7 +16,7 @@ import { assertNever } from './pure/helpers-pure';
import { QueryMetadata, SortDirection } from './pure/interface-types';
import { Logger, ProgressReporter } from './logging';
import { CompilationMessage } from './pure/messages';
import { parseSarif } from './pure/sarif-utils';
import { sarifParser } from './sarif-parser';
import { dbSchemeToLanguage } from './helpers';
/**
@ -682,7 +682,7 @@ export class CodeQLCliServer implements Disposable {
async interpretBqrs(metadata: QueryMetadata, resultsPath: string, interpretedResultsPath: string, sourceInfo?: SourceInfo): Promise<sarif.Log> {
await this.runInterpretCommand(SARIF_FORMAT, metadata, resultsPath, interpretedResultsPath, sourceInfo);
return await parseSarif(interpretedResultsPath);
return await sarifParser(interpretedResultsPath);
}
async generateResultsCsv(metadata: QueryMetadata, resultsPath: string, csvPath: string, sourceInfo?: SourceInfo): Promise<void> {

Просмотреть файл

@ -1,14 +1,6 @@
import * as Sarif from 'sarif';
import * as fs from 'fs-extra';
import { parser } from 'stream-json';
import { pick } from 'stream-json/filters/Pick';
import Assembler = require('stream-json/Assembler');
import { chain } from 'stream-chain';
import { ResolvableLocationValue } from './bqrs-cli-types';
const DUMMY_TOOL : Sarif.Tool = {driver: {name: ''}};
export interface SarifLink {
dest: number;
text: string;
@ -164,46 +156,6 @@ export function parseSarifLocation(
}
}
export async function parseSarif(interpretedResultsPath: string) : Promise<Sarif.Log> {
try {
// Parse the SARIF file into token streams, filtering out only the results array.
const p = parser();
const pipeline = chain([
fs.createReadStream(interpretedResultsPath),
p,
pick({filter: 'runs.0.results'})
]);
// Creates JavaScript objects from the token stream
const asm = Assembler.connectTo(pipeline);
// Returns a constructed Log object with the results or an empty array if no results were found.
// If the parser fails for any reason, it will reject the promise.
return await new Promise((resolve, reject) => {
pipeline.on('error', (error) => {
reject(error);
});
asm.on('done', (asm) => {
const log : Sarif.Log = {
version: '2.1.0',
runs: [
{
tool: DUMMY_TOOL,
results: asm.current ?? []
}
]
};
resolve(log);
});
});
} catch (err) {
throw new Error(`Parsing output of interpretation failed: ${err.stderr || err}`);
}
}
export function isNoLocation(loc: ParsedSarifLocation): loc is NoLocation {
return 'hint' in loc;
}

Просмотреть файл

@ -0,0 +1,48 @@
import * as Sarif from 'sarif';
import * as fs from 'fs-extra';
import { parser } from 'stream-json';
import { pick } from 'stream-json/filters/Pick';
import Assembler = require('stream-json/Assembler');
import { chain } from 'stream-chain';
const DUMMY_TOOL : Sarif.Tool = {driver: {name: ''}};
export async function sarifParser(interpretedResultsPath: string) : Promise<Sarif.Log> {
try {
// Parse the SARIF file into token streams, filtering out only the results array.
const p = parser();
const pipeline = chain([
fs.createReadStream(interpretedResultsPath),
p,
pick({filter: 'runs.0.results'})
]);
// Creates JavaScript objects from the token stream
const asm = Assembler.connectTo(pipeline);
// Returns a constructed Log object with the results or an empty array if no results were found.
// If the parser fails for any reason, it will reject the promise.
return await new Promise((resolve, reject) => {
pipeline.on('error', (error) => {
reject(error);
});
asm.on('done', (asm) => {
const log : Sarif.Log = {
version: '2.1.0',
runs: [
{
tool: DUMMY_TOOL,
results: asm.current ?? []
}
]
};
resolve(log);
});
});
} catch (err) {
throw new Error(`Parsing output of interpretation failed: ${err.stderr || err}`);
}
}

Просмотреть файл

@ -1,23 +1,25 @@
import * as path from 'path';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { CodeQLCliServer } from '../../cli';
import { sarifParser } from '../../sarif-parser';
chai.use(chaiAsPromised);
const expect = chai.expect;
describe.only('cliServerTests', function() {
describe.only('sarif parser', function() {
const sarifDir = path.join(path.dirname(__dirname), 'sarif');
it('should parse a valid SARIF file', async () => {
const result = await CodeQLCliServer.parseSarif(__dirname + '/data/sarif/validSarif.sarif');
const result = await sarifParser(path.join(sarifDir, 'validSarif.sarif'));
expect(result.version).to.exist;
expect(result.runs).to.exist;
expect(result.runs[0].tool).to.exist;
expect(result.runs[0].tool.driver).to.exist;
expect(result.runs.length).to.be.at.least(1);
});
it('should return an empty array if there are no results', async () => {
const result = await CodeQLCliServer.parseSarif(__dirname + '/data/sarif/emptyResultsSarif.sarif');
const result = await sarifParser(path.join(sarifDir, 'emptyResultsSarif.sarif'));
expect(result.runs[0].results).to.be.empty;
});
});

Просмотреть файл

@ -1,19 +1,16 @@
import 'mocha';
import { expect } from 'chai';
import * as Sarif from 'sarif';
import * as path from 'path';
import {
getPathRelativeToSourceLocationPrefix,
parseSarifLocation,
parseSarifPlainTextMessage,
unescapeSarifText,
parseSarif
} from '../../src/pure/sarif-utils';
describe('parsing sarif', () => {
const sarifDir = path.join(path.dirname(__dirname), 'sarif');
it('should be able to parse a simple message from the spec', async function() {
const message = 'Tainted data was used. The data came from [here](3).';
@ -64,20 +61,6 @@ describe('parsing sarif', () => {
.to.eq('file:/a/b/c/?x=test');
});
it('should parse a valid SARIF file', async () => {
const result = await parseSarif(path.join(sarifDir, 'validSarif.sarif'));
expect(result.version).to.exist;
expect(result.runs).to.exist;
expect(result.runs[0].tool).to.exist;
expect(result.runs[0].tool.driver).to.exist;
expect(result.runs.length).to.be.at.least(1);
});
it('should return an empty array if there are no results', async () => {
const result = await parseSarif(path.join(sarifDir, 'emptyResultsSarif.sarif'));
expect(result.runs[0].results).to.be.empty;
});
describe('parseSarifLocation', () => {
it('should parse a sarif location with "no location"', () => {
expect(parseSarifLocation({}, '')).to.deep.equal({