Skip to content

Commit bee24b3

Browse files
authored
Add dependency insertion ordering auto-detection (#286)
addAligned() now detects whether the project's <dependencies> container follows an ordering convention and inserts new dependencies at the correct position, transparently to callers. New AlignOptions.InsertionOrdering enum: NONE, ALPHA, SCOPE, SCOPE_THEN_ALPHA. Follows the existing nullable-field convention (null = auto-detect), consistent with VersionStyle, VersionSource, and PropertyNamingConvention. Detection (detectInsertionOrdering): analyses consecutive dependency pairs with a 75% threshold heuristic. Priority: SCOPE_THEN_ALPHA > SCOPE > ALPHA > NONE. Fewer than 3 deps returns NONE (signal too weak). SCOPE and SCOPE_THEN_ALPHA require actual scope variation; an all-same-scope alpha list returns ALPHA. Plugged into detectConventions(), which returns null (not NONE) for the insertionOrdering field when the direct-deps container is absent or too small, so callers relying on auto-detection are not inadvertently blocked. Canonical scope order: compile, provided, runtime, system, test, import. Null or empty scope is normalised to compile (DEFAULT_SCOPE constant). addAligned(Coordinates, AlignOptions) resolves the effective ordering (explicit option wins, else auto-detect from the appropriate container) and inserts at the anchor position computed by findInsertionAnchor(). ensureManagedDependency() applies the same logic, independently detecting ordering from the managed container — managed-only POMs with no direct <dependencies> are handled correctly. New InsertionOrderingTest (17 tests) covers detection and insertion for ALPHA, SCOPE, SCOPE_THEN_ALPHA, weak-signal (< 3 deps), empty container, inconsistent order, managed-only POM, null/empty scope, and explicit NONE override. No existing public method signatures changed; all 340 existing tests pass.
1 parent 3dd2661 commit bee24b3

4 files changed

Lines changed: 1001 additions & 7 deletions

File tree

‎maven/src/main/java/eu/maveniverse/domtrip/maven/AlignOptions.java‎

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ public enum VersionSource {
7373
PROPERTY
7474
}
7575

76+
/**
77+
* Ordering convention for dependency insertion.
78+
*
79+
* @since 1.7.0
80+
*/
81+
public enum InsertionOrdering {
82+
/** No ordering detected or enforced — insert at end. */
83+
NONE,
84+
/** Dependencies ordered alphabetically by groupId:artifactId. */
85+
ALPHA,
86+
/** Dependencies ordered by Maven scope (compile, provided, runtime, system, test, import). */
87+
SCOPE,
88+
/** Dependencies ordered by scope first, then alphabetically within each scope group. */
89+
SCOPE_THEN_ALPHA
90+
}
91+
7692
/**
7793
* Naming convention for version properties.
7894
*
@@ -92,6 +108,7 @@ public enum PropertyNamingConvention {
92108
private final VersionStyle versionStyle;
93109
private final VersionSource versionSource;
94110
private final PropertyNamingConvention namingConvention;
111+
private final InsertionOrdering insertionOrdering;
95112
private final Function<Coordinates, String> propertyNameGenerator;
96113
private final String propertyName;
97114
private final String scope;
@@ -105,6 +122,7 @@ public enum PropertyNamingConvention {
105122
* @param versionStyle placement of dependency versions (inline vs managed); {@code null} means auto-detect
106123
* @param versionSource whether versions are literal or property references; {@code null} means auto-detect
107124
* @param namingConvention property naming convention to use; {@code null} means auto-detect
125+
* @param insertionOrdering ordering convention for dependency insertion; {@code null} means auto-detect
108126
* @param propertyNameGenerator optional custom generator for property names; {@code null} to use convention-based generation
109127
* @param propertyName explicit property name override; {@code null} to allow auto-generation
110128
* @param scope Maven dependency scope override; {@code null} to use the default scope
@@ -113,12 +131,14 @@ private AlignOptions(
113131
VersionStyle versionStyle,
114132
VersionSource versionSource,
115133
PropertyNamingConvention namingConvention,
134+
InsertionOrdering insertionOrdering,
116135
Function<Coordinates, String> propertyNameGenerator,
117136
String propertyName,
118137
String scope) {
119138
this.versionStyle = versionStyle;
120139
this.versionSource = versionSource;
121140
this.namingConvention = namingConvention;
141+
this.insertionOrdering = insertionOrdering;
122142
this.propertyNameGenerator = propertyNameGenerator;
123143
this.propertyName = propertyName;
124144
this.scope = scope;
@@ -131,7 +151,7 @@ private AlignOptions(
131151
* @since 1.1.0
132152
*/
133153
public static AlignOptions defaults() {
134-
return new AlignOptions(null, null, null, null, null, null);
154+
return new AlignOptions(null, null, null, null, null, null, null);
135155
}
136156

137157
/**
@@ -174,6 +194,16 @@ public PropertyNamingConvention namingConvention() {
174194
return namingConvention;
175195
}
176196

197+
/**
198+
* The insertion ordering convention to use, or null to indicate auto-detection.
199+
*
200+
* @return the insertion ordering override, or {@code null} if it should be auto-detected
201+
* @since 1.7.0
202+
*/
203+
public InsertionOrdering insertionOrdering() {
204+
return insertionOrdering;
205+
}
206+
177207
/**
178208
* Custom function that generates property names from dependency coordinates, or null to use convention-based generation.
179209
*
@@ -278,6 +308,7 @@ public static final class Builder {
278308
private VersionStyle versionStyle;
279309
private VersionSource versionSource;
280310
private PropertyNamingConvention namingConvention;
311+
private InsertionOrdering insertionOrdering;
281312
private Function<Coordinates, String> propertyNameGenerator;
282313
private String propertyName;
283314
private String scope;
@@ -320,6 +351,18 @@ public Builder namingConvention(PropertyNamingConvention namingConvention) {
320351
return this;
321352
}
322353

354+
/**
355+
* Sets the insertion ordering convention override.
356+
*
357+
* @param insertionOrdering the ordering convention (null for auto-detection)
358+
* @return this builder
359+
* @since 1.7.0
360+
*/
361+
public Builder insertionOrdering(InsertionOrdering insertionOrdering) {
362+
this.insertionOrdering = insertionOrdering;
363+
return this;
364+
}
365+
323366
/**
324367
* Set a custom function that generates property names from dependency coordinates.
325368
*
@@ -372,7 +415,13 @@ public Builder scope(String scope) {
372415
*/
373416
public AlignOptions build() {
374417
return new AlignOptions(
375-
versionStyle, versionSource, namingConvention, propertyNameGenerator, propertyName, scope);
418+
versionStyle,
419+
versionSource,
420+
namingConvention,
421+
insertionOrdering,
422+
propertyNameGenerator,
423+
propertyName,
424+
scope);
376425
}
377426
}
378427
}

0 commit comments

Comments
 (0)