Skip to content
Merged
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
45 changes: 21 additions & 24 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 @@ -97,7 +97,7 @@
"firstline": "^2.0.2",
"glob": "^10.3.10",
"macho-uuid": "^1.3.2",
"pdb-guid": "^1.0.7",
"pdb-guid": "^2.1.1",
"pretty-bytes": "^5.6.0",
"promise-retry": "^2.0.1",
"rxjs": "^7.8.1",
Comment thread
bobbyg603 marked this conversation as resolved.
Expand Down
19 changes: 19 additions & 0 deletions spec/guid.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { tryGetGuid } from '../src/guid';

describe('tryGetGuid', () => {
it('should return guid for c++ pdb', async () => {
await expect(tryGetGuid('spec/support/bugsplat.pdb')).resolves.toBe('E546B55B6D214E86871B40AC35CD0D461');
});

it('should return guid for portable pdb', async () => {
await expect(tryGetGuid('spec/support/portable.pdb')).resolves.toBe('153A24FA52FF4C03813A890A535486B81');
});

it('should return guid for c++ exe', async () => {
await expect(tryGetGuid('spec/support/bssndrpt.exe')).resolves.toBe('64FB82D565000');
});

it('should return empty guid for unrecognized file', async () => {
await expect(tryGetGuid('spec/support/corrupt.exe')).resolves.toBe('');
});
});
23 changes: 0 additions & 23 deletions spec/pdb.spec.ts

This file was deleted.

39 changes: 18 additions & 21 deletions spec/worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,28 @@ describe('worker', () => {
const application = 'application';
const version = 'version';

describe('legacy', () => {
let symbolFileInfos;

beforeEach(async () => {
symbolFileInfos = createFakeSymbolFileInfos(2).map((info) => ({ ...info, dbgId: undefined }));
describe('skip', () => {
it('should skip files with no dbgId', async () => {
const symbolFileInfos = createFakeSymbolFileInfos(2).map((info) => ({ ...info, dbgId: '' }));
const worker = createUploadWorkerWithFakeReadStream(1, symbolFileInfos, clients);
await worker.upload(database, application, version);
});
const results = await worker.upload(database, application, version);

it('should call versionsClient.postSymbols with database, application, version, and symbol files', () => {
const symbolFiles = symbolFileInfos.map(symbolFile => ({
name: `${symbolFile.path}.zip`,
dbgId: symbolFile.dbgId,
moduleName: symbolFile.moduleName,
size: 0,
uncompressedSize: 0,
lastModified: 0,
file: expect.stringContaining('.zip'),
}));
expect(versionsClient.postSymbols).toHaveBeenCalledWith(database, application, version, expect.arrayContaining([symbolFiles[0]]));
expect(versionsClient.postSymbols).toHaveBeenCalledWith(database, application, version, expect.arrayContaining([symbolFiles[1]]));
expect(symbolsClient.postSymbols).not.toHaveBeenCalled();
expect(versionsClient.postSymbols).not.toHaveBeenCalled();
expect(results.every(r => r.size === 0)).toBe(true);
});
});

describe('legacy', () => {
it('should use versionsClient for source maps without dbgId', async () => {
const symbolFileInfos = [
createFakeSymbolFileInfo({ path: 'app.js.map', moduleName: 'app.js.map', dbgId: '' }),
];
const worker = createUploadWorkerWithFakeReadStream(1, symbolFileInfos, clients);
await worker.upload(database, application, version);

it('should call versionsClient.postSymbols for each symbol file', () => {
expect(versionsClient.postSymbols).toHaveBeenCalledTimes(symbolFileInfos.length);
expect(versionsClient.postSymbols).toHaveBeenCalledTimes(1);
expect(symbolsClient.postSymbols).not.toHaveBeenCalled();
});
});

Expand Down
12 changes: 12 additions & 0 deletions src/guid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createFromFile } from 'pdb-guid';

export async function tryGetGuid(filePath: string): Promise<string> {
try {
const file = await createFromFile(filePath);
return `${file.guid}`;
} catch (error) {
console.log(`Could not get UUID for ${filePath}...`);
}

return '';
}
19 changes: 4 additions & 15 deletions src/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { stat } from "node:fs/promises";
import { basename, extname } from "node:path";
import { getDSymFileInfos } from "./dsym";
import { tryGetElfUUID } from "./elf";
import { tryGetPdbGuid, tryGetPeGuid } from "./pdb";
import { tryGetGuid } from "./guid";
import { getSymFileInfo } from "./sym";

export type SymbolFileInfo = {
Expand All @@ -16,23 +16,12 @@ export async function createSymbolFileInfos(symbolFilePath: string): Promise<Sym
const isFolder = await stat(path).then((stats) => stats.isDirectory());
const extLowerCase = extname(path).toLowerCase();
const isSymFile = extLowerCase.includes('.sym') && !isFolder;
const isPdbFile = extLowerCase.includes('.pdb') && !isFolder;
const isPeFile = extLowerCase.includes('.exe') || extLowerCase.includes('.dll') && !isFolder;
const isPeOrPdbFile = (extLowerCase.includes('.pdb') || extLowerCase.includes('.exe') || extLowerCase.includes('.dll')) && !isFolder;
const isDsymBundle = extLowerCase.includes('.dsym');
const isElfFile = elfExtensions.some((ext) => extLowerCase.includes(ext) && !isFolder);

if (isPdbFile) {
const dbgId = await tryGetPdbGuid(path);
const moduleName = basename(path);
return [{
path,
dbgId,
moduleName,
} as SymbolFileInfo];
}

if (isPeFile) {
const dbgId = await tryGetPeGuid(path);
if (isPeOrPdbFile) {
const dbgId = await tryGetGuid(path);
const moduleName = basename(path);
return [{
path,
Expand Down
23 changes: 0 additions & 23 deletions src/pdb.ts

This file was deleted.

17 changes: 12 additions & 5 deletions src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,23 @@ export class UploadWorker {
let name = basename(path);
let tmpFileName = '';

const isSourceMap = extname(path).toLowerCase() === '.map';

if (dbgId && !isZip) {
tmpFileName = join(tmpDir, `${fileName}-${dbgId}-${uuid}.gz`);
client = this.symbolsClient;
await this.pool.exec('createGzipFile', [path, tmpFileName]);
} else if (!isZip) {
name = `${name}.zip`;
tmpFileName = join(tmpDir, `${fileName}-${dbgId}-${uuid}.zip`);
await this.pool.exec('createZipFile', [path, tmpFileName]);
} else if (isSourceMap || isZip) {
Comment thread
bobbyg603 marked this conversation as resolved.
if (isZip) {
tmpFileName = path;
} else {
name = `${name}.zip`;
tmpFileName = join(tmpDir, `${fileName}-${dbgId}-${uuid}.zip`);
await this.pool.exec('createZipFile', [path, tmpFileName]);
}
} else {
tmpFileName = path;
console.warn(`Worker ${this.id} skipping ${name} (extension: ${extname(path)}), missing dbgId...`);
return { name, size: 0 };
}

const { mtime: lastModified } = await this.stat(path);
Expand Down
Loading