0
# File Management
1
2
Abstract file system for managing configuration files, source code, and generated content. Projen provides a comprehensive file management system that handles different file types with synthesis markers and read-only protection.
3
4
## Capabilities
5
6
### FileBase Class
7
8
Abstract base class for all file types in projen, providing common file operations and synthesis lifecycle.
9
10
```typescript { .api }
11
/**
12
* Base class for all file types in projen
13
* Provides common file operations and synthesis lifecycle
14
*/
15
abstract class FileBase extends Component {
16
constructor(scope: IConstruct, filePath: string, options?: FileBaseOptions);
17
18
/** Relative file path from project root */
19
readonly path: string;
20
/** Absolute file path on disk */
21
readonly absolutePath: string;
22
/** Whether the file is read-only (has projen marker) */
23
readonly readonly: boolean;
24
/** Whether the file has executable permissions */
25
readonly executable: boolean;
26
/** Projen marker text (null if not a generated file) */
27
readonly marker?: string;
28
29
/** Called during synthesis to write file content */
30
protected abstract synthesizeContent(resolver: IResolver): string | undefined;
31
}
32
33
interface FileBaseOptions {
34
/** Whether the file is read-only (default: true for generated files) */
35
readonly?: boolean;
36
/** Whether the file should be executable */
37
executable?: boolean;
38
/** Custom marker text for generated files */
39
marker?: string;
40
/** Whether to commit this file to git */
41
committed?: boolean;
42
}
43
```
44
45
### JsonFile Class
46
47
JSON file management with object manipulation and projen marker support.
48
49
```typescript { .api }
50
/**
51
* Represents a JSON file with projen marker support
52
* Provides object-based manipulation of JSON content
53
*/
54
class JsonFile extends ObjectFile {
55
constructor(scope: IConstruct, filePath: string, options?: JsonFileOptions);
56
57
/** The JSON object content */
58
readonly obj: any;
59
60
/** Add or update a property in the JSON object */
61
addOverride(path: string, value: any): void;
62
/** Add to an array property */
63
addToArray(path: string, ...values: any[]): void;
64
/** Remove a property from the JSON object */
65
removeProperty(path: string): void;
66
/** Get a property value */
67
getProperty(path: string): any;
68
}
69
70
interface JsonFileOptions extends ObjectFileOptions {
71
/** JSON object content */
72
obj?: any;
73
/** Custom JSON formatting options */
74
formatting?: JsonFormattingOptions;
75
}
76
77
interface JsonFormattingOptions {
78
/** Number of spaces for indentation (default: 2) */
79
indent?: number;
80
/** Whether to add trailing newline */
81
newline?: boolean;
82
}
83
```
84
85
**JSON File Example:**
86
87
```typescript
88
import { Project, JsonFile } from "projen";
89
90
const project = new Project({ name: "json-example" });
91
92
// Create package.json
93
const packageJson = new JsonFile(project, "package.json", {
94
obj: {
95
name: "my-package",
96
version: "1.0.0",
97
main: "index.js",
98
scripts: {},
99
dependencies: {},
100
},
101
});
102
103
// Modify JSON content
104
packageJson.addOverride("scripts.build", "tsc");
105
packageJson.addOverride("scripts.test", "jest");
106
packageJson.addToArray("keywords", "typescript", "projen");
107
108
// Add nested properties
109
packageJson.addOverride("author.name", "Jane Developer");
110
packageJson.addOverride("author.email", "jane@example.com");
111
112
// Remove properties
113
packageJson.removeProperty("main");
114
```
115
116
### YamlFile Class
117
118
YAML file management with object manipulation.
119
120
```typescript { .api }
121
/**
122
* Represents a YAML file with projen marker support
123
* Provides object-based manipulation of YAML content
124
*/
125
class YamlFile extends ObjectFile {
126
constructor(scope: IConstruct, filePath: string, options?: YamlFileOptions);
127
128
/** The YAML object content */
129
readonly obj: any;
130
131
/** Add or update a property in the YAML object */
132
addOverride(path: string, value: any): void;
133
/** Add to an array property */
134
addToArray(path: string, ...values: any[]): void;
135
}
136
137
interface YamlFileOptions extends ObjectFileOptions {
138
/** YAML object content */
139
obj?: any;
140
/** Line width for YAML formatting */
141
lineWidth?: number;
142
/** Whether to use flow style for sequences */
143
flowSequences?: boolean;
144
}
145
```
146
147
**YAML File Example:**
148
149
```typescript
150
import { Project, YamlFile } from "projen";
151
152
const project = new Project({ name: "yaml-example" });
153
154
// Create GitHub workflow
155
const workflow = new YamlFile(project, ".github/workflows/ci.yml", {
156
obj: {
157
name: "CI",
158
on: {
159
push: { branches: ["main"] },
160
pull_request: { branches: ["main"] },
161
},
162
jobs: {
163
test: {
164
"runs-on": "ubuntu-latest",
165
steps: [],
166
},
167
},
168
},
169
});
170
171
// Add steps to workflow
172
workflow.addToArray("jobs.test.steps", {
173
uses: "actions/checkout@v3",
174
});
175
176
workflow.addToArray("jobs.test.steps", {
177
uses: "actions/setup-node@v3",
178
with: {
179
"node-version": "18",
180
},
181
});
182
```
183
184
### TextFile Class
185
186
Plain text file management with line-based manipulation.
187
188
```typescript { .api }
189
/**
190
* Plain text file with line-based manipulation
191
* Suitable for configuration files, source code, and documentation
192
*/
193
class TextFile extends FileBase {
194
constructor(scope: IConstruct, filePath: string, options?: TextFileOptions);
195
196
/** All lines in the file */
197
readonly lines: string[];
198
199
/** Add a line to the file */
200
addLine(line: string): void;
201
/** Add multiple lines to the file */
202
addLines(...lines: string[]): void;
203
/** Insert a line at specific position */
204
insertLine(index: number, line: string): void;
205
/** Remove a line by content */
206
removeLine(line: string): void;
207
/** Remove a line by index */
208
removeLineAt(index: number): void;
209
/** Check if file contains a line */
210
hasLine(line: string): boolean;
211
}
212
213
interface TextFileOptions extends FileBaseOptions {
214
/** Initial lines for the file */
215
lines?: string[];
216
/** Line ending style */
217
lineEnding?: LineEnding;
218
}
219
220
enum LineEnding {
221
/** Unix line endings (\n) */
222
LF = "lf",
223
/** Windows line endings (\r\n) */
224
CRLF = "crlf",
225
/** Automatic based on platform */
226
AUTO = "auto"
227
}
228
```
229
230
**Text File Example:**
231
232
```typescript
233
import { Project, TextFile } from "projen";
234
235
const project = new Project({ name: "text-example" });
236
237
// Create .gitignore file
238
const gitignore = new TextFile(project, ".gitignore", {
239
lines: [
240
"node_modules/",
241
"*.log",
242
".env",
243
],
244
});
245
246
// Add more patterns
247
gitignore.addLine("dist/");
248
gitignore.addLine("coverage/");
249
gitignore.addLines(
250
"# IDE files",
251
".vscode/",
252
".idea/",
253
);
254
255
// Create README
256
const readme = new TextFile(project, "README.md", {
257
lines: [
258
"# My Project",
259
"",
260
"Description of my project.",
261
],
262
});
263
264
readme.addLines(
265
"",
266
"## Installation",
267
"",
268
"```bash",
269
"npm install",
270
"```",
271
);
272
```
273
274
### SampleFile Class
275
276
Sample code files that are only created if they don't exist.
277
278
```typescript { .api }
279
/**
280
* Sample code files that are only created if they don't already exist
281
* Used for generating example code and configuration templates
282
*/
283
class SampleFile extends FileBase {
284
constructor(scope: IConstruct, filePath: string, options?: SampleFileOptions);
285
286
/** File content */
287
readonly content: string;
288
}
289
290
interface SampleFileOptions extends FileBaseOptions {
291
/** File content */
292
content: string;
293
/** Source file to copy from */
294
sourcePath?: string;
295
}
296
```
297
298
**Sample File Example:**
299
300
```typescript
301
import { TypeScriptProject, SampleFile } from "projen";
302
303
const project = new TypeScriptProject({
304
name: "sample-example",
305
sampleCode: false, // Disable automatic samples
306
});
307
308
// Create custom sample files
309
new SampleFile(project, "src/hello.ts", {
310
content: `export function hello(name: string): string {
311
return \`Hello, \${name}!\`;
312
}
313
`,
314
});
315
316
new SampleFile(project, "test/hello.test.ts", {
317
content: `import { hello } from '../src/hello';
318
319
describe('hello', () => {
320
test('should greet correctly', () => {
321
expect(hello('World')).toBe('Hello, World!');
322
});
323
});
324
`,
325
});
326
327
// Sample configuration file
328
new SampleFile(project, ".env.example", {
329
content: `# Environment variables
330
API_KEY=your_api_key_here
331
DATABASE_URL=postgresql://localhost:5432/mydb
332
`,
333
});
334
```
335
336
### IgnoreFile Class
337
338
Manages ignore pattern files like .gitignore, .npmignore.
339
340
```typescript { .api }
341
/**
342
* Manages ignore pattern files (.gitignore, .npmignore, etc.)
343
* Provides pattern-based file exclusion functionality
344
*/
345
class IgnoreFile extends TextFile {
346
constructor(scope: IConstruct, filePath: string, options?: IgnoreFileOptions);
347
348
/** Add ignore pattern */
349
addPattern(pattern: string): void;
350
/** Add multiple ignore patterns */
351
addPatterns(...patterns: string[]): void;
352
/** Remove ignore pattern */
353
removePattern(pattern: string): void;
354
/** Check if pattern exists */
355
hasPattern(pattern: string): boolean;
356
/** Add comment */
357
addComment(comment: string): void;
358
}
359
360
interface IgnoreFileOptions extends TextFileOptions {
361
/** Initial ignore patterns */
362
ignorePatterns?: string[];
363
}
364
```
365
366
**Ignore File Example:**
367
368
```typescript
369
import { Project, IgnoreFile } from "projen";
370
371
const project = new Project({ name: "ignore-example" });
372
373
// Create custom .gitignore
374
const gitignore = new IgnoreFile(project, ".gitignore", {
375
ignorePatterns: [
376
"node_modules/",
377
"*.log",
378
],
379
});
380
381
gitignore.addComment("Build artifacts");
382
gitignore.addPatterns(
383
"dist/",
384
"build/",
385
"lib/",
386
);
387
388
gitignore.addComment("Environment files");
389
gitignore.addPattern(".env*");
390
391
// Create .dockerignore
392
const dockerignore = new IgnoreFile(project, ".dockerignore", {
393
ignorePatterns: [
394
"node_modules/",
395
".git/",
396
"README.md",
397
"Dockerfile",
398
".dockerignore",
399
],
400
});
401
```
402
403
### ObjectFile Class
404
405
Base class for files that represent structured objects (JSON, YAML, etc.).
406
407
```typescript { .api }
408
/**
409
* Base class for files that represent structured objects
410
* Provides common functionality for JSON, YAML, and other object files
411
*/
412
abstract class ObjectFile extends FileBase {
413
constructor(scope: IConstruct, filePath: string, options?: ObjectFileOptions);
414
415
/** The object content */
416
readonly obj: any;
417
418
/** Add or update a property using dot notation */
419
addOverride(path: string, value: any): void;
420
/** Remove a property using dot notation */
421
removeProperty(path: string): void;
422
/** Get a property value using dot notation */
423
getProperty(path: string): any;
424
/** Check if property exists */
425
hasProperty(path: string): boolean;
426
/** Add to array property */
427
addToArray(path: string, ...values: any[]): void;
428
/** Merge object into property */
429
mergeObject(path: string, obj: any): void;
430
}
431
432
interface ObjectFileOptions extends FileBaseOptions {
433
/** Initial object content */
434
obj?: any;
435
/** Whether to omit empty values */
436
omitEmpty?: boolean;
437
}
438
```
439
440
## Types
441
442
### File-Related Types
443
444
```typescript { .api }
445
interface IResolver {
446
/** Resolve tokens in content */
447
resolve(obj: any): any;
448
}
449
450
interface FileSystemOptions {
451
/** Base directory for file operations */
452
baseDir?: string;
453
/** Default file permissions */
454
defaultPermissions?: string;
455
/** Whether to create directories automatically */
456
autoCreateDirs?: boolean;
457
}
458
459
enum FileType {
460
TEXT = "text",
461
JSON = "json",
462
YAML = "yaml",
463
BINARY = "binary"
464
}
465
```