From ae7f14a0341e119e1a25d226c347ca7bf7e7e86b Mon Sep 17 00:00:00 2001 From: logikgate Date: Mon, 22 Oct 2018 15:56:53 -0400 Subject: [PATCH 1/3] Use npm's modules to stringify package.json file before save. Fixes #4049 --- lib/common/declarations.d.ts | 10 ++++++++++ lib/common/file-system.ts | 10 +++++++++- npm-shrinkwrap.json | 21 +++++++++++++++++++-- package.json | 2 ++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/common/declarations.d.ts b/lib/common/declarations.d.ts index 8aedd1092c..9ed22e4641 100644 --- a/lib/common/declarations.d.ts +++ b/lib/common/declarations.d.ts @@ -2011,3 +2011,13 @@ interface ILockFile { */ check(lockFilePath?: string, lockFileOpts?: ILockFileOptions): boolean; } + +declare module "stringify-package" { + function stringifyPackage(data: any, indent: any, newline: string): string + export = stringifyPackage +} + +declare module "detect-newline" { + function detectNewline(data: string): string | null; + export = detectNewline +} \ No newline at end of file diff --git a/lib/common/file-system.ts b/lib/common/file-system.ts index 2d01ce4694..29e03e597e 100644 --- a/lib/common/file-system.ts +++ b/lib/common/file-system.ts @@ -5,6 +5,8 @@ import * as injector from "./yok"; import * as crypto from "crypto"; import * as shelljs from "shelljs"; import { parseJson } from "./helpers"; +import stringifyPackage = require("stringify-package"); +import detectNewline = require("detect-newline"); // TODO: Add .d.ts for mkdirp module (or use it from @types repo). const mkdirp = require("mkdirp"); @@ -205,7 +207,13 @@ export class FileSystem implements IFileSystem { space = this.getIndentationCharacter(filename); } - return this.writeFile(filename, JSON.stringify(data, null, space), encoding); + let stringifiedData = JSON.stringify(data, null, space); + if (path.basename(filename) === "package.json") { + const newline = detectNewline(stringifiedData); + stringifiedData = stringifyPackage(data, space, newline); + } + + return this.writeFile(filename, stringifiedData, encoding); } public copyFile(sourceFileName: string, destinationFileName: string): void { diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 20a261d279..8686d5b0d2 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1580,8 +1580,7 @@ "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" }, "diff": { "version": "1.4.0", @@ -4721,6 +4720,19 @@ "supports-color": "^5.3.0" } }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "requires": { + "colors": "1.0.3" + } + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -7236,6 +7248,11 @@ "safe-buffer": "~5.1.0" } }, + "stringify-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.0.tgz", + "integrity": "sha512-JIQqiWmLiEozOC0b0BtxZ/AOUtdUZHCBPgqIZ2kSJJqGwgb9neo44XdTHUC4HZSGqi03hOeB7W/E8rAlKnGe9g==" + }, "stringstream": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", diff --git a/package.json b/package.json index 9744212132..36c1a3186c 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "cli-table": "https://github.com/telerik/cli-table/tarball/v0.3.1.2", "color": "3.0.0", "colors": "1.1.2", + "detect-newline": "^2.1.0", "email-validator": "1.0.4", "esprima": "2.7.0", "gaze": "1.1.0", @@ -73,6 +74,7 @@ "shelljs": "0.7.6", "simple-plist": "0.2.1", "source-map": "0.5.6", + "stringify-package": "^1.0.0", "tabtab": "https://github.com/Icenium/node-tabtab/tarball/master", "tar": "4.4.4", "temp": "0.8.3", From b17dc9acc3b0f9e76d897fa0aeb14d75384f5656 Mon Sep 17 00:00:00 2001 From: logikgate Date: Mon, 29 Oct 2018 17:44:24 -0400 Subject: [PATCH 2/3] Pin packages to exact versions --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 36c1a3186c..278a27cabf 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "cli-table": "https://github.com/telerik/cli-table/tarball/v0.3.1.2", "color": "3.0.0", "colors": "1.1.2", - "detect-newline": "^2.1.0", + "detect-newline": "2.1.0", "email-validator": "1.0.4", "esprima": "2.7.0", "gaze": "1.1.0", @@ -74,7 +74,7 @@ "shelljs": "0.7.6", "simple-plist": "0.2.1", "source-map": "0.5.6", - "stringify-package": "^1.0.0", + "stringify-package": "1.0.0", "tabtab": "https://github.com/Icenium/node-tabtab/tarball/master", "tar": "4.4.4", "temp": "0.8.3", From 14d52e031a03376e2506347e5cfd2cfc6b6d585b Mon Sep 17 00:00:00 2001 From: logikgate Date: Mon, 29 Oct 2018 17:44:56 -0400 Subject: [PATCH 3/3] Only stringify once and correctly detect existing file newline --- lib/common/file-system.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/common/file-system.ts b/lib/common/file-system.ts index 29e03e597e..802bfcfce9 100644 --- a/lib/common/file-system.ts +++ b/lib/common/file-system.ts @@ -5,6 +5,8 @@ import * as injector from "./yok"; import * as crypto from "crypto"; import * as shelljs from "shelljs"; import { parseJson } from "./helpers"; +import { PACKAGE_JSON_FILE_NAME } from "../constants"; +import { EOL } from "os"; import stringifyPackage = require("stringify-package"); import detectNewline = require("detect-newline"); @@ -207,10 +209,16 @@ export class FileSystem implements IFileSystem { space = this.getIndentationCharacter(filename); } - let stringifiedData = JSON.stringify(data, null, space); - if (path.basename(filename) === "package.json") { - const newline = detectNewline(stringifiedData); + let stringifiedData; + if (path.basename(filename) === PACKAGE_JSON_FILE_NAME) { + let newline = EOL; + if (fs.existsSync(filename)) { + const existingFile = this.readText(filename); + newline = detectNewline(existingFile); + } stringifiedData = stringifyPackage(data, space, newline); + } else { + stringifiedData = JSON.stringify(data, null, space); } return this.writeFile(filename, stringifiedData, encoding);