Repository: openrewrite/rewrite (Java)

Issue:
Maven - Add `groupId ` if missing for maven plugins
## What problem are you trying to solve?

In Maven, it is possible to omit the `groupId ` of a Maven plugin as maven defaults to `org.apache.maven.plugins` when the `groupId ` is not provided


## What precondition(s) should be checked before applying this recipe?

- It is a maven build
- It is a plugin definition
- the `groupId ` is not present


## Describe the situation before applying the recipe
<!-- Ideally as a self-contained code example, as a start to the recipe unit tests. -->
```xml

<build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
            </plugin>
        </plugins>
 </build>         
   
```

## Describe the situation after applying the recipe
<!-- Ideally as a self-contained code example, as a start to the recipe unit tests. -->


```diff

<build>
        <plugins>
            <plugin>
++             <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
            </plugin>
        </plugins>
 </build>         
   
```



## Any additional context

Schema : https://maven.apache.org/xsd/maven-4.0.0.xsd

In particualr this section


```xml

<xs:all>
<xs:element minOccurs="0" name="groupId" type="xs:string" default="org.apache.maven.plugins">
<xs:annotation>
<xs:documentation source="version">4.0.0+</xs:documentation>
<xs:documentation source="description">
The group ID of the reporting plugin in the repository.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" name="artifactId" type="xs:string">

```



Discussion: Thanks for the clear description and link to the xsd; what's your motivation to override the default with the same value? Clarity?

Seems like an relatively straightforward (custom) recipe; would you be willing to take that on?
> Thanks for the clear description and link to the xsd; what's your motivation to override the default with the same value? Clarity?
> 
> Seems like an relatively straightforward (custom) recipe; would you be willing to take that on?

The motivation is definitely clarity. It took some digging to find out that this was a default when all other plugins expect the groupId defined. In my opinion, I think that it is a bad practice to depend on that default
Agree with you there; we can add this to a Maven best practices recipe, along with setting an explicit version & property prefix.
- https://github.com/openrewrite/rewrite/issues/2735
- https://github.com/openrewrite/rewrite/issues/1621
Implemented in 
- https://github.com/openrewrite/rewrite/pull/3591



Fix (patch):
diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupId.java b/rewrite-maven/src/main/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupId.java
new file mode 100755
index 0000000000..e9bb432c38
--- /dev/null
+++ b/rewrite-maven/src/main/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupId.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2023 the original author or authors.
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * https://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.maven.cleanup;
+
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.maven.MavenTagInsertionComparator;
+import org.openrewrite.maven.MavenVisitor;
+import org.openrewrite.xml.AddToTagVisitor;
+import org.openrewrite.xml.tree.Xml;
+
+@Value
+@EqualsAndHashCode(callSuper = true)
+public class ExplicitPluginGroupId extends Recipe {
+    @Override
+    public String getDisplayName() {
+        return "Add explicit `groupId` to Maven plugins";
+    }
+
+    @Override
+    public String getDescription() {
+        return "Add the default `<groupId>org.apache.maven.plugins</groupId>` to plugins for clarity.";
+    }
+
+    @Override
+    public TreeVisitor<?, ExecutionContext> getVisitor() {
+        return new MavenVisitor<ExecutionContext>() {
+            @Override
+            public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
+                Xml.Tag t = (Xml.Tag) super.visitTag(tag, ctx);
+                if (isPluginTag() && !t.getChild("groupId").isPresent()) {
+                    Xml.Tag groupIdTag = Xml.Tag.build("<groupId>org.apache.maven.plugins</groupId>");
+                    t = (Xml.Tag) new AddToTagVisitor<>(t, groupIdTag, new MavenTagInsertionComparator(t.getChildren()))
+                            .visitNonNull(t, ctx, getCursor().getParentOrThrow());
+                    maybeUpdateModel();
+                }
+                return t;
+            }
+        };
+    }
+}
diff --git a/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml b/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml
index 1a8a106553..351033dad4 100644
--- a/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml
+++ b/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml
@@ -19,6 +19,7 @@ name: org.openrewrite.maven.BestPractices
 displayName: Apache Maven best practices
 description: Applies best practices to Maven POMs.
 recipeList:
+  - org.openrewrite.maven.cleanup.ExplicitPluginGroupId
   - org.openrewrite.maven.cleanup.PrefixlessExpressions
 
 ---