Skip to content

Commit 510f0ec

Browse files
authored
fix(arborist): ensure indentation is preserved (#4218)
It turns out that `new Arborist().buildIdealTree().meta.toString()` does not take into account the indentation in the package.json (tabs, in my case) the way `npm install --package-lock-only` does. This fixes that. Also included a bonus commit that removes redundant Promise stuff inside an `async function`.
1 parent a92665c commit 510f0ec

File tree

4 files changed

+60
-12
lines changed

4 files changed

+60
-12
lines changed

workspaces/arborist/lib/arborist/build-ideal-tree.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
176176
// public method
177177
async buildIdealTree (options = {}) {
178178
if (this.idealTree) {
179-
return Promise.resolve(this.idealTree)
179+
return this.idealTree
180180
}
181181

182182
// allow the user to set reify options on the ctor as well.
@@ -194,8 +194,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
194194
process.emit('time', 'idealTree')
195195

196196
if (!options.add && !options.rm && !options.update && this[_global]) {
197-
const er = new Error('global requires add, rm, or update option')
198-
return Promise.reject(er)
197+
throw new Error('global requires add, rm, or update option')
199198
}
200199

201200
// first get the virtual tree, if possible. If there's a lockfile, then
@@ -334,6 +333,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
334333
root.meta.lockfileVersion = defaultLockfileVersion
335334
}
336335
}
336+
root.meta.inferFormattingOptions(root.package)
337337
return root
338338
})
339339

workspaces/arborist/lib/shrinkwrap.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,18 @@ class Shrinkwrap {
424424
.map(fn => fn && maybeStatFile(fn)))
425425
}
426426

427+
inferFormattingOptions (packageJSONData) {
428+
// don't use detect-indent, just pick the first line.
429+
// if the file starts with {" then we have an indent of '', ie, none
430+
// which will default to 2 at save time.
431+
const {
432+
[Symbol.for('indent')]: indent,
433+
[Symbol.for('newline')]: newline,
434+
} = packageJSONData
435+
this.indent = indent !== undefined ? indent : this.indent
436+
this.newline = newline !== undefined ? newline : this.newline
437+
}
438+
427439
load () {
428440
// we don't need to load package-lock.json except for top of tree nodes,
429441
// only npm-shrinkwrap.json.
@@ -451,15 +463,7 @@ class Shrinkwrap {
451463

452464
return data ? parseJSON(data) : {}
453465
}).then(async data => {
454-
// don't use detect-indent, just pick the first line.
455-
// if the file starts with {" then we have an indent of '', ie, none
456-
// which will default to 2 at save time.
457-
const {
458-
[Symbol.for('indent')]: indent,
459-
[Symbol.for('newline')]: newline,
460-
} = data
461-
this.indent = indent !== undefined ? indent : this.indent
462-
this.newline = newline !== undefined ? newline : this.newline
466+
this.inferFormattingOptions(data)
463467

464468
if (!this.hiddenLockfile || !data.packages) {
465469
return data

workspaces/arborist/tap-snapshots/test/arborist/build-ideal-tree.js.test.cjs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97673,6 +97673,37 @@ ArboristNode {
9767397673
}
9767497674
`
9767597675

97676+
exports[`test/arborist/build-ideal-tree.js TAP store files with a custom indenting > must match snapshot 1`] = `
97677+
{
97678+
"name": "tab-indented-package-json",
97679+
"version": "1.0.0",
97680+
"lockfileVersion": 2,
97681+
"requires": true,
97682+
"packages": {
97683+
"": {
97684+
"name": "tab-indented-package-json",
97685+
"version": "1.0.0",
97686+
"dependencies": {
97687+
"abbrev": "^1.0.0"
97688+
}
97689+
},
97690+
"node_modules/abbrev": {
97691+
"version": "1.1.1",
97692+
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
97693+
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
97694+
}
97695+
},
97696+
"dependencies": {
97697+
"abbrev": {
97698+
"version": "1.1.1",
97699+
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
97700+
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
97701+
}
97702+
}
97703+
}
97704+
97705+
`
97706+
9767697707
exports[`test/arborist/build-ideal-tree.js TAP tap vs react15 > build ideal tree with tap collision 1`] = `
9767797708
ArboristNode {
9767897709
"children": Map {

workspaces/arborist/test/arborist/build-ideal-tree.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3682,3 +3682,16 @@ t.test('overrides', t => {
36823682

36833683
t.end()
36843684
})
3685+
3686+
t.test('store files with a custom indenting', async t => {
3687+
const tabIndentedPackageJson =
3688+
fs.readFileSync(
3689+
resolve(__dirname, '../fixtures/tab-indented-package-json/package.json'),
3690+
'utf8'
3691+
).replace(/\r\n/g, '\n')
3692+
const path = t.testdir({
3693+
'package.json': tabIndentedPackageJson,
3694+
})
3695+
const tree = await buildIdeal(path)
3696+
t.matchSnapshot(String(tree.meta))
3697+
})

0 commit comments

Comments
 (0)