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]

Reply via email to