Skip to content

Commit 1e74b7c

Browse files
authored
fix(gatsby-recipes): fix for when recipes have multiple NPMPackageJSON resources (#26281)
* fix(gatsby-recipes): restrict changes to package.json to one at a time * Add message for npmpackagejson + make install output denser * update snapshots
1 parent e2030ae commit 1e74b7c

File tree

4 files changed

+86
-28
lines changed

4 files changed

+86
-28
lines changed

packages/gatsby-recipes/src/cli/index.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,19 +441,23 @@ export default async ({
441441
const Installing = ({ state }) => (
442442
<Div>
443443
{state.context.plan.map((p, i) => (
444-
<Div key={`${p.resourceName}-${i}`}>
445-
<Text italic>{p.resourceName}:</Text>
444+
<Box
445+
textWrap="wrap"
446+
flexDirection="column"
447+
key={`${p.resourceName}-${i}`}
448+
>
446449
<Text>
450+
{p.isDone ? `✔ ` : <Spinner.default />}
447451
{` `}
448-
{p.isDone ? `✅ ` : <Spinner.default />}
452+
<Text italic>{p.resourceName}:</Text>
449453
{` `}
450454
{p.isDone ? p._message : p.describe}
451455
{` `}
452456
{state.context.elapsed > 0 && (
453457
<Text>({state.context.elapsed / 1000}s elapsed)</Text>
454458
)}
455459
</Text>
456-
</Div>
460+
</Box>
457461
))}
458462
</Div>
459463
)

packages/gatsby-recipes/src/providers/npm/__snapshots__/package-json.test.js.snap

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
exports[`packageJson resource e2e package resource test: PackageJson create 1`] = `
44
Object {
5+
"_message": "Wrote key \\"husky\\" to package.json",
56
"id": "husky",
67
"name": "husky",
7-
"value": "{
8-
\\"hooks\\": {}
9-
}",
8+
"value": "\\"{/n /\\"hooks/\\": {}/n}\\"",
109
}
1110
`;
1211

@@ -41,13 +40,10 @@ exports[`packageJson resource e2e package resource test: PackageJson destroy 1`]
4140

4241
exports[`packageJson resource e2e package resource test: PackageJson update 1`] = `
4342
Object {
43+
"_message": "Wrote key \\"husky\\" to package.json",
4444
"id": "husky",
4545
"name": "husky",
46-
"value": "{
47-
\\"hooks\\": {
48-
\\"pre-commit\\": \\"lint-staged\\"
49-
}
50-
}",
46+
"value": "\\"{/n /\\"hooks/\\": {/n /\\"pre-commit/\\": /\\"lint-staged/\\"/n }/n}\\"",
5147
}
5248
`;
5349
@@ -56,26 +52,22 @@ Object {
5652
"currentState": "{
5753
\\"name\\": \\"test\\",
5854
\\"scripts\\": {},
59-
\\"husky\\": {
60-
\\"hooks\\": {}
61-
}
55+
\\"husky\\": \\"{/n /\\"hooks/\\": {}/n}\\"
6256
}",
6357
"describe": "Add husky to package.json",
64-
"diff": "- Original - 3
65-
+ Modified + 5
58+
"diff": "- Original - 1
59+
+ Modified + 3
6660
61+
@@ -1,6 +1,8 @@
6762
Object {
68-
- \\"husky\\": Object {
69-
- \\"hooks\\": Object {},
70-
- },
71-
+ \\"husky\\": \\"{
63+
\\"husky\\": \\"{
64+
- /\\"hooks/\\": {}
7265
+ /\\"hooks/\\": {
7366
+ /\\"pre-commit/\\": /\\"lint-staged/\\"
7467
+ }
75-
+ }\\",
68+
}\\",
7669
\\"name\\": \\"test\\",
77-
\\"scripts\\": Object {},
78-
}",
70+
\\"scripts\\": Object {},",
7971
"id": "husky",
8072
"name": "husky",
8173
"newState": "{
@@ -88,6 +80,7 @@ Object {
8880

8981
exports[`packageJson resource handles object values 1`] = `
9082
Object {
83+
"_message": "Wrote key \\"husky\\" to package.json",
9184
"id": "husky",
9285
"name": "husky",
9386
"value": "{

packages/gatsby-recipes/src/providers/npm/package-json.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,63 @@ const getDiff = require(`../utils/get-diff`)
55

66
const resourceSchema = require(`../resource-schema`)
77

8+
class Deferred {
9+
constructor(name) {
10+
this._promise = new Promise((resolve, reject) => {
11+
// assign the resolve and reject functions to `this`
12+
// making them usable on the class instance
13+
this.resolve = resolve
14+
this.reject = reject
15+
})
16+
this.name = name
17+
// bind `then` and `catch` to implement the same interface as Promise
18+
this.then = this._promise.then.bind(this._promise)
19+
this.catch = this._promise.catch.bind(this._promise)
20+
this[Symbol.toStringTag] = `Promise`
21+
}
22+
}
23+
let writesQueue = new Map()
24+
let paused = false
25+
const checkWritesQueue = async root =>
26+
new Promise((resolve, reject) => {
27+
setTimeout(async () => {
28+
if (writesQueue.size > 0) {
29+
await processWritesQueue(root)
30+
resolve()
31+
} else {
32+
paused = false
33+
}
34+
}, 100)
35+
})
36+
37+
const processWritesQueue = async root => {
38+
const toProcess = [...writesQueue.entries()]
39+
writesQueue = new Map()
40+
const pkg = await readPackageJson(root)
41+
toProcess.forEach(change => {
42+
pkg[change[0]] = change[1].value
43+
})
44+
45+
await writePackageJson(root, pkg)
46+
toProcess.forEach(change => {
47+
change[1].dfd.resolve()
48+
})
49+
await checkWritesQueue(root)
50+
}
51+
52+
const enqueueWrite = (root, change) => {
53+
const dfd = new Deferred(change[0])
54+
writesQueue.set(change[0], { value: change[1], dfd })
55+
56+
// If we're not paused, write immediately
57+
if (!paused) {
58+
paused = true
59+
processWritesQueue(root)
60+
}
61+
62+
return dfd
63+
}
64+
865
const readPackageJson = async root => {
966
const fullPath = path.join(root, `package.json`)
1067
const contents = await fs.readFile(fullPath, `utf8`)
@@ -19,10 +76,7 @@ const writePackageJson = async (root, obj) => {
1976
}
2077

2178
const create = async ({ root }, { name, value }) => {
22-
const pkg = await readPackageJson(root)
23-
pkg[name] = typeof value === `string` ? JSON.parse(value) : value
24-
25-
await writePackageJson(root, pkg)
79+
await enqueueWrite(root, [name, value])
2680

2781
return await read({ root }, name)
2882
}
@@ -38,6 +92,7 @@ const read = async ({ root }, id) => {
3892
id,
3993
name: id,
4094
value: JSON.stringify(pkg[id], null, 2),
95+
_message: `Wrote key "${id}" to package.json`,
4196
}
4297
}
4398

packages/gatsby-recipes/src/renderer/render.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,14 @@ const handleResource = (resourceName, context, props) => {
173173
resolve(cachedValue)
174174
updateResource(cachedValue)
175175
} else {
176+
// if (fn == `create`) {
177+
// console.log(`start creating resource:`, { context, props })
178+
// }
176179
resources[resourceName][fn](context, props)
177180
.then(result => {
181+
// if (fn == `create`) {
182+
// console.log(`finish creating resource:`, { props })
183+
// }
178184
updateResource(result)
179185
inFlightCache.set(cacheKey, false)
180186
return result

0 commit comments

Comments
 (0)