Skip to content

Commit 4da18d3

Browse files
authored
Merge pull request #3 from alonefox/issue49
StackToolbox#49 Add partial replace .vscode/launch.json
2 parents d8a8759 + ade3619 commit 4da18d3

File tree

3 files changed

+202
-1
lines changed

3 files changed

+202
-1
lines changed

src/__tests__/__snapshots__/integration.test.ts.snap

+12
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Resources:
4343
".vscode/launch.json": "{
4444
\\"version\\": \\"0.2.0\\",
4545
\\"configurations\\": [
46+
// BEGIN AwsSamPlugin
4647
{
4748
\\"name\\": \\"MyLambda\\",
4849
\\"type\\": \\"node\\",
@@ -62,6 +63,7 @@ Resources:
6263
\\"<node_internals>/**/*.js\\"
6364
]
6465
}
66+
// END AwsSamPlugin
6567
]
6668
}",
6769
},
@@ -89,6 +91,7 @@ Resources:
8991
".vscode/launch.json": "{
9092
\\"version\\": \\"0.2.0\\",
9193
\\"configurations\\": [
94+
// BEGIN AwsSamPlugin
9295
{
9396
\\"name\\": \\"MyLambda\\",
9497
\\"type\\": \\"node\\",
@@ -108,6 +111,7 @@ Resources:
108111
\\"<node_internals>/**/*.js\\"
109112
]
110113
}
114+
// END AwsSamPlugin
111115
]
112116
}",
113117
},
@@ -135,6 +139,7 @@ Resources:
135139
".vscode/launch.json": "{
136140
\\"version\\": \\"0.2.0\\",
137141
\\"configurations\\": [
142+
// BEGIN AwsSamPlugin
138143
{
139144
\\"name\\": \\"MyLambda\\",
140145
\\"type\\": \\"node\\",
@@ -154,6 +159,7 @@ Resources:
154159
\\"<node_internals>/**/*.js\\"
155160
]
156161
}
162+
// END AwsSamPlugin
157163
]
158164
}",
159165
},
@@ -181,6 +187,7 @@ Resources:
181187
".vscode/launch.json": "{
182188
\\"version\\": \\"0.2.0\\",
183189
\\"configurations\\": [
190+
// BEGIN AwsSamPlugin
184191
{
185192
\\"name\\": \\"MyLambda\\",
186193
\\"type\\": \\"node\\",
@@ -200,6 +207,7 @@ Resources:
200207
\\"<node_internals>/**/*.js\\"
201208
]
202209
}
210+
// END AwsSamPlugin
203211
]
204212
}",
205213
},
@@ -216,6 +224,7 @@ Object {
216224
".vscode/launch.json": "{
217225
\\"version\\": \\"0.2.0\\",
218226
\\"configurations\\": [
227+
// BEGIN AwsSamPlugin
219228
{
220229
\\"name\\": \\"a:MyLambda\\",
221230
\\"type\\": \\"node\\",
@@ -254,6 +263,7 @@ Object {
254263
\\"<node_internals>/**/*.js\\"
255264
]
256265
}
266+
// END AwsSamPlugin
257267
]
258268
}",
259269
"project-a/.aws-sam/build/template.yaml": "AWSTemplateFormatVersion: 2010-09-09
@@ -294,6 +304,7 @@ Object {
294304
".vscode/launch.json": "{
295305
\\"version\\": \\"0.2.0\\",
296306
\\"configurations\\": [
307+
// BEGIN AwsSamPlugin
297308
{
298309
\\"name\\": \\"a:MyLambda\\",
299310
\\"type\\": \\"node\\",
@@ -332,6 +343,7 @@ Object {
332343
\\"<node_internals>/**/*.js\\"
333344
]
334345
}
346+
// END AwsSamPlugin
335347
]
336348
}",
337349
"project-a/.aws-sam/build/template.yaml": "AWSTemplateFormatVersion: 2010-09-09

src/__tests__/integration.test.ts

+159
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,165 @@ test("Happy path with VS Code debugging disabled", () => {
233233
expect({ entryPoints, files: fs.__getMockWrittenFiles() }).toMatchSnapshot();
234234
});
235235

236+
const vscodeLaunchJson1 = `{
237+
"version": "0.2.0",
238+
"configurations": [
239+
{
240+
"name": "CustomLambda",
241+
"type": "node",
242+
"request": "attach",
243+
"address": "localhost",
244+
"port": 5858,
245+
"localRoot": "\${workspaceFolder}/.aws-sam/build/CustomLambda",
246+
"remoteRoot": "/var/task",
247+
"protocol": "inspector",
248+
"stopOnEntry": false,
249+
"outFiles": [
250+
"\${workspaceFolder}/.aws-sam/build/CustomLambda/**/*.js"
251+
],
252+
"sourceMaps": true,
253+
"skipFiles": [
254+
"/var/runtime/**/*.js",
255+
"<node_internals>/**/*.js"
256+
]
257+
}
258+
]
259+
}`;
260+
const vscodeLaunchJson2 = `{
261+
"version": "0.2.0",
262+
"configurations": [
263+
{
264+
"name": "CustomLambda",
265+
"type": "node",
266+
"request": "attach",
267+
"address": "localhost",
268+
"port": 5858,
269+
"localRoot": "\${workspaceFolder}/.aws-sam/build/CustomLambda",
270+
"remoteRoot": "/var/task",
271+
"protocol": "inspector",
272+
"stopOnEntry": false,
273+
"outFiles": [
274+
"\${workspaceFolder}/.aws-sam/build/CustomLambda/**/*.js"
275+
],
276+
"sourceMaps": true,
277+
"skipFiles": [
278+
"/var/runtime/**/*.js",
279+
"<node_internals>/**/*.js"
280+
]
281+
},
282+
// BEGIN AwsSamPlugin
283+
{
284+
"name": "OldLambda",
285+
"type": "node",
286+
"request": "attach",
287+
"address": "localhost",
288+
"port": 5858,
289+
"localRoot": "\${workspaceFolder}/.aws-sam/build/OldLambda",
290+
"remoteRoot": "/var/task",
291+
"protocol": "inspector",
292+
"stopOnEntry": false,
293+
"outFiles": [
294+
"\${workspaceFolder}/.aws-sam/build/OldLambda/**/*.js"
295+
],
296+
"sourceMaps": true,
297+
"skipFiles": [
298+
"/var/runtime/**/*.js",
299+
"<node_internals>/**/*.js"
300+
]
301+
}
302+
// END AwsSamPlugin
303+
]
304+
}`;
305+
const vscodeLaunchJsonTest = `{
306+
"version": "0.2.0",
307+
"configurations": [
308+
{
309+
"name": "CustomLambda",
310+
"type": "node",
311+
"request": "attach",
312+
"address": "localhost",
313+
"port": 5858,
314+
"localRoot": "\${workspaceFolder}/.aws-sam/build/CustomLambda",
315+
"remoteRoot": "/var/task",
316+
"protocol": "inspector",
317+
"stopOnEntry": false,
318+
"outFiles": [
319+
"\${workspaceFolder}/.aws-sam/build/CustomLambda/**/*.js"
320+
],
321+
"sourceMaps": true,
322+
"skipFiles": [
323+
"/var/runtime/**/*.js",
324+
"<node_internals>/**/*.js"
325+
]
326+
},
327+
// BEGIN AwsSamPlugin
328+
{
329+
"name": "MyLambda",
330+
"type": "node",
331+
"request": "attach",
332+
"address": "localhost",
333+
"port": 5858,
334+
"localRoot": "\${workspaceFolder}/.aws-sam/build/MyLambda",
335+
"remoteRoot": "/var/task",
336+
"protocol": "inspector",
337+
"stopOnEntry": false,
338+
"outFiles": [
339+
"\${workspaceFolder}/.aws-sam/build/MyLambda/**/*.js"
340+
],
341+
"sourceMaps": true,
342+
"skipFiles": [
343+
"/var/runtime/**/*.js",
344+
"<node_internals>/**/*.js"
345+
]
346+
}
347+
// END AwsSamPlugin
348+
]
349+
}`;
350+
351+
test.each([
352+
[vscodeLaunchJson1, vscodeLaunchJsonTest],
353+
[vscodeLaunchJson2, vscodeLaunchJsonTest],
354+
])("Happy build launch.json with replace old content", (srcData, testData) => {
355+
const plugin = new SamPlugin({ vscodeDebug: true });
356+
357+
// @ts-ignore
358+
fs.__clearMocks();
359+
// @ts-ignore
360+
fs.__setMockDirs(["."]);
361+
// @ts-ignore
362+
fs.__setMockFiles({ "./template.yaml": samTemplate, ".vscode/launch.json": srcData });
363+
364+
// @ts-ignore
365+
path.__clearMocks();
366+
// @ts-ignore
367+
path.__setMockBasenames({ "./template.yaml": "template.yaml" });
368+
// @ts-ignore
369+
path.__setMockDirnames({ "./template.yaml": "." });
370+
// @ts-ignore
371+
path.__setMockRelatives({ ".#.": "" });
372+
373+
const entryPoints = plugin.entry();
374+
375+
let afterEmit: (_compilation: any) => void;
376+
377+
plugin.apply({
378+
hooks: {
379+
afterEmit: {
380+
tap: (n: string, f: (_compilation: any) => void) => {
381+
afterEmit = f;
382+
},
383+
},
384+
},
385+
});
386+
// @ts-ignore
387+
afterEmit(null);
388+
389+
// @ts-ignore
390+
const vscodeLaunchJsonContent = fs.__getMockWrittenFiles()[".vscode/launch.json"];
391+
392+
expect(vscodeLaunchJsonContent).toEqual(testData);
393+
});
394+
236395
test("Happy path with multiple projects works", () => {
237396
const plugin = new SamPlugin({ projects: { a: "project-a", b: "project-b" } });
238397

src/index.ts

+31-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,37 @@ class AwsSamPlugin {
428428
if (!fs.existsSync(".vscode")) {
429429
fs.mkdirSync(".vscode");
430430
}
431-
fs.writeFileSync(".vscode/launch.json", JSON.stringify(this.launchConfig, null, 2));
431+
const launchPath = ".vscode/launch.json";
432+
433+
const launchContent = JSON.stringify(this.launchConfig, null, 2)
434+
.replace(/^(.*"configurations": \[\s*)$/m, "$1\n // BEGIN AwsSamPlugin")
435+
.replace(/(\n \s*\][\r\n]+\})$/m, "\n // END AwsSamPlugin$1");
436+
const regexBlock = /\s+\/\/ BEGIN AwsSamPlugin(\r|\n|.)+\/\/ END AwsSamPlugin/m;
437+
438+
// get new "configurations" content
439+
const matches = launchContent.match(regexBlock);
440+
if (!matches) {
441+
throw new Error(launchPath + " new content does not match");
442+
}
443+
const launchConfigurations = matches[0];
444+
445+
if (fs.existsSync(launchPath)) {
446+
const launchContentOld = fs.readFileSync(launchPath).toString("utf8");
447+
if (launchContentOld.match(regexBlock)) {
448+
// partial rewrite contents
449+
const newContent = launchContentOld.replace(regexBlock, () => launchConfigurations);
450+
fs.writeFileSync(launchPath, newContent);
451+
} else {
452+
// add configurations
453+
const newContent = launchContentOld.replace(
454+
/(\n \]\n\})$/m,
455+
(p0, p1) => `,${launchConfigurations}${p1}`
456+
);
457+
fs.writeFileSync(launchPath, newContent);
458+
}
459+
} else {
460+
fs.writeFileSync(launchPath, launchContent);
461+
}
432462
}
433463
});
434464
}

0 commit comments

Comments
 (0)