Skip to content

Commit c6851b7

Browse files
committed
collate errors by default
1 parent 4a17770 commit c6851b7

File tree

7 files changed

+112
-69
lines changed

7 files changed

+112
-69
lines changed

integration-tests/broken-patch-file/__snapshots__/broken-patch-file.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ exports[`Test broken-patch-file: patch-package fails when patch file is invalid
2323
https://github.com/ds300/patch-package/issues
2424
2525
26+
---
27+
patch-package finished with 1 error(s).
2628
END SNAPSHOT"
2729
`;

integration-tests/dev-only-patches/__snapshots__/dev-only-patches.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Error: Patch file found for package fake-package which is not present at node_mo
1818
1919
fake-package+3.0.0.dev.patch
2020
21+
---
22+
patch-package finished with 1 error(s).
2123
END SNAPSHOT"
2224
`;
2325

integration-tests/fails-when-no-package/__snapshots__/fails-when-no-package.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
exports[`Test fails-when-no-package: no package present failure 1`] = `
44
"SNAPSHOT: no package present failure
55
Error: Patch file found for package left-pad which is not present at node_modules/left-pad
6+
---
7+
patch-package finished with 1 error(s).
68
END SNAPSHOT"
79
`;

integration-tests/package-gets-updated/__snapshots__/package-gets-updated.test.ts.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ warning [email protected]: use String.prototype.padStart()
3030
Patch was made for version: 1.1.1
3131
Installed version: 1.1.3
3232
33+
---
34+
patch-package finished with 1 error(s).
3335
error Command failed with exit code 1.
3436
END SNAPSHOT"
3537
`;
@@ -74,5 +76,7 @@ Warning: patch-package detected a patch file version mismatch
7476
7577
to update the version in the patch file name and make this warning go away.
7678
79+
---
80+
patch-package finished with 1 warning(s).
7781
END SNAPSHOT"
7882
`;

src/applyPatches.ts

Lines changed: 100 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import semver from "semver"
1414
import { readPatch } from "./patch/read"
1515
import { packageIsDevDependency } from "./packageIsDevDependency"
1616

17+
class PatchApplicationError extends Error {
18+
constructor(msg: string) {
19+
super(msg)
20+
}
21+
}
22+
1723
// don't want to exit(1) on postinsall locally.
1824
// see https://github.com/ds300/patch-package/issues/86
1925
const shouldExitPostinstallWithError = isCi || process.env.NODE_ENV === "test"
@@ -46,39 +52,35 @@ function getInstalledPackageVersion({
4652
if (process.env.NODE_ENV === "production" && isDevOnly) {
4753
return null
4854
}
49-
console.error(
55+
56+
let err =
5057
`${chalk.red("Error:")} Patch file found for package ${posix.basename(
5158
pathSpecifier,
52-
)}` + ` which is not present at ${relative(".", packageDir)}`,
53-
)
59+
)}` + ` which is not present at ${relative(".", packageDir)}`
5460

5561
if (!isDevOnly && process.env.NODE_ENV === "production") {
56-
console.error(
57-
`
62+
err += `
63+
5864
If this package is a dev dependency, rename the patch file to
5965
6066
${chalk.bold(patchFilename.replace(".patch", ".dev.patch"))}
61-
`,
62-
)
67+
`
6368
}
64-
65-
throw new Error("applyPatches")
69+
throw new PatchApplicationError(err)
6670
}
6771

6872
const { version } = require(join(packageDir, "package.json"))
6973
// normalize version for `npm ci`
7074
const result = semver.valid(version)
7175
if (result === null) {
72-
console.error(
76+
throw new PatchApplicationError(
7377
`${chalk.red(
7478
"Error:",
7579
)} Version string '${version}' cannot be parsed from ${join(
7680
packageDir,
7781
"package.json",
7882
)}`,
7983
)
80-
81-
throw new Error("applyPatches")
8284
}
8385

8486
return result as string
@@ -87,12 +89,10 @@ function getInstalledPackageVersion({
8789
export function applyPatchesForApp({
8890
appPath,
8991
reverse,
90-
ignoreErrors,
9192
patchDir,
9293
}: {
9394
appPath: string
9495
reverse: boolean
95-
ignoreErrors: boolean
9696
patchDir: string
9797
}): void {
9898
const patchesDirectory = join(appPath, patchDir)
@@ -103,14 +103,18 @@ export function applyPatchesForApp({
103103
return
104104
}
105105

106-
let hasFailed = false
107-
files.forEach((filename, idx) => {
106+
const errors: string[] = []
107+
const warnings: string[] = []
108+
109+
for (const filename of files) {
108110
try {
109111
const packageDetails = getPackageDetailsFromPatchFilename(filename)
110112

111113
if (!packageDetails) {
112-
console.warn(`Unrecognized patch file in patches directory ${filename}`)
113-
return
114+
warnings.push(
115+
`Unrecognized patch file in patches directory ${filename}`,
116+
)
117+
continue
114118
}
115119

116120
const {
@@ -140,7 +144,7 @@ export function applyPatchesForApp({
140144
pathSpecifier,
141145
)}@${version} ${chalk.blue("✔")}`,
142146
)
143-
return
147+
continue
144148
}
145149

146150
if (
@@ -154,59 +158,76 @@ export function applyPatchesForApp({
154158
// yay patch was applied successfully
155159
// print warning if version mismatch
156160
if (installedPackageVersion !== version) {
157-
printVersionMismatchWarning({
158-
packageName: name,
159-
actualVersion: installedPackageVersion,
160-
originalVersion: version,
161-
pathSpecifier,
162-
path,
163-
})
161+
warnings.push(
162+
createVersionMismatchWarning({
163+
packageName: name,
164+
actualVersion: installedPackageVersion,
165+
originalVersion: version,
166+
pathSpecifier,
167+
path,
168+
}),
169+
)
164170
} else {
165171
console.log(
166172
`${chalk.bold(pathSpecifier)}@${version} ${chalk.green("✔")}`,
167173
)
168174
}
169-
} else {
175+
} else if (installedPackageVersion === version) {
170176
// completely failed to apply patch
171177
// TODO: propagate useful error messages from patch application
172-
if (installedPackageVersion === version) {
173-
printBrokenPatchFileError({
178+
errors.push(
179+
createBrokenPatchFileError({
174180
packageName: name,
175181
patchFileName: filename,
176182
pathSpecifier,
177183
path,
178-
})
179-
} else {
180-
printPatchApplictionFailureError({
184+
}),
185+
)
186+
} else {
187+
errors.push(
188+
createPatchApplictionFailureError({
181189
packageName: name,
182190
actualVersion: installedPackageVersion,
183191
originalVersion: version,
184192
patchFileName: filename,
185193
path,
186194
pathSpecifier,
187-
})
188-
}
189-
190-
throw new Error("applyPatches")
191-
}
192-
} catch (err) {
193-
if (err.message !== "applyPatches") {
194-
throw err
195-
}
196-
if (!ignoreErrors) {
197-
exit()
198-
}
199-
hasFailed = true
200-
if (idx < files.length - 1) {
201-
console.warn(
202-
`${chalk.yellow("Warning:")} Option ${chalk.bold(
203-
"--ignore-errors",
204-
)} was set, moving on to next patch.`,
195+
}),
205196
)
206197
}
198+
} catch (error) {
199+
if (error instanceof PatchApplicationError) {
200+
errors.push(error.message)
201+
} else {
202+
errors.push(createUnexpectedError({ filename, error }))
203+
}
207204
}
208-
})
209-
if (hasFailed) {
205+
}
206+
207+
for (const warning of warnings) {
208+
console.warn(warning)
209+
}
210+
for (const error of errors) {
211+
console.error(error)
212+
}
213+
214+
const problemsSummary = []
215+
if (warnings.length) {
216+
problemsSummary.push(chalk.yellow(`${warnings.length} warning(s)`))
217+
}
218+
if (errors.length) {
219+
problemsSummary.push(chalk.red(`${errors.length} error(s)`))
220+
}
221+
222+
if (problemsSummary.length) {
223+
console.error("---")
224+
console.error(
225+
"patch-package finished with",
226+
problemsSummary.join(", ") + ".",
227+
)
228+
}
229+
230+
if (errors.length) {
210231
exit()
211232
}
212233
}
@@ -236,7 +257,7 @@ export function applyPatch({
236257
return true
237258
}
238259

239-
function printVersionMismatchWarning({
260+
function createVersionMismatchWarning({
240261
packageName,
241262
actualVersion,
242263
originalVersion,
@@ -249,8 +270,8 @@ function printVersionMismatchWarning({
249270
pathSpecifier: string
250271
path: string
251272
}) {
252-
console.warn(`
253-
${chalk.red("Warning:")} patch-package detected a patch file version mismatch
273+
return `
274+
${chalk.yellow("Warning:")} patch-package detected a patch file version mismatch
254275
255276
Don't worry! This is probably fine. The patch was still applied
256277
successfully. Here's the deets:
@@ -274,10 +295,10 @@ ${chalk.red("Warning:")} patch-package detected a patch file version mismatch
274295
${chalk.bold(`patch-package ${pathSpecifier}`)}
275296
276297
to update the version in the patch file name and make this warning go away.
277-
`)
298+
`
278299
}
279300

280-
function printBrokenPatchFileError({
301+
function createBrokenPatchFileError({
281302
packageName,
282303
patchFileName,
283304
path,
@@ -288,7 +309,7 @@ function printBrokenPatchFileError({
288309
path: string
289310
pathSpecifier: string
290311
}) {
291-
console.error(`
312+
return `
292313
${chalk.red.bold("**ERROR**")} ${chalk.red(
293314
`Failed to apply patch for package ${chalk.bold(packageName)} at path`,
294315
)}
@@ -310,10 +331,10 @@ ${chalk.red.bold("**ERROR**")} ${chalk.red(
310331
311332
https://github.com/ds300/patch-package/issues
312333
313-
`)
334+
`
314335
}
315336

316-
function printPatchApplictionFailureError({
337+
function createPatchApplictionFailureError({
317338
packageName,
318339
actualVersion,
319340
originalVersion,
@@ -328,7 +349,7 @@ function printPatchApplictionFailureError({
328349
path: string
329350
pathSpecifier: string
330351
}) {
331-
console.error(`
352+
return `
332353
${chalk.red.bold("**ERROR**")} ${chalk.red(
333354
`Failed to apply patch for package ${chalk.bold(packageName)} at path`,
334355
)}
@@ -356,5 +377,22 @@ ${chalk.red.bold("**ERROR**")} ${chalk.red(
356377
Patch file: patches/${patchFileName}
357378
Patch was made for version: ${chalk.green.bold(originalVersion)}
358379
Installed version: ${chalk.red.bold(actualVersion)}
359-
`)
380+
`
381+
}
382+
383+
function createUnexpectedError({
384+
filename,
385+
error,
386+
}: {
387+
filename: string
388+
error: Error
389+
}) {
390+
return `
391+
${chalk.red.bold("**ERROR**")} ${chalk.red(
392+
`Failed to apply patch file ${chalk.bold(filename)}`,
393+
)}
394+
395+
${error.stack}
396+
397+
`
360398
}

src/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ if (argv.version || argv.v) {
7070
} else {
7171
console.log("Applying patches...")
7272
const reverse = !!argv["reverse"]
73-
const ignoreErrors = !!argv["ignore-errors"]
74-
applyPatchesForApp({ appPath, reverse, ignoreErrors, patchDir })
73+
applyPatchesForApp({ appPath, reverse, patchDir })
7574
}
7675
}
7776

@@ -97,10 +96,6 @@ Usage:
9796
9897
Specify the name for the directory in which the patch files are located.
9998
100-
${chalk.bold("--ignore-errors")}
101-
102-
Try to apply all of the patches, even if some of them fail.
103-
10499
${chalk.bold("--reverse")}
105100
106101
Un-applies all patches.

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"target": "es5",
3+
"target": "es2015",
44
"module": "commonjs",
55
"lib": ["es2015", "es2016", "es2017"],
66
"strict": true,

0 commit comments

Comments
 (0)