@aspruyt/xfg 5.5.0 → 5.6.0
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.
|
@@ -394,16 +394,18 @@ function mergeGroupSettings(rootSettings, groupNames, groupDefs) {
|
|
|
394
394
|
}
|
|
395
395
|
/**
|
|
396
396
|
* Evaluates a conditional group's `when` clause against a repo's effective groups.
|
|
397
|
-
*
|
|
398
|
-
*
|
|
397
|
+
* All specified operators must be satisfied: `allOf` (every listed group present),
|
|
398
|
+
* `anyOf` (at least one present), and `noneOf` (none of the listed groups present).
|
|
399
|
+
* Absent conditions are treated as satisfied.
|
|
399
400
|
*/
|
|
400
401
|
function evaluateWhenClause(when, effectiveGroups) {
|
|
401
|
-
// Defensive: if
|
|
402
|
-
if (!when.allOf && !when.anyOf)
|
|
402
|
+
// Defensive: if no condition is specified, don't match
|
|
403
|
+
if (!when.allOf && !when.anyOf && !when.noneOf)
|
|
403
404
|
return false;
|
|
404
405
|
const allOfSatisfied = !when.allOf || when.allOf.every((g) => effectiveGroups.has(g));
|
|
405
406
|
const anyOfSatisfied = !when.anyOf || when.anyOf.some((g) => effectiveGroups.has(g));
|
|
406
|
-
|
|
407
|
+
const noneOfSatisfied = !when.noneOf || when.noneOf.every((g) => !effectiveGroups.has(g));
|
|
408
|
+
return allOfSatisfied && anyOfSatisfied && noneOfSatisfied;
|
|
407
409
|
}
|
|
408
410
|
/**
|
|
409
411
|
* Merges matching conditional groups into the accumulated files/prOptions/settings.
|
package/dist/config/types.d.ts
CHANGED
|
@@ -315,6 +315,8 @@ export interface RawConditionalGroupWhen {
|
|
|
315
315
|
allOf?: string[];
|
|
316
316
|
/** At least one listed group must be present */
|
|
317
317
|
anyOf?: string[];
|
|
318
|
+
/** None of the listed groups may be present */
|
|
319
|
+
noneOf?: string[];
|
|
318
320
|
}
|
|
319
321
|
/** Conditional group: activates based on which groups a repo has */
|
|
320
322
|
export interface RawConditionalGroupConfig {
|
package/dist/config/validator.js
CHANGED
|
@@ -449,9 +449,9 @@ function validateConditionalGroups(config) {
|
|
|
449
449
|
if (!entry.when || !isPlainObject(entry.when)) {
|
|
450
450
|
throw new ValidationError(`${ctx}: 'when' is required and must be an object`);
|
|
451
451
|
}
|
|
452
|
-
const { allOf, anyOf } = entry.when;
|
|
453
|
-
if (!allOf && !anyOf) {
|
|
454
|
-
throw new ValidationError(`${ctx}: 'when' must have at least one of 'allOf' or '
|
|
452
|
+
const { allOf, anyOf, noneOf } = entry.when;
|
|
453
|
+
if (!allOf && !anyOf && !noneOf) {
|
|
454
|
+
throw new ValidationError(`${ctx}: 'when' must have at least one of 'allOf', 'anyOf', or 'noneOf'`);
|
|
455
455
|
}
|
|
456
456
|
if (allOf !== undefined) {
|
|
457
457
|
validateGroupRefArray(allOf, "allOf", ctx, groupNames);
|
|
@@ -459,6 +459,27 @@ function validateConditionalGroups(config) {
|
|
|
459
459
|
if (anyOf !== undefined) {
|
|
460
460
|
validateGroupRefArray(anyOf, "anyOf", ctx, groupNames);
|
|
461
461
|
}
|
|
462
|
+
if (noneOf !== undefined) {
|
|
463
|
+
validateGroupRefArray(noneOf, "noneOf", ctx, groupNames);
|
|
464
|
+
}
|
|
465
|
+
// Cross-operator overlap: noneOf must not share groups with allOf or anyOf
|
|
466
|
+
if (noneOf) {
|
|
467
|
+
const noneOfSet = new Set(noneOf);
|
|
468
|
+
if (allOf) {
|
|
469
|
+
for (const g of allOf) {
|
|
470
|
+
if (noneOfSet.has(g)) {
|
|
471
|
+
throw new ValidationError(`${ctx}: noneOf group '${g}' overlaps with allOf (contradictory condition)`);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (anyOf) {
|
|
476
|
+
for (const g of anyOf) {
|
|
477
|
+
if (noneOfSet.has(g)) {
|
|
478
|
+
throw new ValidationError(`${ctx}: noneOf group '${g}' overlaps with anyOf (contradictory condition)`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
462
483
|
// Validate files
|
|
463
484
|
if (entry.files) {
|
|
464
485
|
for (const [fileName, fileConfig] of Object.entries(entry.files)) {
|
package/package.json
CHANGED