Skip to content

Commit b9faeaa

Browse files
authored
feat(maven): add Maven/pom.xml ecosystem support (#61)
* feat(maven): add Maven/pom.xml ecosystem support Add deps-maven crate implementing Maven Central registry integration with pom.xml SAX parsing via quick-xml. Supports dependencies, dependencyManagement, and build plugins with byte-accurate position tracking. Registered as feature-gated ecosystem in deps-lsp. * docs: add Maven ecosystem to CHANGELOG and README files
1 parent a6208ed commit b9faeaa

25 files changed

+2387
-3
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- **Maven ecosystem support** — New `deps-maven` crate with pom.xml parsing and Maven Central integration
12+
- SAX parser via quick-xml with byte-accurate position tracking
13+
- Parses `<dependencies>`, `<dependencyManagement>`, and `<build><plugins>` sections
14+
- Maven Central Solr API client for version lookup and package search
15+
- Maven version comparison with prerelease qualifier detection (alpha, beta, RC, SNAPSHOT)
16+
- `groupId:artifactId` as canonical package identifier
17+
- Feature-gated registration in deps-lsp (`maven`)
18+
1019
## [0.7.0] - 2026-02-16
1120

1221
### Added

Cargo.lock

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ deps-pypi = { version = "0.7.0", path = "crates/deps-pypi" }
2222
deps-go = { version = "0.7.0", path = "crates/deps-go" }
2323
deps-bundler = { version = "0.7.0", path = "crates/deps-bundler" }
2424
deps-dart = { version = "0.7.0", path = "crates/deps-dart" }
25+
deps-maven = { version = "0.7.0", path = "crates/deps-maven" }
2526
deps-lsp = { version = "0.7.0", path = "crates/deps-lsp" }
2627
futures = "0.3"
2728
insta = "1"
@@ -45,6 +46,7 @@ tower-lsp-server = "0.23"
4546
tracing = "0.1"
4647
tracing-subscriber = "0.3"
4748
urlencoding = "2.1"
49+
quick-xml = "0.39"
4850
yaml-rust2 = "0.11"
4951
zed_extension_api = "0.7"
5052

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,10 @@ deps-lsp is optimized for responsiveness:
4747
| Go Modules | `go.mod` | ✅ Supported |
4848
| Ruby/Bundler | `Gemfile` | ✅ Supported |
4949
| Dart/Pub | `pubspec.yaml` | ✅ Supported |
50+
| Maven | `pom.xml` | ✅ Supported |
5051

5152
> [!NOTE]
52-
> PyPI support includes PEP 621, PEP 735 (dependency-groups), and Poetry formats. Go support includes require, replace, and exclude directives with pseudo-version handling. Bundler support includes git, path, and GitHub sources plus pessimistic version requirements (`~>`). Dart support includes hosted, git, path, and SDK dependency sources with caret version semantics.
53+
> PyPI support includes PEP 621, PEP 735 (dependency-groups), and Poetry formats. Go support includes require, replace, and exclude directives with pseudo-version handling. Bundler support includes git, path, and GitHub sources plus pessimistic version requirements (`~>`). Dart support includes hosted, git, path, and SDK dependency sources with caret version semantics. Maven support covers `dependencies`, `dependencyManagement`, and `build/plugins` sections with Maven qualifier-aware version comparison.
5354
5455
## Installation
5556

@@ -113,6 +114,7 @@ cargo install deps-lsp --no-default-features --features "pypi"
113114
| `go` | go.mod ||
114115
| `bundler` | Ruby (Bundler/Gemfile) ||
115116
| `dart` | pubspec.yaml ||
117+
| `maven` | pom.xml ||
116118

117119
## Usage
118120

@@ -291,6 +293,7 @@ deps-lsp/
291293
│ ├── deps-go/ # go.mod parser + proxy.golang.org
292294
│ ├── deps-bundler/ # Gemfile parser + rubygems.org registry
293295
│ ├── deps-dart/ # pubspec.yaml parser + pub.dev registry
296+
│ ├── deps-maven/ # pom.xml parser + Maven Central registry
294297
│ ├── deps-lsp/ # Main LSP server
295298
│ └── deps-zed/ # Zed extension (WASM)
296299
├── .config/ # nextest configuration

crates/deps-lsp/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ name = "deps_lsp"
2121
path = "src/lib.rs"
2222

2323
[features]
24-
default = ["cargo", "npm", "pypi", "go", "bundler", "dart"]
24+
default = ["cargo", "npm", "pypi", "go", "bundler", "dart", "maven"]
2525
cargo = ["dep:deps-cargo"]
2626
npm = ["dep:deps-npm"]
2727
pypi = ["dep:deps-pypi"]
2828
go = ["dep:deps-go"]
2929
bundler = ["dep:deps-bundler"]
3030
dart = ["dep:deps-dart"]
31+
maven = ["dep:deps-maven"]
3132

3233
[dependencies]
3334
# Internal crates
@@ -38,6 +39,7 @@ deps-pypi = { workspace = true, optional = true }
3839
deps-go = { workspace = true, optional = true }
3940
deps-bundler = { workspace = true, optional = true }
4041
deps-dart = { workspace = true, optional = true }
42+
deps-maven = { workspace = true, optional = true }
4143

4244
# External dependencies
4345
dashmap = { workspace = true }

crates/deps-lsp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Language Server Protocol implementation for dependency management.
99

1010
## Features
1111

12-
- **Multi-ecosystem** — Cargo.toml, package.json, pyproject.toml, go.mod
12+
- **Multi-ecosystem** — Cargo.toml, package.json, pyproject.toml, go.mod, Gemfile, pubspec.yaml, pom.xml
1313
- **Inlay Hints** — Show latest versions inline
1414
- **Hover Info** — Package descriptions and version lists
1515
- **Code Actions** — Quick fixes to update dependencies

crates/deps-lsp/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,21 @@ ecosystem!(
124124
]
125125
);
126126

127+
ecosystem!(
128+
"maven",
129+
deps_maven,
130+
MavenEcosystem,
131+
[
132+
MavenDependency,
133+
MavenParseResult,
134+
MavenVersion,
135+
MavenFormatter,
136+
ArtifactInfo,
137+
MavenCentralRegistry,
138+
parse_pom_xml,
139+
]
140+
);
141+
127142
/// Registers all enabled ecosystems.
128143
pub fn register_ecosystems(registry: &EcosystemRegistry, cache: Arc<HttpCache>) {
129144
register!("cargo", CargoEcosystem, registry, &cache);
@@ -132,6 +147,7 @@ pub fn register_ecosystems(registry: &EcosystemRegistry, cache: Arc<HttpCache>)
132147
register!("go", GoEcosystem, registry, &cache);
133148
register!("bundler", BundlerEcosystem, registry, &cache);
134149
register!("dart", DartEcosystem, registry, &cache);
150+
register!("maven", MavenEcosystem, registry, &cache);
135151
}
136152

137153
#[cfg(test)]
@@ -156,5 +172,7 @@ mod tests {
156172
assert!(registry.get("bundler").is_some());
157173
#[cfg(feature = "dart")]
158174
assert!(registry.get("dart").is_some());
175+
#[cfg(feature = "maven")]
176+
assert!(registry.get("maven").is_some());
159177
}
160178
}

crates/deps-maven/Cargo.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[package]
2+
name = "deps-maven"
3+
version.workspace = true
4+
edition.workspace = true
5+
rust-version.workspace = true
6+
authors.workspace = true
7+
license.workspace = true
8+
repository.workspace = true
9+
description = "pom.xml support for deps-lsp"
10+
publish = true
11+
12+
[lints]
13+
workspace = true
14+
15+
[dependencies]
16+
deps-core = { workspace = true }
17+
async-trait = { workspace = true }
18+
quick-xml = { workspace = true }
19+
serde = { workspace = true, features = ["derive"] }
20+
serde_json = { workspace = true }
21+
thiserror = { workspace = true }
22+
tokio = { workspace = true }
23+
tower-lsp-server = { workspace = true }
24+
tracing = { workspace = true }
25+
urlencoding = { workspace = true }
26+
27+
[dev-dependencies]
28+
insta = { workspace = true, features = ["json"] }
29+
tempfile = { workspace = true }
30+
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
31+
tokio-test = { workspace = true }

crates/deps-maven/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# deps-maven
2+
3+
[![Crates.io](https://img.shields.io/crates/v/deps-maven)](https://crates.io/crates/deps-maven)
4+
[![docs.rs](https://img.shields.io/docsrs/deps-maven)](https://docs.rs/deps-maven)
5+
[![codecov](https://codecov.io/gh/bug-ops/deps-lsp/graph/badge.svg?token=S71PTINTGQ&flag=deps-maven)](https://codecov.io/gh/bug-ops/deps-lsp)
6+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)
7+
8+
pom.xml support for deps-lsp.
9+
10+
This crate provides Maven/JVM ecosystem support for the deps-lsp server, including pom.xml parsing, dependency extraction, and Maven Central registry integration.
11+
12+
## Features
13+
14+
- **XML Parsing** — Parse `pom.xml` with byte-accurate position tracking using `quick-xml` SAX reader
15+
- **Dependency Sections** — Handle `<dependencies>`, `<dependencyManagement>`, and `<build><plugins>` blocks
16+
- **Maven Central Registry** — Solr API client for version lookups and artifact search
17+
- **Version Comparison** — Maven version qualifier support (`alpha`, `beta`, `RC`, `SNAPSHOT`, `GA`)
18+
- **Property Resolution** — Resolve `${property}` placeholders defined in `<properties>`
19+
- **Scope Handling** — Recognise `compile`, `test`, `provided`, `runtime`, and `import` scopes
20+
- **Ecosystem Trait** — Implements `deps_core::Ecosystem` trait
21+
22+
## Usage
23+
24+
```toml
25+
[dependencies]
26+
deps-maven = "0.7"
27+
```
28+
29+
```rust
30+
use deps_maven::{parse_pom_xml, MavenCentralRegistry};
31+
32+
let result = parse_pom_xml(content, &uri)?;
33+
let registry = MavenCentralRegistry::new(cache);
34+
let versions = registry.get_versions_typed("org.springframework:spring-core").await?;
35+
```
36+
37+
## Supported pom.xml Syntax
38+
39+
```xml
40+
<project>
41+
<properties>
42+
<spring.version>6.1.0</spring.version>
43+
</properties>
44+
45+
<dependencies>
46+
<dependency>
47+
<groupId>org.springframework</groupId>
48+
<artifactId>spring-core</artifactId>
49+
<version>6.1.0</version>
50+
</dependency>
51+
<dependency>
52+
<groupId>junit</groupId>
53+
<artifactId>junit</artifactId>
54+
<version>4.13.2</version>
55+
<scope>test</scope>
56+
</dependency>
57+
</dependencies>
58+
59+
<dependencyManagement>
60+
<dependencies>
61+
<dependency>
62+
<groupId>org.springframework.boot</groupId>
63+
<artifactId>spring-boot-dependencies</artifactId>
64+
<version>3.2.0</version>
65+
<type>pom</type>
66+
<scope>import</scope>
67+
</dependency>
68+
</dependencies>
69+
</dependencyManagement>
70+
71+
<build>
72+
<plugins>
73+
<plugin>
74+
<groupId>org.apache.maven.plugins</groupId>
75+
<artifactId>maven-compiler-plugin</artifactId>
76+
<version>3.12.1</version>
77+
</plugin>
78+
</plugins>
79+
</build>
80+
</project>
81+
```
82+
83+
## License
84+
85+
[MIT](../../LICENSE)

0 commit comments

Comments
 (0)