Repository: semantic-release/npm (js)

Issue:
Preserver `package.json` formatting
Using `readJson` and `writeJson` from `fs-extra` remove the JSON formatting and write the `package.json` as one long string.

It's a problem for plugins like `git` that publish the `pacakge.json`

Pull request:
Preserve `package.json` and `npm-shrinkwrap.json` formatting
Fix #21 

Patch:
diff --git a/lib/update-package-version.js b/lib/update-package-version.js
index 261010d..821909a 100644
--- a/lib/update-package-version.js
+++ b/lib/update-package-version.js
@@ -1,15 +1,18 @@
-const {readJson, writeJson, pathExists} = require('fs-extra');
+const {readFile, writeFile, pathExists} = require('fs-extra');
 
 module.exports = async (version, logger) => {
-  const pkg = await readJson('./package.json');
+  const pkg = (await readFile('./package.json')).toString();
 
-  await writeJson('./package.json', Object.assign(pkg, {version}));
+  await writeFile('./package.json', replaceVersion(pkg, version));
   logger.log('Wrote version %s to package.json', version);
 
   if (await pathExists('./npm-shrinkwrap.json')) {
-    const shrinkwrap = await readJson('./npm-shrinkwrap.json');
-    shrinkwrap.version = version;
-    await writeJson('./npm-shrinkwrap.json', shrinkwrap);
+    const shrinkwrap = (await readFile('./npm-shrinkwrap.json')).toString();
+    await writeFile('./npm-shrinkwrap.json', replaceVersion(shrinkwrap, version));
     logger.log('Wrote version %s to npm-shrinkwrap.json', version);
   }
 };
+
+function replaceVersion(json, version) {
+  return json.replace(/("version"\s*:\s*")\S+?(\s*")/, `$1${version}$2`);
+}


Test patch:
diff --git a/test/update-package-version.test.js b/test/update-package-version.test.js
index fa52a57..4f67cc7 100644
--- a/test/update-package-version.test.js
+++ b/test/update-package-version.test.js
@@ -1,5 +1,5 @@
 import test from 'ava';
-import {writeJson, readJson} from 'fs-extra';
+import {writeFile, readFile} from 'fs-extra';
 import tempy from 'tempy';
 import execa from 'execa';
 import {stub} from 'sinon';
@@ -21,28 +21,49 @@ test.afterEach.always(() => {
 });
 
 test.serial('Updade package.json', async t => {
+  const pkg = `{
+  "name": "test",
+  "description": "pacakage description",
+  "version":
+       "0.0.0-dev"   ,
+  "arr": [
+    1,
+        2, 3
+      ]
+}
+`;
+
   // Create package.json in repository root
-  await writeJson('./package.json', {version: '0.0.0-dev'});
+  await writeFile('./package.json', pkg);
 
   await updatePackageVersion('1.0.0', t.context.logger);
 
   // Verify package.json has been updated
-  t.is((await readJson('./package.json')).version, '1.0.0');
+  t.is((await readFile('./package.json')).toString(), pkg.replace('0.0.0-dev', '1.0.0'));
+
   // Verify the logger has been called with the version updated
   t.deepEqual(t.context.log.args[0], ['Wrote version %s to package.json', '1.0.0']);
 });
 
 test.serial('Updade package.json and npm-shrinkwrap.json', async t => {
+  const pkg = `{
+    "name": "test"
+    ,    "description":
+"pacakage description",
+
+    "version":      "0.0.0-dev"
+  }`;
   // Create package.json in repository root
-  await writeJson('./package.json', {version: '0.0.0-dev'});
+  await writeFile('./package.json', pkg);
   // Create a npm-shrinkwrap.json file
   await execa('npm', ['shrinkwrap']);
+  const shrinkwrap = (await readFile('./npm-shrinkwrap.json')).toString();
 
   await updatePackageVersion('1.0.0', t.context.logger);
 
   // Verify package.json and npm-shrinkwrap.json have been updated
-  t.is((await readJson('./package.json')).version, '1.0.0');
-  t.is((await readJson('./npm-shrinkwrap.json')).version, '1.0.0');
+  t.is((await readFile('./package.json')).toString(), pkg.replace('0.0.0-dev', '1.0.0'));
+  t.is((await readFile('./npm-shrinkwrap.json')).toString(), shrinkwrap.replace('0.0.0-dev', '1.0.0'));
   // Verify the logger has been called with the version updated
   t.deepEqual(t.context.log.args[0], ['Wrote version %s to package.json', '1.0.0']);
   t.deepEqual(t.context.log.args[1], ['Wrote version %s to npm-shrinkwrap.json', '1.0.0']);