1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
// rustc's default recursion limit can't always prove the `Send` bound on the boxed futures
// `impl_dependency!`/`impl_version!` generate, turning a silent trait-solver retry into a hard
// error under `-D warnings` (rust-lang/rust#159228). Same fix as deps-cargo #745, deps-nuget
// #696, deps-swift #673.
//! Core abstractions for deps-lsp.
//!
//! This crate provides the foundational traits and utilities used across
//! all ecosystem-specific implementations (Cargo, npm, PyPI, etc.).
//!
//! # Architecture
//!
//! deps-core defines:
//! - **Traits**: `Registry`, `Version`, `Metadata`, `Ecosystem`, `ParseResult`
//! - **HTTP Cache**: Shared caching layer with ETag/Last-Modified validation
//! - **Error Types**: Unified error handling across all ecosystems
//!
//! # API stability (issue #769)
//!
//! Most public structs and enums here are `#[non_exhaustive]` so a new field or variant
//! never breaks a downstream ecosystem crate's exhaustive match or struct literal. This is a
//! per-kind decision, not one policy for both: on a **struct** with no `pub` fields,
//! `#[non_exhaustive]` is a semantic no-op (an external crate can't literal-construct or
//! destructure it either way), so such structs are deliberately left exhaustive instead. On
//! an **enum**, `#[non_exhaustive]` always forces a downstream `match` to carry a wildcard
//! arm, regardless of any variant's field visibility — each enum opts in when that forced
//! wildcard is wanted and stays exhaustive when a future variant should instead be a
//! compile error downstream; see the individual enum's own doc comment for which applies.
//!
//! A few pre-1.0 dependency types remain visible in public signatures as a deliberate
//! semver commitment rather than an oversight:
//! - [`error::SanitizedRegistryError`] implements `From<reqwest::Error>` — a `reqwest`
//! major bump that reshapes `Error` is a breaking change for this crate too.
//! - [`parser::yaml_scalar_string`] takes `&yaml_rust2::Yaml`; `yaml_rust2` is re-exported
//! from the crate root so callers can name the type without their own direct dependency,
//! and a `yaml-rust2` major bump is likewise a breaking change here.
//! - `deps-gitlab-ci`'s `gitlab_version_req` (`crates/deps-gitlab-ci/src/component.rs`)
//! returns `semver::VersionReq` directly — low risk since `semver` is unusually stable
//! pre-1.0, but the same commitment applies.
//! - [`cache_policy`] takes/returns `&dashmap::DashMap<K, V>` in its public functions; this
//! is not new coupling — [`registry::register_capped_with_occupied`] already exposes
//! `&DashMap` publicly without a `pub use dashmap` — so a `dashmap` major bump is already
//! a breaking change here regardless of this module's visibility.
//!
//! ## LSP type stability (issue #832, narrowed by #1071 and #1083)
//!
//! `tower-lsp-server` is pinned pre-1.0, so a `tower-lsp-server` minor bump (e.g. 0.23 →
//! 0.24) is not an implementation detail this crate can absorb silently — it forces a
//! breaking release of `deps-core`: a minor version bump while `deps-core` itself remains
//! pre-1.0, a major version bump once `deps-core` reaches 1.0. This section describes which
//! parts of the public API still carry that coupling.
//!
//! As of issue #1071, a dependency's own *domain* data never carried it in the first place:
//! [`ecosystem::Dependency`]'s range accessors return [`position::Range`], and
//! [`ecosystem::ParseResult::uri`] / [`ecosystem::Ecosystem::parse_manifest`] use `url::Url`
//! — neither names a `tower-lsp-server` type.
//!
//! As of issue #1083, the remaining *response*-shaped surface — `generate_hover`,
//! `generate_diagnostics` (retyped to the protocol-agnostic [`diagnostic::Diagnostic`], not
//! merely gated), `generate_code_actions`, `generate_code_lenses`, `generate_inlay_hints`,
//! `generate_document_links`, `generate_completions`/`complete_version`/
//! `complete_package_name`/`complete_feature`, and the [`completion`] module itself — is
//! gated behind the `lsp-responses` Cargo feature, along with the `tower-lsp-server`
//! dependency it requires. The feature is **not** part of this crate's `default` set:
//! Cargo does not allow a `workspace = true` dependency edge to turn off a feature that a
//! crate defaults on, so making it default here would make it inescapable for `deps-engine`
//! (see `deps-engine/Cargo.toml`'s own `lsp-responses` feature doc) — every consumer that
//! wants it, including each of the 14 `deps-<ecosystem>` crates via their own
//! identically-named feature, must request `deps-core/lsp-responses` explicitly (`deps-lsp`
//! does, directly and via `deps-engine`; `deps-cli` never does). Under `--no-default-features`
//! (or with `lsp-responses` otherwise off), `deps-core` links no `tower-lsp-server` code at
//! all, [`tower_lsp_server`] is not re-exported, and an ecosystem crate's `Ecosystem` impl
//! simply doesn't declare the gated trait methods (the trait itself omits them when the
//! feature is off, so there is nothing to implement) — this is FR-001/SC-001's mechanism for
//! keeping `deps-cli`'s dependency tree free of `tower-lsp-server` entirely (verified by
//! `cargo tree -p deps-cli -e features,no-dev` in CI).
//!
//! Downstream consumers implementing [`ecosystem::Ecosystem`] with `lsp-responses` enabled
//! should depend on the exact matching `tower-lsp-server` version through the
//! [`tower_lsp_server`] re-export rather than adding their own separate direct dependency,
//! which could otherwise drift out of sync with the version `deps-core` was built against.
//! `deps-core`'s own `lsp_helpers` converts a [`position::Position`]/[`position::Range`] into
//! its `ls_types` equivalent internally via their `From` impls wherever one must be embedded
//! in a gated response.
//!
//! Whether the *rest* of `deps-core`'s public API should stop naming third-party dependency
//! types generally (`reqwest::Error`, `yaml_rust2::Yaml`, ...) is issue #851's broader, still-
//! open question — out of scope for #1071/#1083.
// #673: re-enables the cast-safety pedantic lints the workspace allows by default, since this
// crate computes LSP offset/position math from attacker-influenceable input. Confirmed-safe
// sites get an individual `#[allow]` with justification, not a blanket allow.
// #1238: lets `redact_debug::RedactingDebug`'s generated code say `deps_core::redact_debug::…`
// unconditionally, whether the derive is used by an external consumer or by a type defined
// inside this crate itself (e.g. a future `lsp_helpers::git_ref::ResolvedShaPin` migration) —
// a crate has no external name for itself without this alias.
extern crate self as deps_core;
/// HTTP response cache with `ETag`/`Last-Modified` conditional-request validation.
/// Bounded-`DashMap` capacity policies shared by [`cache`], [`github`], [`deps_dev`], and
/// [`osv`].
///
/// `pub`, so ecosystem crates (`deps-gitlab-ci`, `deps-github-actions`, `deps-npm`) reach it
/// directly too.
/// Config-value trust tiers and `${VAR}`/`%VAR%` env-var interpolation (issue #1434).
///
/// Shared by every ecosystem whose own config format supports it.
/// Shared `#[macro_export]`ed conformance-test scaffolding (#758).
///
/// Ecosystem crates invoke these macros instead of hand-copying the same test family. Gated
/// identically to [`test_util`].
/// Per-document ceiling on tracked dependencies, enforced by
/// [`ecosystem::parse_manifest_blocking`] for all 14 ecosystems (#796).
/// Protocol-agnostic [`diagnostic::Diagnostic`]/[`diagnostic::Severity`] types (issue #1083).
///
/// The domain-level replacement for `tower_lsp_server::ls_types::{Diagnostic,
/// DiagnosticSeverity, DiagnosticRelatedInformation, CodeDescription}` returned by
/// [`lsp_helpers::generate_diagnostics_from_cache`] and
/// [`ecosystem::Ecosystem::generate_diagnostics`].
/// The [`ecosystem::Ecosystem`] trait: the sealed extension point every package
/// ecosystem crate implements to plug into the LSP server.
/// Routes a manifest path to its owning [`ecosystem::Ecosystem`] implementation.
/// Unified error types (`DepsError`, `FetchFailure`) shared across ecosystems.
/// Protocol-agnostic [`hover::Hover`] type (issue #1277).
///
/// The domain-level replacement for `tower_lsp_server::ls_types::Hover` returned by
/// [`lsp_helpers::generate_hover`] and [`ecosystem::Ecosystem::generate_hover`]. Gated
/// behind the `lsp-responses` feature, unlike [`diagnostic`] — see this module's own doc
/// for why.
/// Bounded property/variable values for manifest interpolation (issue #1481).
///
/// Shared by `deps-maven` (`${property}`) and `deps-gradle` (`version.ref`/`$name`/
/// `${name}`) to bound retained resolution memory.
/// Shared bracket-interval version-range grammar (`[1.0,2.0)`-shaped), used by
/// `deps-maven`, `deps-gradle`, and `deps-nuget` (#821).
/// Shared manifest-parsing helpers: bounded JSON/TOML/YAML nesting checks and
/// depth-limited parsing used by every ecosystem's manifest parser.
/// The policy-relevant subset of `deps-lsp`'s configuration.
///
/// Diagnostics severities, cache, freshness, supply-chain, registries, network, license
/// policy — shared with `deps-cli` so both compose the same type instead of each parsing its
/// own copy.
/// Protocol-agnostic [`position::Position`]/[`position::Range`] types (issue #1071).
///
/// The domain-level replacement for `tower_lsp_server::ls_types::{Position, Range}` in
/// [`ecosystem::Dependency`]'s range accessors.
/// Shared escape-aware string-literal and comment scanning.
///
/// [`quote_scan::read_string_literal`], [`quote_scan::strip_line_comment`],
/// [`quote_scan::blank_comments`], [`quote_scan::is_code_byte`],
/// [`quote_scan::last_string_literal`], and [`quote_scan::find_closing_quote_before_comment`],
/// parameterized over [`quote_scan::ScanSyntax`] — used by `deps-bundler`, `deps-swift`,
/// `deps-pypi`, and `deps-gradle` instead of each hand-rolling its own scanner (#1022,
/// #1174).
/// Local, process-lifetime rate-limit short-circuiting.
///
/// [`rate_limit::RateLimitGate`] is shared by `deps-github-actions` and `deps-gitlab-ci`.
/// Redaction: URL/declaration-key/parse-error text and in-memory secret values (issue #1247).
///
/// Extracted from [`net_policy`], which kept the old paths as re-exports.
/// Compile-time-enforced `Debug` redaction: the [`redact_debug::RedactingDebug`] derive
/// (issue #1238).
/// The [`registry::Registry`] trait: version lookup and search that every
/// ecosystem's registry client implements.
/// Re-export of [`redact::secret`] at its pre-#1247 path.
pub use secret;
/// [`selection::SelectionContext`]/[`selection::StabilityFloor`]: manifest-scoped
/// selection state (#1444).
/// Re-export of the LSP protocol types that appear in this crate's public trait
/// signatures. `deps-core`'s version tracks `tower-lsp-server`'s: a
/// `tower-lsp-server` bump is a breaking change here, by construction. See the
/// "LSP type stability" section of this module's docs for detail.
///
/// Only present when the `lsp-responses` feature is enabled — see that feature's own
/// doc comment in `Cargo.toml` for what it gates and why.
pub use tower_lsp_server;
pub use ;
pub use ;
pub use ;
pub use ;
pub use EcosystemRegistry;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use string_valued_entries;
pub use ;
pub use ;
pub use ;
/// LSP-response-shaped re-exports, present only when the `lsp-responses` feature is enabled.
pub use ;
pub use MatchedSpans;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
/// Re-exported so a caller of [`yaml_scalar_string`] can name `yaml_rust2::Yaml` without
/// depending on `yaml-rust2` directly — see the "API stability" section above for the
/// semver implication of this pre-1.0 dependency coupling.
pub use yaml_rust2;
/// Re-exported so a caller of [`error::SanitizedRegistryError`]'s `From<reqwest::Error>`
/// impl can name `reqwest::Error` without depending on `reqwest` directly — see the "API
/// stability" section above for the semver implication of this pre-1.0 dependency coupling.
pub use reqwest;