Skip to content

Commit 7cff0f1

Browse files
authored
Prevent package.json rewrite from being checked in with test (#1809)
* Fix up package.json rewrite VSCode package.json is readonly. Rewriting package.json will use the disk package.json to prevent getting expanded fields from VSCode. It will only read from disk once. Added `gulp pr-check` to make sure that package.json activationEvents has not been rewritten for open source contributers. * run pr-check needs to be before run test * Update log message
1 parent 6517b8e commit 7cff0f1

File tree

6 files changed

+44
-13
lines changed

6 files changed

+44
-13
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ script:
3333
- npm install
3434
- npm run tslint
3535
- npm run compile
36+
# pr-check needs to run before test. test modifies package.json.
37+
- npm run pr-check
3638
- npm run test
3739

3840
after_failure:

Extension/gulpfile.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const gulp = require('gulp');
99
const env = require('gulp-env')
1010
const tslint = require('gulp-tslint');
1111
const mocha = require('gulp-mocha');
12+
const fs = require('fs');
1213

1314
gulp.task('allTests', () => {
1415
gulp.start('unitTests');
@@ -73,4 +74,12 @@ gulp.task('tslint', () => {
7374
summarizeFailureOutput: false,
7475
emitError: false
7576
}))
77+
});
78+
79+
gulp.task('pr-check', () => {
80+
const packageJson = JSON.parse(fs.readFileSync('./package.json').toString());
81+
if (packageJson.activationEvents.length !== 1 && packageJson.activationEvents[0] !== '*') {
82+
console.log('Please make sure to not check in package.json that has been rewritten by the extension activation. If you intended to have changes in package.json, please only check-in your changes. If you did not, please run `git checkout -- package.json`.');
83+
process.exit(1);
84+
}
7685
});

Extension/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,7 @@
11091109
"integrationTests": "gulp integrationTests",
11101110
"postinstall": "node ./node_modules/vscode/bin/install",
11111111
"pretest": "tsc -p ./",
1112+
"pr-check": "gulp pr-check",
11121113
"test": "gulp allTests",
11131114
"tslint": "gulp tslint",
11141115
"unitTests": "gulp unitTests",

Extension/src/abTesting.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,17 @@ export function downloadCpptoolsJsonPkg(): Promise<void> {
8080
export function processCpptoolsJson(cpptoolsString: string): Promise<void> {
8181
let cpptoolsObject: any = JSON.parse(cpptoolsString);
8282
let intelliSenseEnginePercentage: number = cpptoolsObject.intelliSenseEngine_default_percentage;
83+
let packageJson: any = util.getRawPackageJson();
8384

84-
if (!util.packageJson.extensionFolderPath.includes(".vscode-insiders")) {
85-
let prevIntelliSenseEngineDefault: any = util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
85+
if (!packageJson.extensionFolderPath.includes(".vscode-insiders")) {
86+
let prevIntelliSenseEngineDefault: any = packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
8687
if (util.extensionContext.globalState.get<number>(userBucketString, userBucketMax + 1) <= intelliSenseEnginePercentage) {
87-
util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
88+
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
8889
} else {
89-
util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
90+
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
9091
}
91-
if (prevIntelliSenseEngineDefault !== util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
92-
return util.writeFileText(util.getPackageJsonPath(), util.getPackageJsonString());
92+
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
93+
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
9394
}
9495
}
9596
}

Extension/src/common.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,34 @@ export function setExtensionContext(context: vscode.ExtensionContext): void {
2020
extensionContext = context;
2121
}
2222

23-
export let packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools").packageJSON;
23+
// Use this package.json to read values
24+
export const packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools").packageJSON;
25+
26+
// Use getRawPackageJson to read and write back to package.json
27+
// This prevents obtaining any of VSCode's expanded variables.
28+
let rawPackageJson: any = null;
29+
export function getRawPackageJson(): any {
30+
if (rawPackageJson === null) {
31+
const fileContents: Buffer = fs.readFileSync(getPackageJsonPath());
32+
rawPackageJson = JSON.parse(fileContents.toString());
33+
}
34+
return rawPackageJson;
35+
}
36+
37+
// This function is used to stringify the rawPackageJson.
38+
// Do not use with util.packageJson or else the expanded
39+
// package.json will be written back.
40+
export function stringifyPackageJson(packageJson: string): string {
41+
return JSON.stringify(packageJson, null, 2);
42+
}
2443

2544
export function getExtensionFilePath(extensionfile: string): string {
2645
return path.resolve(extensionContext.extensionPath, extensionfile);
2746
}
47+
2848
export function getPackageJsonPath(): string {
2949
return getExtensionFilePath("package.json");
3050
}
31-
export function getPackageJsonString(): string {
32-
packageJson.main = "./out/src/main"; // Needs to be reset, because the relative path is removed by VS Code.
33-
return JSON.stringify(packageJson, null, 2);
34-
}
3551

3652
// Extension is ready if install.lock exists and debugAdapters folder exist.
3753
export async function isExtensionReady(): Promise<boolean> {

Extension/src/main.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,9 @@ async function finalizeExtensionActivation(): Promise<void> {
287287

288288
function rewriteManifest(): Promise<void> {
289289
// Replace activationEvents with the events that the extension should be activated for subsequent sessions.
290-
util.packageJson.activationEvents = [
290+
let packageJson: any = util.getRawPackageJson();
291+
292+
packageJson.activationEvents = [
291293
"onLanguage:cpp",
292294
"onLanguage:c",
293295
"onCommand:extension.pickNativeProcess",
@@ -310,5 +312,5 @@ function rewriteManifest(): Promise<void> {
310312
"onDebug"
311313
];
312314

313-
return util.writeFileText(util.getPackageJsonPath(), util.getPackageJsonString());
315+
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
314316
}

0 commit comments

Comments
 (0)