Howdy, for start check out Toolbox similar goals like https://maveniverse.eu/docs/toolbox/plugin-documentation/add-managed-dependency-mojo.html
Also, implementation wise, Xpp3Reader _does not_ preserve formatting nor comments. In fact, this is the sole reason why we did this: https://github.com/maveniverse/domtrip HTH T On Tue, Mar 31, 2026 at 4:01 PM Bruno Borges <[email protected]> wrote: > > Hi all, > > I'd like to propose adding three new goals to the Maven Dependency > Plugin: `dependency:add`, `dependency:remove`, and > `dependency:search`. I'm volunteering to do the implementation work > and would appreciate feedback on the approach before I begin. > > Every major dependency management ecosystem provides a simple, > single-command way to add a dependency from the command line, except > Maven. Consider how Google's recently released Agent Development Kit > (ADK) documents its installation across languages: > > * **Python:** `pip install google-adk` > * **TypeScript:** `npm install @google/adk` > * **Go:** `go get google.golang.org/adk` > * **Java (Maven):** "Open your `pom.xml` and add the following > dependency block..." followed by a multi-line XML snippet that the > developer must manually copy, paste, and position correctly. > > This isn't unique to Google's ADK... it's the same experience for > every Java library distributed through Maven Central. While Cargo has > `cargo add`, NuGet has `dotnet add package`, Maven requires developers > to leave their terminal, open an XML file, find the right insertion > point, paste a `<dependency>` block, and ensure the formatting is > consistent. Even for AI coding agents, calling a CLI would be > significantly cheaper (in terms of token usage) than editing an XML > file. This friction is a real barrier, particularly for developers > coming from other ecosystems, and it makes Maven feel dated compared > to its peers. > > # Proposed goals > > ## `dependency:add` - Adds a dependency to the project's `pom.xml`. > > ``` > mvn dependency:add -DgroupId=com.google.adk -DartifactId=google-adk > -Dversion=1.0.0 > mvn dependency:add -Dgav="com.google.adk:google-adk:1.0.0" > mvn dependency:add -DgroupId=com.google.adk -DartifactId=google-adk > -Dversion=1.0.0 -Dscope=test > ``` > > The goal would parse the existing `pom.xml`, insert the dependency in > the `<dependencies>` section, preserve existing formatting and > comments, and write the file back. If the dependency already exists, > it would update the version (or warn, depending on a flag). > > ### `<dependencies>` vs `<dependencyManagement>` > > By default, `dependency:add` would insert into the `<dependencies>` > section, since that's the most common use case and the closest analog > to what `npm install` or `cargo add` do. However, a > `-DdependencyManagement` flag (or shorter alias `-Dmanaged`) would > target the `<dependencyManagement>` section instead: > > ``` > mvn dependency:add -Dgav="com.google.adk:google-adk:1.0.0" -Dmanaged > ``` > > When adding to `<dependencyManagement>`, the version is always > required. When adding to `<dependencies>` in a child module where the > parent already manages that dependency's version via > `<dependencyManagement>`, the version parameter would be optional — > the goal would detect the managed version and omit `<version>` from > the inserted block, following Maven's established convention. > > ### Multi-module projects > > In multi-module projects, the behavior depends on where the command is > executed: > > * **From a child module directory:** the dependency is added to that > module's `pom.xml`. This is the default and most intuitive behavior: > you `cd` into the module you want to modify and run the command, just > as you would run `npm install` from a specific package directory in a > monorepo. > > * **From the root/parent directory with `-Dmanaged`:** the dependency > is added to the parent's `<dependencyManagement>` section, making the > version centrally governed. Child modules can then declare the > dependency without specifying a version. > > * **From the root/parent directory without `-Dmanaged`:** the > dependency is added to the parent's `<dependencies>` section, meaning > it will be inherited by all child modules. This is a legitimate use > case (e.g., adding a logging facade or a common utility across all > modules), but since it has broad impact, the goal would print a > warning: _"Adding dependency to parent POM — this will be inherited by > all child modules. Use -Dmanaged to add to dependencyManagement > instead."_ > > This goal would also support a `-Dmodule=module-name` parameter to > target a specific child module from the root directory without having > to `cd` into it. > > ## `dependency:remove` - Removes a dependency from the project's `pom.xml`. > > ``` > mvn dependency:remove -DgroupId=com.google.adk -DartifactId=google-adk > mvn dependency:remove -Dgav=com.google.adk:google-adk > ``` > > By default, this removes from `<dependencies>`. The `-Dmanaged` flag > would target `<dependencyManagement>` instead. When removing a managed > dependency from a parent POM, the goal would warn if any child modules > still reference that dependency without an explicit version, since > those modules would break on the next build. > > ## `dependency:search` - Queries Maven Central for artifacts matching > a search term. > > ``` > mvn dependency:search -Dquery=google-adk > ``` > > This would return a concise list of matching `groupId:artifactId` > pairs with their latest versions, making it easy to discover > coordinates without leaving the terminal. > > # What I'm not proposing > > ## Conflict resolution tooling > > Automatic resolution of version conflicts is a complex problem with > many edge cases. The existing `dependency:tree` and > `dependency:analyze` goals are better starting points for > understanding conflicts, and automated resolution would require > careful design. This is better left for a separate discussion. Adding > or removing dependencies using the command line achieves the same > result as manually editing the XML files; neither prevents potential > conflicts or issues. > > ## Vulnerability auditing or license checking > > Plugins like `org.owasp:dependency-check-maven` and > `org.codehaus.mojo:license-maven-plugin` already handle these concerns > well. Duplicating their functionality here would fragment the > ecosystem without adding clear value. > > ## SBOM generation > > Both `org.cyclonedx:cyclonedx-maven-plugin` (CycloneDX format) and > `org.spdx:spdx-maven-plugin` (SPDX format) are actively maintained and > closely track their respective evolving specifications. A > general-purpose plugin would inevitably lag behind these dedicated > implementations. > > ## Migration assistance > > Helping developers navigate breaking changes across major dependency > upgrades requires deep semantic understanding of API changes; the kind > of analysis that likely depends on AI/LLM tooling rather than a build > plugin. This is an interesting space but outside the scope of what the > dependency plugin should tackle in my opinion. > > # Implementation notes > > * `pom.xml` modification would use a formatting-preserving XML > approach (likely `MavenXpp3Reader`/`Writer` or similar) to avoid > reformatting the entire file. > * The search goal would use the Maven Central REST API (or Solr search > endpoint) by default, with support for custom repository search if the > repository exposes a compatible API. > * All goals would respect the standard Maven plugin parameter > conventions and work in both single-module and multi-module projects. > * For multi-module projects, the goals would resolve the effective POM > to determine whether a dependency version is already managed by a > parent, and adjust the inserted XML accordingly (omitting `<version>` > when already managed). > > I'd welcome any feedback on the scope, naming conventions, or > implementation approach. I will start working on it as soon as we have > some general agreement that this would be a valuable addition. > > Best regards > --- > Bruno Borges > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
