@webpieces/dev-config 0.2.61 → 0.2.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/architecture/executors/validate-modified-files/executor.d.ts +22 -0
- package/architecture/executors/validate-modified-files/executor.js +446 -0
- package/architecture/executors/validate-modified-files/executor.js.map +1 -0
- package/architecture/executors/validate-modified-files/executor.ts +510 -0
- package/architecture/executors/validate-modified-files/schema.json +14 -0
- package/architecture/executors/validate-modified-methods/executor.d.ts +3 -1
- package/architecture/executors/validate-modified-methods/executor.js +191 -46
- package/architecture/executors/validate-modified-methods/executor.js.map +1 -1
- package/architecture/executors/validate-modified-methods/executor.ts +230 -58
- package/executors.json +5 -0
- package/package.json +1 -1
- package/plugin.js +22 -0
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
* Usage:
|
|
15
15
|
* nx affected --target=validate-modified-methods --base=origin/main
|
|
16
16
|
*
|
|
17
|
-
* Escape hatch: Add webpieces-disable max-lines-new-and-modified comment with justification
|
|
17
|
+
* Escape hatch: Add webpieces-disable max-lines-new-and-modified comment with date and justification
|
|
18
|
+
* Format: // webpieces-disable max-lines-new-and-modified 2025/01/15 -- [reason]
|
|
19
|
+
* The disable expires after 1 month from the date specified.
|
|
18
20
|
*/
|
|
19
21
|
|
|
20
22
|
import type { ExecutorContext } from '@nx/devkit';
|
|
@@ -36,6 +38,8 @@ interface MethodViolation {
|
|
|
36
38
|
methodName: string;
|
|
37
39
|
line: number;
|
|
38
40
|
lines: number;
|
|
41
|
+
expiredDisable?: boolean;
|
|
42
|
+
expiredDate?: string;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
const TMP_DIR = 'tmp/webpieces';
|
|
@@ -140,15 +144,19 @@ const result = this.buildResultObject(data);
|
|
|
140
144
|
|
|
141
145
|
Sometimes methods genuinely need to be longer (complex algorithms, state machines, etc.).
|
|
142
146
|
|
|
143
|
-
**Escape hatch**: Add a webpieces-disable comment with justification:
|
|
147
|
+
**Escape hatch**: Add a webpieces-disable comment with DATE and justification:
|
|
144
148
|
|
|
145
149
|
\`\`\`typescript
|
|
146
|
-
// webpieces-disable max-lines-new-and-modified -- Complex state machine, splitting reduces clarity
|
|
150
|
+
// webpieces-disable max-lines-new-and-modified 2025/01/15 -- Complex state machine, splitting reduces clarity
|
|
147
151
|
async complexStateMachine(): Promise<void> {
|
|
148
152
|
// ... longer method with justification
|
|
149
153
|
}
|
|
150
154
|
\`\`\`
|
|
151
155
|
|
|
156
|
+
**IMPORTANT**: The date format is yyyy/mm/dd. The disable will EXPIRE after 1 month from this date.
|
|
157
|
+
After expiration, you must either fix the method or update the date to get another month.
|
|
158
|
+
This ensures that disable comments are reviewed periodically.
|
|
159
|
+
|
|
152
160
|
## AI Agent Action Steps
|
|
153
161
|
|
|
154
162
|
1. **READ** the method to understand its logical sections
|
|
@@ -289,14 +297,64 @@ function getChangedLineNumbers(diffContent: string): Set<number> {
|
|
|
289
297
|
return changedLines;
|
|
290
298
|
}
|
|
291
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Parse a date string in yyyy/mm/dd format and return a Date object.
|
|
302
|
+
* Returns null if the format is invalid.
|
|
303
|
+
*/
|
|
304
|
+
function parseDisableDate(dateStr: string): Date | null {
|
|
305
|
+
// Match yyyy/mm/dd format
|
|
306
|
+
const match = dateStr.match(/^(\d{4})\/(\d{2})\/(\d{2})$/);
|
|
307
|
+
if (!match) return null;
|
|
308
|
+
|
|
309
|
+
const year = parseInt(match[1], 10);
|
|
310
|
+
const month = parseInt(match[2], 10) - 1; // JS months are 0-indexed
|
|
311
|
+
const day = parseInt(match[3], 10);
|
|
312
|
+
|
|
313
|
+
const date = new Date(year, month, day);
|
|
314
|
+
|
|
315
|
+
// Validate the date is valid (e.g., not Feb 30)
|
|
316
|
+
if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return date;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Check if a date is within the last month (not expired).
|
|
325
|
+
*/
|
|
326
|
+
function isDateWithinMonth(date: Date): boolean {
|
|
327
|
+
const now = new Date();
|
|
328
|
+
const oneMonthAgo = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate());
|
|
329
|
+
return date >= oneMonthAgo;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Get today's date in yyyy/mm/dd format for error messages
|
|
334
|
+
*/
|
|
335
|
+
function getTodayDateString(): string {
|
|
336
|
+
const now = new Date();
|
|
337
|
+
const year = now.getFullYear();
|
|
338
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
339
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
340
|
+
return `${year}/${month}/${day}`;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
interface DisableInfo {
|
|
344
|
+
type: 'full' | 'new-only' | 'none';
|
|
345
|
+
isExpired: boolean;
|
|
346
|
+
date?: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
292
349
|
/**
|
|
293
350
|
* Check what kind of webpieces-disable comment is present for a method.
|
|
294
|
-
* Returns:
|
|
351
|
+
* Returns: DisableInfo with type, expiration status, and date
|
|
295
352
|
* - 'full': max-lines-new-and-modified (ultimate escape, skips both validators)
|
|
296
353
|
* - 'new-only': max-lines-new-methods (escaped 30-line check, still needs 80-line check)
|
|
297
354
|
* - 'none': no escape hatch
|
|
298
355
|
*/
|
|
299
|
-
|
|
356
|
+
// webpieces-disable max-lines-new-methods -- Complex validation logic with multiple escape hatch types
|
|
357
|
+
function getDisableInfo(lines: string[], lineNumber: number): DisableInfo {
|
|
300
358
|
const startCheck = Math.max(0, lineNumber - 5);
|
|
301
359
|
for (let i = lineNumber - 2; i >= startCheck; i--) {
|
|
302
360
|
const line = lines[i]?.trim() ?? '';
|
|
@@ -305,24 +363,83 @@ function getDisableType(lines: string[], lineNumber: number): 'full' | 'new-only
|
|
|
305
363
|
}
|
|
306
364
|
if (line.includes('webpieces-disable')) {
|
|
307
365
|
if (line.includes('max-lines-new-and-modified')) {
|
|
308
|
-
|
|
366
|
+
// Check for date in format: max-lines-new-and-modified yyyy/mm/dd
|
|
367
|
+
const dateMatch = line.match(/max-lines-new-and-modified\s+(\d{4}\/\d{2}\/\d{2}|XXXX\/XX\/XX)/);
|
|
368
|
+
|
|
369
|
+
if (!dateMatch) {
|
|
370
|
+
// No date found - treat as expired (invalid)
|
|
371
|
+
return { type: 'full', isExpired: true, date: undefined };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const dateStr = dateMatch[1];
|
|
375
|
+
|
|
376
|
+
// Secret permanent disable
|
|
377
|
+
if (dateStr === 'XXXX/XX/XX') {
|
|
378
|
+
return { type: 'full', isExpired: false, date: dateStr };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const date = parseDisableDate(dateStr);
|
|
382
|
+
if (!date) {
|
|
383
|
+
// Invalid date format - treat as expired
|
|
384
|
+
return { type: 'full', isExpired: true, date: dateStr };
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (!isDateWithinMonth(date)) {
|
|
388
|
+
// Date is expired (older than 1 month)
|
|
389
|
+
return { type: 'full', isExpired: true, date: dateStr };
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Valid and not expired
|
|
393
|
+
return { type: 'full', isExpired: false, date: dateStr };
|
|
309
394
|
}
|
|
310
395
|
if (line.includes('max-lines-new-methods')) {
|
|
311
|
-
|
|
396
|
+
// Check for date in format: max-lines-new-methods yyyy/mm/dd
|
|
397
|
+
const dateMatch = line.match(/max-lines-new-methods\s+(\d{4}\/\d{2}\/\d{2}|XXXX\/XX\/XX)/);
|
|
398
|
+
|
|
399
|
+
if (!dateMatch) {
|
|
400
|
+
// No date found - treat as expired (invalid)
|
|
401
|
+
return { type: 'new-only', isExpired: true, date: undefined };
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const dateStr = dateMatch[1];
|
|
405
|
+
|
|
406
|
+
// Secret permanent disable
|
|
407
|
+
if (dateStr === 'XXXX/XX/XX') {
|
|
408
|
+
return { type: 'new-only', isExpired: false, date: dateStr };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const date = parseDisableDate(dateStr);
|
|
412
|
+
if (!date) {
|
|
413
|
+
// Invalid date format - treat as expired
|
|
414
|
+
return { type: 'new-only', isExpired: true, date: dateStr };
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (!isDateWithinMonth(date)) {
|
|
418
|
+
// Date is expired (older than 1 month)
|
|
419
|
+
return { type: 'new-only', isExpired: true, date: dateStr };
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Valid and not expired
|
|
423
|
+
return { type: 'new-only', isExpired: false, date: dateStr };
|
|
312
424
|
}
|
|
313
425
|
}
|
|
314
426
|
}
|
|
315
|
-
return 'none';
|
|
427
|
+
return { type: 'none', isExpired: false };
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
interface MethodInfo {
|
|
431
|
+
name: string;
|
|
432
|
+
line: number;
|
|
433
|
+
endLine: number;
|
|
434
|
+
lines: number;
|
|
435
|
+
disableInfo: DisableInfo;
|
|
316
436
|
}
|
|
317
437
|
|
|
318
438
|
/**
|
|
319
439
|
* Parse a TypeScript file and find methods with their line counts
|
|
320
440
|
*/
|
|
321
441
|
// webpieces-disable max-lines-new-methods -- AST traversal requires inline visitor function
|
|
322
|
-
function findMethodsInFile(
|
|
323
|
-
filePath: string,
|
|
324
|
-
workspaceRoot: string
|
|
325
|
-
): Array<{ name: string; line: number; endLine: number; lines: number; disableType: 'full' | 'new-only' | 'none' }> {
|
|
442
|
+
function findMethodsInFile(filePath: string, workspaceRoot: string): MethodInfo[] {
|
|
326
443
|
const fullPath = path.join(workspaceRoot, filePath);
|
|
327
444
|
if (!fs.existsSync(fullPath)) return [];
|
|
328
445
|
|
|
@@ -330,8 +447,7 @@ function findMethodsInFile(
|
|
|
330
447
|
const fileLines = content.split('\n');
|
|
331
448
|
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
332
449
|
|
|
333
|
-
const methods:
|
|
334
|
-
[];
|
|
450
|
+
const methods: MethodInfo[] = [];
|
|
335
451
|
|
|
336
452
|
// webpieces-disable max-lines-new-methods -- AST visitor pattern requires handling multiple node types
|
|
337
453
|
function visit(node: ts.Node): void {
|
|
@@ -367,7 +483,7 @@ function findMethodsInFile(
|
|
|
367
483
|
line: startLine,
|
|
368
484
|
endLine: endLine,
|
|
369
485
|
lines: endLine - startLine + 1,
|
|
370
|
-
|
|
486
|
+
disableInfo: getDisableInfo(fileLines, startLine),
|
|
371
487
|
});
|
|
372
488
|
}
|
|
373
489
|
|
|
@@ -387,9 +503,9 @@ function findMethodsInFile(
|
|
|
387
503
|
*
|
|
388
504
|
* Skips:
|
|
389
505
|
* - NEW methods without any escape (let validate-new-methods handle them first)
|
|
390
|
-
* - Methods with `max-lines-new-and-modified` escape (ultimate escape hatch)
|
|
506
|
+
* - Methods with valid, non-expired `max-lines-new-and-modified` escape (ultimate escape hatch)
|
|
391
507
|
*/
|
|
392
|
-
// webpieces-disable max-lines-new-
|
|
508
|
+
// webpieces-disable max-lines-new-and-modified 2025/12/20 -- Core validation logic with multiple file operations
|
|
393
509
|
function findViolations(
|
|
394
510
|
workspaceRoot: string,
|
|
395
511
|
changedFiles: string[],
|
|
@@ -414,26 +530,52 @@ function findViolations(
|
|
|
414
530
|
|
|
415
531
|
for (const method of methods) {
|
|
416
532
|
const isNewMethod = newMethodNames.has(method.name);
|
|
533
|
+
const { type: disableType, isExpired, date: disableDate } = method.disableInfo;
|
|
417
534
|
|
|
418
|
-
// Skip methods with full escape (max-lines-new-and-modified)
|
|
419
|
-
if (
|
|
535
|
+
// Skip methods with valid, non-expired full escape (max-lines-new-and-modified)
|
|
536
|
+
if (disableType === 'full' && !isExpired) continue;
|
|
420
537
|
|
|
421
538
|
// Skip methods under the limit
|
|
422
539
|
if (method.lines <= maxLines) continue;
|
|
423
540
|
|
|
424
541
|
if (isNewMethod) {
|
|
425
542
|
// For NEW methods:
|
|
426
|
-
// - If has 'new-only' escape → check (they escaped 30-line, now need 80-line check)
|
|
543
|
+
// - If has 'new-only' escape (non-expired) → check (they escaped 30-line, now need 80-line check)
|
|
427
544
|
// - If has 'none' → skip (let validate-new-methods handle first)
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
545
|
+
// - If has expired disable → report as violation
|
|
546
|
+
if (disableType === 'full' && isExpired) {
|
|
547
|
+
// Expired full disable - report with expired info
|
|
548
|
+
violations.push({
|
|
549
|
+
file,
|
|
550
|
+
methodName: method.name,
|
|
551
|
+
line: method.line,
|
|
552
|
+
lines: method.lines,
|
|
553
|
+
expiredDisable: true,
|
|
554
|
+
expiredDate: disableDate,
|
|
555
|
+
});
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
if (disableType !== 'new-only') continue;
|
|
559
|
+
|
|
560
|
+
if (isExpired) {
|
|
561
|
+
// Expired new-only disable - report with expired info
|
|
562
|
+
violations.push({
|
|
563
|
+
file,
|
|
564
|
+
methodName: method.name,
|
|
565
|
+
line: method.line,
|
|
566
|
+
lines: method.lines,
|
|
567
|
+
expiredDisable: true,
|
|
568
|
+
expiredDate: disableDate,
|
|
569
|
+
});
|
|
570
|
+
} else {
|
|
571
|
+
// New method with valid max-lines-new-methods escape - check against 80-line limit
|
|
572
|
+
violations.push({
|
|
573
|
+
file,
|
|
574
|
+
methodName: method.name,
|
|
575
|
+
line: method.line,
|
|
576
|
+
lines: method.lines,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
437
579
|
} else {
|
|
438
580
|
// For MODIFIED methods: check if any changed line falls within method's range
|
|
439
581
|
let hasChanges = false;
|
|
@@ -445,12 +587,24 @@ function findViolations(
|
|
|
445
587
|
}
|
|
446
588
|
|
|
447
589
|
if (hasChanges) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
590
|
+
if (disableType === 'full' && isExpired) {
|
|
591
|
+
// Expired full disable - report with expired info
|
|
592
|
+
violations.push({
|
|
593
|
+
file,
|
|
594
|
+
methodName: method.name,
|
|
595
|
+
line: method.line,
|
|
596
|
+
lines: method.lines,
|
|
597
|
+
expiredDisable: true,
|
|
598
|
+
expiredDate: disableDate,
|
|
599
|
+
});
|
|
600
|
+
} else {
|
|
601
|
+
violations.push({
|
|
602
|
+
file,
|
|
603
|
+
methodName: method.name,
|
|
604
|
+
line: method.line,
|
|
605
|
+
lines: method.lines,
|
|
606
|
+
});
|
|
607
|
+
}
|
|
454
608
|
}
|
|
455
609
|
}
|
|
456
610
|
}
|
|
@@ -491,6 +645,46 @@ function detectBase(workspaceRoot: string): string | null {
|
|
|
491
645
|
return null;
|
|
492
646
|
}
|
|
493
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Report violations to console
|
|
650
|
+
*/
|
|
651
|
+
// webpieces-disable max-lines-new-methods -- Error output formatting with multiple message sections
|
|
652
|
+
function reportViolations(violations: MethodViolation[], maxLines: number): void {
|
|
653
|
+
console.error('');
|
|
654
|
+
console.error('❌ Modified methods exceed ' + maxLines + ' lines!');
|
|
655
|
+
console.error('');
|
|
656
|
+
console.error('📚 When you modify a method, you must bring it under ' + maxLines + ' lines.');
|
|
657
|
+
console.error(' This rule encourages GRADUAL cleanup so even though you did not cause it,');
|
|
658
|
+
console.error(' you touched it, so you should fix now as part of your PR');
|
|
659
|
+
console.error(' (this is for vibe coding and AI to fix as it touches things).');
|
|
660
|
+
console.error(' You can refactor to stay under the limit 50% of the time. If not feasible, use the escape hatch.');
|
|
661
|
+
console.error('');
|
|
662
|
+
console.error(
|
|
663
|
+
'⚠️ *** READ tmp/webpieces/webpieces.methodsize.md for detailed guidance on how to fix this easily *** ⚠️'
|
|
664
|
+
);
|
|
665
|
+
console.error('');
|
|
666
|
+
|
|
667
|
+
for (const v of violations) {
|
|
668
|
+
if (v.expiredDisable) {
|
|
669
|
+
console.error(` ❌ ${v.file}:${v.line}`);
|
|
670
|
+
console.error(` Method: ${v.methodName} (${v.lines} lines, max: ${maxLines})`);
|
|
671
|
+
console.error(` ⏰ EXPIRED DISABLE: Your disable comment dated ${v.expiredDate ?? 'unknown'} has expired (>1 month old).`);
|
|
672
|
+
console.error(` You must either FIX the method or UPDATE the date to get another month.`);
|
|
673
|
+
} else {
|
|
674
|
+
console.error(` ❌ ${v.file}:${v.line}`);
|
|
675
|
+
console.error(` Method: ${v.methodName} (${v.lines} lines, max: ${maxLines})`);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
console.error('');
|
|
679
|
+
|
|
680
|
+
console.error(' You can disable this error, but you will be forced to fix again in 1 month');
|
|
681
|
+
console.error(' since 99% of methods can be less than ' + maxLines + ' lines of code.');
|
|
682
|
+
console.error('');
|
|
683
|
+
console.error(' Use escape with DATE (expires in 1 month):');
|
|
684
|
+
console.error(` // webpieces-disable max-lines-new-and-modified ${getTodayDateString()} -- [your reason]`);
|
|
685
|
+
console.error('');
|
|
686
|
+
}
|
|
687
|
+
|
|
494
688
|
export default async function runExecutor(
|
|
495
689
|
options: ValidateModifiedMethodsOptions,
|
|
496
690
|
context: ExecutorContext
|
|
@@ -537,30 +731,8 @@ export default async function runExecutor(
|
|
|
537
731
|
return { success: true };
|
|
538
732
|
}
|
|
539
733
|
|
|
540
|
-
// Write instructions file
|
|
541
734
|
writeTmpInstructions(workspaceRoot);
|
|
542
|
-
|
|
543
|
-
// Report violations
|
|
544
|
-
console.error('');
|
|
545
|
-
console.error('❌ Modified methods exceed ' + maxLines + ' lines!');
|
|
546
|
-
console.error('');
|
|
547
|
-
console.error('📚 When you modify a method, you must bring it under ' + maxLines + ' lines.');
|
|
548
|
-
console.error(' This rule encourages GRADUAL cleanup so even though you did not cause it,');
|
|
549
|
-
console.error(' you touched it, so you should fix now as part of your PR');
|
|
550
|
-
console.error(' (this is for vibe coding and AI to fix as it touches things).');
|
|
551
|
-
console.error(' You can refactor to stay under the limit 50% of the time. If not feasible, use the escape hatch.');
|
|
552
|
-
console.error('');
|
|
553
|
-
console.error(
|
|
554
|
-
'⚠️ *** READ tmp/webpieces/webpieces.methodsize.md for detailed guidance on how to fix this easily *** ⚠️'
|
|
555
|
-
);
|
|
556
|
-
console.error('');
|
|
557
|
-
|
|
558
|
-
for (const v of violations) {
|
|
559
|
-
console.error(` ❌ ${v.file}:${v.line}`);
|
|
560
|
-
console.error(` Method: ${v.methodName} (${v.lines} lines, max: ${maxLines})`);
|
|
561
|
-
}
|
|
562
|
-
console.error('');
|
|
563
|
-
|
|
735
|
+
reportViolations(violations, maxLines);
|
|
564
736
|
return { success: false };
|
|
565
737
|
} catch (err: unknown) {
|
|
566
738
|
const error = err instanceof Error ? err : new Error(String(err));
|
package/executors.json
CHANGED
|
@@ -54,6 +54,11 @@
|
|
|
54
54
|
"implementation": "./executors/validate-versions-locked/executor",
|
|
55
55
|
"schema": "./executors/validate-versions-locked/schema.json",
|
|
56
56
|
"description": "Validate package.json versions are locked (no semver ranges) and npm ci compatible"
|
|
57
|
+
},
|
|
58
|
+
"validate-modified-files": {
|
|
59
|
+
"implementation": "./architecture/executors/validate-modified-files/executor",
|
|
60
|
+
"schema": "./architecture/executors/validate-modified-files/schema.json",
|
|
61
|
+
"description": "Validate modified files don't exceed max line count"
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
64
|
}
|
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -37,9 +37,11 @@ const DEFAULT_OPTIONS = {
|
|
|
37
37
|
validatePackageJson: true,
|
|
38
38
|
validateNewMethods: true,
|
|
39
39
|
validateModifiedMethods: true,
|
|
40
|
+
validateModifiedFiles: true,
|
|
40
41
|
validateVersionsLocked: true,
|
|
41
42
|
newMethodsMaxLines: 30,
|
|
42
43
|
modifiedAndNewMethodsMaxLines: 80,
|
|
44
|
+
modifiedFilesMaxLines: 900,
|
|
43
45
|
},
|
|
44
46
|
features: {
|
|
45
47
|
generate: true,
|
|
@@ -157,6 +159,8 @@ function buildValidationTargetsList(validations) {
|
|
|
157
159
|
targets.push('validate-new-methods');
|
|
158
160
|
if (validations.validateModifiedMethods)
|
|
159
161
|
targets.push('validate-modified-methods');
|
|
162
|
+
if (validations.validateModifiedFiles)
|
|
163
|
+
targets.push('validate-modified-files');
|
|
160
164
|
if (validations.validateVersionsLocked)
|
|
161
165
|
targets.push('validate-versions-locked');
|
|
162
166
|
return targets;
|
|
@@ -195,6 +199,9 @@ function createWorkspaceTargetsWithoutPrefix(opts) {
|
|
|
195
199
|
if (validations.validateModifiedMethods) {
|
|
196
200
|
targets['validate-modified-methods'] = createValidateModifiedMethodsTarget(validations.modifiedAndNewMethodsMaxLines);
|
|
197
201
|
}
|
|
202
|
+
if (validations.validateModifiedFiles) {
|
|
203
|
+
targets['validate-modified-files'] = createValidateModifiedFilesTarget(validations.modifiedFilesMaxLines);
|
|
204
|
+
}
|
|
198
205
|
if (validations.validateVersionsLocked) {
|
|
199
206
|
targets['validate-versions-locked'] = createValidateVersionsLockedTarget();
|
|
200
207
|
}
|
|
@@ -239,6 +246,9 @@ function createWorkspaceTargets(opts) {
|
|
|
239
246
|
if (opts.workspace.validations.validateModifiedMethods) {
|
|
240
247
|
targets[`${prefix}validate-modified-methods`] = createValidateModifiedMethodsTarget(opts.workspace.validations.modifiedAndNewMethodsMaxLines);
|
|
241
248
|
}
|
|
249
|
+
if (opts.workspace.validations.validateModifiedFiles) {
|
|
250
|
+
targets[`${prefix}validate-modified-files`] = createValidateModifiedFilesTarget(opts.workspace.validations.modifiedFilesMaxLines);
|
|
251
|
+
}
|
|
242
252
|
return targets;
|
|
243
253
|
}
|
|
244
254
|
function createGenerateTarget(graphPath) {
|
|
@@ -345,6 +355,18 @@ function createValidateModifiedMethodsTarget(maxLines) {
|
|
|
345
355
|
},
|
|
346
356
|
};
|
|
347
357
|
}
|
|
358
|
+
function createValidateModifiedFilesTarget(maxLines) {
|
|
359
|
+
return {
|
|
360
|
+
executor: '@webpieces/dev-config:validate-modified-files',
|
|
361
|
+
cache: false, // Don't cache - depends on git state
|
|
362
|
+
inputs: ['default'],
|
|
363
|
+
options: { max: maxLines },
|
|
364
|
+
metadata: {
|
|
365
|
+
technologies: ['nx'],
|
|
366
|
+
description: `Validate modified files do not exceed ${maxLines} lines (encourages keeping files small)`,
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
}
|
|
348
370
|
function createValidateVersionsLockedTarget() {
|
|
349
371
|
return {
|
|
350
372
|
executor: '@webpieces/dev-config:validate-versions-locked',
|