0
# Patch Application
1
2
Robust patch application system that applies patches during package installation with support for error handling, partial application, reverse operations, and state management. This is the core functionality that makes patch-package integrate seamlessly into development workflows.
3
4
## Capabilities
5
6
### Main Application Functions
7
8
Core functions for applying patches to packages.
9
10
```typescript { .api }
11
/**
12
* Main function to apply all patches for an application
13
* @param options - Application configuration options
14
*/
15
function applyPatchesForApp(options: ApplyPatchesForAppOptions): void;
16
17
interface ApplyPatchesForAppOptions {
18
/** Root path of the application */
19
appPath: string;
20
/** Whether to reverse/un-apply patches */
21
reverse: boolean;
22
/** Directory containing patch files */
23
patchDir: string;
24
/** Exit process on error */
25
shouldExitWithError: boolean;
26
/** Exit process on warning */
27
shouldExitWithWarning: boolean;
28
/** Continue on partial failures */
29
bestEffort: boolean;
30
}
31
32
/**
33
* Apply patches for a specific package
34
* @param options - Package-specific application options
35
*/
36
function applyPatchesForPackage(options: ApplyPatchesForPackageOptions): void;
37
38
interface ApplyPatchesForPackageOptions {
39
/** Array of patch details to apply */
40
patches: PatchedPackageDetails[];
41
/** Application root path */
42
appPath: string;
43
/** Patch directory */
44
patchDir: string;
45
/** Reverse application */
46
reverse: boolean;
47
/** Warning messages array */
48
warnings: string[];
49
/** Error messages array */
50
errors: string[];
51
/** Best effort mode */
52
bestEffort: boolean;
53
}
54
55
/**
56
* Apply a single patch file
57
* @param options - Single patch application options
58
* @returns Success status
59
*/
60
function applyPatch(options: ApplyPatchOptions): boolean;
61
62
interface ApplyPatchOptions {
63
/** Path to patch file */
64
patchFilePath: string;
65
/** Apply in reverse */
66
reverse: boolean;
67
/** Package details */
68
patchDetails: PackageDetails;
69
/** Patch directory */
70
patchDir: string;
71
/** Current working directory */
72
cwd: string;
73
/** Best effort mode */
74
bestEffort: boolean;
75
}
76
```
77
78
**Usage Examples:**
79
80
```typescript
81
import { applyPatchesForApp } from "patch-package/dist/applyPatches";
82
83
// Apply all patches for application
84
applyPatchesForApp({
85
appPath: process.cwd(),
86
reverse: false,
87
patchDir: "patches",
88
shouldExitWithError: true,
89
shouldExitWithWarning: false,
90
bestEffort: false
91
});
92
93
// Apply patches in reverse (un-apply)
94
applyPatchesForApp({
95
appPath: process.cwd(),
96
reverse: true,
97
patchDir: "patches",
98
shouldExitWithError: false,
99
shouldExitWithWarning: false,
100
bestEffort: true
101
});
102
```
103
104
### Error Handling
105
106
Specialized error types and handling for patch application failures.
107
108
```typescript { .api }
109
/**
110
* Custom error for patch application failures
111
*/
112
class PatchApplicationError extends Error {
113
constructor(msg: string);
114
}
115
```
116
117
## Patch Processing
118
119
### Patch File Operations
120
121
Core patch processing operations for reading, parsing, and applying patches.
122
123
```typescript { .api }
124
/**
125
* Read and parse patch file
126
* @param options - Read patch options
127
* @returns Parsed patch file parts
128
*/
129
function readPatch(options: ReadPatchOptions): PatchFilePart[];
130
131
interface ReadPatchOptions {
132
/** Path to patch file */
133
patchFilePath: string;
134
/** Package details */
135
patchDetails: PackageDetails;
136
/** Patch directory */
137
patchDir: string;
138
}
139
140
/**
141
* Execute patch effects (file operations)
142
* @param effects - Parsed patch operations
143
* @param options - Execution options
144
*/
145
function executeEffects(effects: ParsedPatchFile, options: ExecuteEffectsOptions): void;
146
147
interface ExecuteEffectsOptions {
148
/** Dry run mode - don't actually apply changes */
149
dryRun: boolean;
150
/** Current working directory */
151
cwd?: string;
152
/** Error messages array */
153
errors?: string[];
154
/** Best effort mode */
155
bestEffort: boolean;
156
}
157
158
/**
159
* Reverse a patch for un-applying
160
* @param patch - Parsed patch file
161
* @returns Reversed patch
162
*/
163
function reversePatch(patch: ParsedPatchFile): ParsedPatchFile;
164
```
165
166
### Parse Operations
167
168
Detailed patch parsing functionality for understanding patch structure.
169
170
```typescript { .api }
171
/**
172
* Parse complete patch file content
173
* @param file - Patch file content as string
174
* @returns Parsed patch file structure
175
*/
176
function parsePatchFile(file: string): ParsedPatchFile;
177
178
/**
179
* Parse hunk header from diff line
180
* @param headerLine - Hunk header line from patch
181
* @returns Parsed hunk header
182
*/
183
function parseHunkHeaderLine(headerLine: string): HunkHeader;
184
185
/**
186
* Verify hunk integrity
187
* @param hunk - Hunk to verify
188
* @throws Error if hunk is invalid
189
*/
190
function verifyHunkIntegrity(hunk: Hunk): void;
191
192
/**
193
* Interpret parsed patch file data
194
* @param files - File details array
195
* @returns Interpreted patch file
196
*/
197
function interpretParsedPatchFile(files: FileDeets[]): ParsedPatchFile;
198
```
199
200
## Patch File Structure
201
202
### Core Interfaces
203
204
Data structures representing parsed patch files and their components.
205
206
```typescript { .api }
207
interface HunkHeader {
208
original: { start: number; length: number };
209
patched: { start: number; length: number };
210
}
211
212
interface FilePatch {
213
type: "patch";
214
path: string;
215
hunks: Hunk[];
216
beforeHash: string | null;
217
afterHash: string | null;
218
}
219
220
interface Hunk {
221
header: HunkHeader;
222
parts: PatchMutationPart[];
223
source: string;
224
}
225
226
type ParsedPatchFile = PatchFilePart[];
227
type PatchFilePart = FilePatch | FileRename | FileCreation | FileDeletion | FileModeChange;
228
type PatchMutationPart = AdditionPart | DeletionPart | ContextPart;
229
```
230
231
### File Mode Constants
232
233
Standard file mode constants used in patch operations.
234
235
```typescript { .api }
236
/** Default file mode for non-executable files */
237
const NON_EXECUTABLE_FILE_MODE: 0o644;
238
239
/** File mode for executable files */
240
const EXECUTABLE_FILE_MODE: 0o755;
241
```
242
243
## State Management
244
245
### Patch State Tracking
246
247
Comprehensive state management for tracking applied patches and handling sequences.
248
249
```typescript { .api }
250
/**
251
* Get current patch application state
252
* @param packageDetails - Package details
253
* @returns Current state or null if none exists
254
*/
255
function getPatchApplicationState(packageDetails: PackageDetails): PatchApplicationState | null;
256
257
/**
258
* Save patch application state
259
* @param options - State save options
260
*/
261
function savePatchApplicationState(options: SaveStateOptions): void;
262
263
interface SaveStateOptions {
264
packageDetails: PackageDetails;
265
patches: PatchState[];
266
isRebasing: boolean;
267
}
268
269
/**
270
* Clear patch application state
271
* @param packageDetails - Package details
272
*/
273
function clearPatchApplicationState(packageDetails: PackageDetails): void;
274
275
/**
276
* Verify applied patches are still valid
277
* @param options - Verification options
278
*/
279
function verifyAppliedPatches(options: VerifyPatchesOptions): void;
280
281
interface VerifyPatchesOptions {
282
appPath: string;
283
patchDir: string;
284
state: PatchApplicationState;
285
}
286
```
287
288
### State Data Structures
289
290
Data structures for managing patch application state.
291
292
```typescript { .api }
293
interface PatchState {
294
/** Patch file name */
295
patchFilename: string;
296
/** Content hash for validation */
297
patchContentHash: string;
298
/** Whether patch was successfully applied */
299
didApply: boolean;
300
}
301
302
interface PatchApplicationState {
303
/** State version for compatibility */
304
version: number;
305
/** Array of patch states */
306
patches: PatchState[];
307
/** Whether currently rebasing */
308
isRebasing: boolean;
309
}
310
311
/** State file name */
312
const STATE_FILE_NAME: ".patch-package.json";
313
```
314
315
## File System Integration
316
317
### Patch File Discovery
318
319
Functions for discovering and organizing patch files.
320
321
```typescript { .api }
322
/**
323
* Get all patch files in directory
324
* @param patchesDir - Directory containing patches
325
* @returns Array of patch file paths
326
*/
327
function getPatchFiles(patchesDir: string): string[];
328
329
/**
330
* Get patches grouped by package
331
* @param patchesDirectory - Patches directory
332
* @returns Grouped patches with metadata
333
*/
334
function getGroupedPatches(patchesDirectory: string): GroupedPatches;
335
336
interface GroupedPatches {
337
/** Total number of patch files */
338
numPatchFiles: number;
339
/** Patches organized by package path specifier */
340
pathSpecifierToPatchFiles: Record<string, PatchedPackageDetails[]>;
341
/** Warning messages */
342
warnings: string[];
343
}
344
```
345
346
## Advanced Application Features
347
348
### Rebase Operations
349
350
Advanced functionality for rebasing patch sequences.
351
352
```typescript { .api }
353
/**
354
* Rebase patches to specific target
355
* @param options - Rebase configuration options
356
*/
357
function rebase(options: RebaseOptions): void;
358
359
interface RebaseOptions {
360
/** Application path */
361
appPath: string;
362
/** Patch directory */
363
patchDir: string;
364
/** Package specifier */
365
packagePathSpecifier: string;
366
/** Target patch identifier */
367
targetPatch: string;
368
}
369
```
370
371
### Safe Process Execution
372
373
Secure process spawning for patch application operations.
374
375
```typescript { .api }
376
/**
377
* Safely execute shell commands
378
* @param command - Command to execute
379
* @param args - Command arguments
380
* @param options - Spawn options
381
* @returns Spawn result
382
*/
383
function spawnSafeSync(
384
command: string,
385
args?: string[],
386
options?: SpawnSafeOptions
387
): SpawnResult;
388
389
interface SpawnSafeOptions extends SpawnOptions {
390
// Additional safety options
391
}
392
393
interface SpawnResult {
394
status: number | null;
395
signal: string | null;
396
stdout: Buffer;
397
stderr: Buffer;
398
}
399
```
400
401
## Application Workflow
402
403
The patch application workflow typically involves:
404
405
1. **Discovery**: Find all relevant patch files in the patch directory
406
2. **Grouping**: Organize patches by package and sequence
407
3. **State Validation**: Check current application state against patches
408
4. **Dependency Resolution**: Verify target packages exist and match versions
409
5. **Sequential Application**: Apply patches in correct order
410
6. **State Tracking**: Update application state for each successful patch
411
7. **Error Handling**: Handle failures according to configuration
412
413
**Complete Example:**
414
415
```typescript
416
import { applyPatchesForApp } from "patch-package/dist/applyPatches";
417
import { getPatchApplicationState } from "patch-package/dist/stateFile";
418
import { getGroupedPatches } from "patch-package/dist/patchFs";
419
420
// Check current state
421
const currentState = getPatchApplicationState({
422
path: "/path/to/package",
423
name: "my-package",
424
// ... other package details
425
});
426
427
// Discover available patches
428
const groupedPatches = getGroupedPatches("patches");
429
console.log(`Found ${groupedPatches.numPatchFiles} patch files`);
430
431
// Apply patches with comprehensive error handling
432
applyPatchesForApp({
433
appPath: process.cwd(),
434
reverse: false,
435
patchDir: "patches",
436
shouldExitWithError: false,
437
shouldExitWithWarning: false,
438
bestEffort: true // Continue on individual failures
439
});
440
```