Skip to content
This repository was archived by the owner on Apr 3, 2024. It is now read-only.

Commit bf79ce8

Browse files
mctavishDominicKramer
authored andcommitted
feat: introduce javascriptFileExtensions config parameter. (#779)
This config parameter can be used to allow users to debug javascript files that have extensions other than .js.
1 parent 92a56db commit bf79ce8

File tree

7 files changed

+54
-17
lines changed

7 files changed

+54
-17
lines changed

src/agent/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ export interface ResolvedDebugAgentConfig extends GoogleAuthOptions {
179179
*/
180180
appPathRelativeToRepository?: string;
181181

182+
/**
183+
* The set of file extensions that identify javascript code to be debugged.
184+
* By default, only .js files or files with sourcemaps are considered to be
185+
* debuggable. This setting can be used to inform the debugger if you have
186+
* javascript code in files with extensions other than .js.
187+
* Example: ['.js', '.jsz']
188+
*/
189+
javascriptFileExtensions: string[];
190+
182191
/**
183192
* A function which takes the path of a source file in your repository,
184193
* a list of your project's Javascript files known to the debugger,
@@ -362,6 +371,7 @@ export const defaultConfig: ResolvedDebugAgentConfig = {
362371
},
363372

364373
appPathRelativeToRepository: undefined,
374+
javascriptFileExtensions: ['.js'],
365375
pathResolver: undefined,
366376
logLevel: 1,
367377
breakpointUpdateIntervalSec: 10,

src/agent/debuglet.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,16 +314,23 @@ export class Debuglet extends EventEmitter {
314314
return extend(true, {}, defaultConfig, config, envConfig);
315315
}
316316

317+
static buildRegExp(fileExtensions: string[]): RegExp {
318+
return new RegExp(fileExtensions.map(f => f + '$').join('|'));
319+
}
320+
317321
static async findFiles(
318-
baseDir: string,
322+
config: ResolvedDebugAgentConfig,
319323
precomputedHash?: string
320324
): Promise<FindFilesResult> {
325+
const baseDir = config.workingDirectory;
321326
const fileStats = await scanner.scan(
322327
baseDir,
323-
/.js$|.js.map$/,
328+
Debuglet.buildRegExp(config.javascriptFileExtensions.concat('js.map')),
324329
precomputedHash
325330
);
326-
const jsStats = fileStats.selectStats(/.js$/);
331+
const jsStats = fileStats.selectStats(
332+
Debuglet.buildRegExp(config.javascriptFileExtensions)
333+
);
327334
const mapFiles = fileStats.selectFiles(/.js.map$/, process.cwd());
328335
const errors = fileStats.errors();
329336
return {jsStats, mapFiles, errors, hash: fileStats.hash};
@@ -370,10 +377,7 @@ export class Debuglet extends EventEmitter {
370377

371378
let findResults: FindFilesResult;
372379
try {
373-
findResults = await Debuglet.findFiles(
374-
that.config.workingDirectory,
375-
gaeId
376-
);
380+
findResults = await Debuglet.findFiles(that.config, gaeId);
377381
findResults.errors.forEach(that.logger.warn);
378382
} catch (err) {
379383
that.logger.error('Error scanning the filesystem.', err);

src/agent/v8/inspector-debugapi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ export class InspectorDebugApi implements debugapi.DebugApi {
136136
}
137137
const baseScriptPath = path.normalize(breakpoint.location.path);
138138
if (!this.sourcemapper.hasMappingInfo(baseScriptPath)) {
139-
if (!baseScriptPath.endsWith('js')) {
139+
const extension = path.extname(baseScriptPath);
140+
if (!this.config.javascriptFileExtensions.includes(extension)) {
140141
return utils.setErrorStatusAndCallback(
141142
cb,
142143
breakpoint,

src/agent/v8/legacy-debugapi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ export class V8DebugApi implements debugapi.DebugApi {
132132
}
133133
const baseScriptPath = path.normalize(breakpoint.location.path);
134134
if (!this.sourcemapper.hasMappingInfo(baseScriptPath)) {
135-
if (!baseScriptPath.endsWith('.js')) {
135+
const extension = path.extname(baseScriptPath);
136+
if (!this.config.javascriptFileExtensions.includes(extension)) {
136137
return utils.setErrorStatusAndCallback(
137138
cb,
138139
breakpoint,

test/fixtures/hello.jsz

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('hello world');

test/test-debuglet.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,23 @@ describe('Debuglet', () => {
9191
const SOURCEMAP_DIR = path.join(__dirname, 'fixtures', 'sourcemaps');
9292

9393
it('throws an error for an invalid directory', async () => {
94+
const config = extend({}, defaultConfig, {
95+
workingDirectory: path.join(SOURCEMAP_DIR, '!INVALID'),
96+
});
9497
let err: Error | null = null;
9598
try {
96-
await Debuglet.findFiles(
97-
path.join(SOURCEMAP_DIR, '!INVALID!'),
98-
'fake-id'
99-
);
99+
await Debuglet.findFiles(config, 'fake-id');
100100
} catch (e) {
101101
err = e;
102102
}
103103
assert.ok(err);
104104
});
105105

106106
it('finds the correct sourcemaps files', async () => {
107-
const searchResults = await Debuglet.findFiles(SOURCEMAP_DIR, 'fake-id');
107+
const config = extend({}, defaultConfig, {
108+
workingDirectory: SOURCEMAP_DIR,
109+
});
110+
const searchResults = await Debuglet.findFiles(config, 'fake-id');
108111
assert(searchResults.jsStats);
109112
assert.strictEqual(Object.keys(searchResults.jsStats).length, 1);
110113
assert(searchResults.jsStats[path.join(SOURCEMAP_DIR, 'js-file.js')]);
@@ -717,9 +720,10 @@ describe('Debuglet', () => {
717720
// Don't actually scan the entire filesystem. Act like the filesystem
718721
// is empty.
719722
mockedDebuglet.Debuglet.findFiles = (
720-
baseDir: string,
723+
config: ResolvedDebugAgentConfig,
721724
precomputedHash?: string
722725
): Promise<FindFilesResult> => {
726+
const baseDir = config.workingDirectory;
723727
assert.strictEqual(baseDir, root);
724728
return Promise.resolve({
725729
jsStats: {},

test/test-v8debugapi.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ describe('v8debugapi', () => {
244244
const config: ResolvedDebugAgentConfig = extend({}, defaultConfig, {
245245
workingDirectory: __dirname,
246246
forceNewAgent_: true,
247+
javascriptFileExtensions: ['.js', '.jsz'],
247248
});
248249
const logger = consoleLogLevel({
249250
level: Debuglet.logLevelToName(config.logLevel),
@@ -253,10 +254,10 @@ describe('v8debugapi', () => {
253254
beforeEach(done => {
254255
if (!api) {
255256
scanner
256-
.scan(config.workingDirectory, /.js$|.js.map$/)
257+
.scan(config.workingDirectory, /.js$|.jsz$|.js.map$/)
257258
.then(async fileStats => {
258259
assert.strictEqual(fileStats.errors().size, 0);
259-
const jsStats = fileStats.selectStats(/.js$/);
260+
const jsStats = fileStats.selectStats(/.js$|.jsz$/);
260261
const mapFiles = fileStats.selectFiles(/.js.map$/, process.cwd());
261262
const mapper = await SourceMapper.create(mapFiles);
262263

@@ -322,6 +323,21 @@ describe('v8debugapi', () => {
322323
});
323324
});
324325

326+
it('should permit breakpoints on js files with non-standard extensions', done => {
327+
require('./fixtures/hello.jsz');
328+
const bp: stackdriver.Breakpoint = ({
329+
id: 0,
330+
location: {line: 1, path: path.join('fixtures', 'hello.jsz')},
331+
} as {}) as stackdriver.Breakpoint;
332+
api.set(bp, err1 => {
333+
assert.ifError(err1);
334+
api.clear(bp, err2 => {
335+
assert.ifError(err2);
336+
done();
337+
});
338+
});
339+
});
340+
325341
it('should set error for breakpoint in non-js files', done => {
326342
require('./fixtures/key-bad.json');
327343
// TODO(dominickramer): Have this actually implement Breakpoint

0 commit comments

Comments
 (0)