From 6cb147bd9cdbe08fb0cbc65f09948236c36fd3e0 Mon Sep 17 00:00:00 2001 From: Andrew Sprouse Date: Tue, 11 Jun 2019 23:04:20 -0400 Subject: [PATCH] Fix `yarn list --json` stdOut parsing. fixes #388 --- lib/packagers/yarn.js | 8 +++++++- lib/packagers/yarn.test.js | 24 ++++++++++++++++-------- lib/utils.js | 16 +++++++++++++++- lib/utils.test.js | 16 ++++++++++++++++ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/lib/packagers/yarn.js b/lib/packagers/yarn.js index 4b3721b9b..d1dcd74d9 100644 --- a/lib/packagers/yarn.js +++ b/lib/packagers/yarn.js @@ -62,7 +62,13 @@ class Yarn { return BbPromise.reject(err); }) .then(processOutput => processOutput.stdout) - .then(depJson => BbPromise.try(() => JSON.parse(depJson))) + .then(stdout => + BbPromise.try(() => { + const lines = Utils.splitLines(stdout); + const parsedLines = _.map(lines, Utils.safeJsonParse); + return _.find(parsedLines, line => line && line.type === 'tree'); + }) + ) .then(parsedTree => { const convertTrees = trees => _.reduce( diff --git a/lib/packagers/yarn.test.js b/lib/packagers/yarn.test.js index 0e58d46f0..52445ad4a 100644 --- a/lib/packagers/yarn.test.js +++ b/lib/packagers/yarn.test.js @@ -61,14 +61,22 @@ describe('yarn', () => { }); it('should transform yarn trees to npm dependencies', () => { - const testYarnResult = `{"type":"tree","data":{"type":"list","trees":[ - {"name":"archiver@2.1.1","children":[],"hint":null,"color":"bold", - "depth":0},{"name":"bluebird@3.5.1","children":[],"hint":null,"color": - "bold","depth":0},{"name":"fs-extra@4.0.3","children":[],"hint":null, - "color":"bold","depth":0},{"name":"mkdirp@0.5.1","children":[{"name": - "minimist@0.0.8","children":[],"hint":null,"color":"bold","depth":0}], - "hint":null,"color":null,"depth":0},{"name":"@sls/webpack@1.0.0", - "children":[],"hint":null,"color":"bold","depth":0}]}}`; + const testYarnResult = + '{"type":"activityStart","data":{"id":0}}\n' + + '{"type":"activityTick","data":{"id":0,"name":"archiver@^2.1.1"}}\n' + + '{"type":"activityTick","data":{"id":0,"name":"bluebird@^3.5.1"}}\n' + + '{"type":"activityTick","data":{"id":0,"name":"fs-extra@^4.0.3"}}\n' + + '{"type":"activityTick","data":{"id":0,"name":"mkdirp@^0.5.1"}}\n' + + '{"type":"activityTick","data":{"id":0,"name":"minimist@^0.0.8"}}\n' + + '{"type":"activityTick","data":{"id":0,"name":"@sls/webpack@^1.0.0"}}\n' + + '{"type":"tree","data":{"type":"list","trees":[' + + '{"name":"archiver@2.1.1","children":[],"hint":null,"color":"bold",' + + '"depth":0},{"name":"bluebird@3.5.1","children":[],"hint":null,"color":' + + '"bold","depth":0},{"name":"fs-extra@4.0.3","children":[],"hint":null,' + + '"color":"bold","depth":0},{"name":"mkdirp@0.5.1","children":[{"name":' + + '"minimist@0.0.8","children":[],"hint":null,"color":"bold","depth":0}],' + + '"hint":null,"color":null,"depth":0},{"name":"@sls/webpack@1.0.0",' + + '"children":[],"hint":null,"color":"bold","depth":0}]}}\n'; const expectedResult = { problems: [], dependencies: { diff --git a/lib/utils.js b/lib/utils.js index 7609265c8..5bb12ff67 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -96,10 +96,24 @@ function spawnProcess(command, args, options) { }); } +function safeJsonParse(str) { + try { + return JSON.parse(str); + } catch (e) { + return null; + } +} + +function splitLines(str) { + return _.split(str, /\r?\n/); +} + module.exports = { guid, purgeCache, searchAndProcessCache, SpawnError, - spawnProcess + spawnProcess, + safeJsonParse, + splitLines }; diff --git a/lib/utils.test.js b/lib/utils.test.js index a0a6479db..5d751673f 100644 --- a/lib/utils.test.js +++ b/lib/utils.test.js @@ -118,4 +118,20 @@ describe('Utils', () => { return expect(Utils.spawnProcess('cmd', [])).to.be.rejectedWith(Utils.SpawnError); }); }); + + describe('safeJsonParse', () => { + it('should parse valid JSON', () => { + expect(Utils.safeJsonParse('{"foo": "bar"}')).to.deep.equal({ foo: 'bar' }); + }); + + it('should return null for invalid JSON', () => { + expect(Utils.safeJsonParse('{"foo":')).to.equal(null); + }); + }); + + describe('splitLines', () => { + it('should split on new line characters', () => { + expect(Utils.splitLines('a\r\nb\nc')).to.deep.equal([ 'a', 'b', 'c' ]); + }); + }); });