deps-core
Core abstractions for deps-lsp: traits, caching, and generic LSP handlers.
This crate provides the shared infrastructure used by all ecosystem-specific crates in the deps-lsp workspace. Every ecosystem crate depends on deps-core and implements its Ecosystem trait.
What this crate provides
Ecosystemtrait — Unified interface for all package ecosystems (parse, registry, format)EcosystemIdenum — Exhaustive, typed identifier for every registered ecosystem, withDisplay/FromStrinterop withEcosystem::id(). Downstream code should match on this instead of the raw id string so a new ecosystem forces every relevantmatchto be updated at compile timePackageName/VersionReqnewtypes — Distinguish a manifest package name from a version requirement string at the type level, threaded throughRegistry,Ecosystem, andEcosystemFormatterso the two cannot be swapped at a call siteRegistrytrait — Abstraction over package registries with version lookupfreshnessmodule — Release-freshness signal (PublishTime,FreshnessSettings,is_within_cooldown) flagging a "latest" version still inside its cooldown window, mirroring GitHub Dependabot's default 3-day package cooldowneditmodule —ManifestEdit,PlannedUpdate,UpdateKind/classify_update,collect_update_edits, andplan_vulnerability_fix: the edit planning shared bydeps-lsp's code actions/lenses anddeps-cli update, including the cooldown-fallback guard (lsp_helpers::fallback_edit_excludes_newer) that decides whether a fallback edit is safe to writefs_probe::write_atomic— symlink-refusing, permission-preserving atomic file writeconfig_trustmodule — sharedConfigTier/expand_env_varsconfig-trust-tier and${VAR}/%VAR%interpolation logicinterval::VersionRange,lsp_helpers::BoundedVersionReqandMatchedSpans— shared bounded-interval requirement matching and oversized-requirement gating, so every ecosystem rejects unsatisfiable or pathological ranges the same waypolicy_config::{GossipConfig, TyposquatConfig}— opt-in deps.dev GOSSIP-signal and typosquat-similarity settings (both default off)LockFileProvidertrait — Abstract lock file parsing for resolved versions- Generic LSP handlers —
generate_inlay_hints,generate_hover,generate_code_actions,generate_diagnostics_from_cache,generate_code_lenses, taking a bundledVersionData(cached + resolved version maps) to avoid swapping same-typed arguments at call sites collect_update_all_edits— batchTextEdits bringing every safely-editable outdated dependency to latest, shared across all ecosystems; guards against rewriting aversion_rangethat isn't actually the version literal (property references, DSL variables, catalog aliases, synthesized range bounds)HttpCache— ETag/Last-Modified caching for registry HTTP requests, with a streaming 32 MiB response-size caposv::OsvClient— batches dependency versions against the OSV.dev vulnerability database (POST /v1/querybatch), resolves matching advisories (bounded record-fetch concurrency, in-flight dedup, GitHub Actions advisories matched locally by canonical name), and caches both queries and records independently ofHttpCache(OSV sends no cache validators).EcosystemId::osv_ecosystem()andEcosystemFormatter::osv_package_name()provide the per-ecosystem mappingcheck_toml_nesting_depth— single-pass structural guard rejecting pathologically nested TOML (bracket depth and dotted-key/header segment count) before it reaches the recursive-descenttoml_spanparserparse_toml_checked— the single shared entry point combiningcheck_toml_nesting_depthwithtoml_span::parse, returning aCheckedTomlError(NestingTooDeep/Syntax) callers can branch oncheck_yaml_nesting_depth— single-pass structural guard rejecting pathologically nested YAML (flow bracket depth and block-style indentation/dash-chain nesting) before it reaches the recursive-descentyaml-rust2parsercheck_yaml_expansion— streaming pre-pass overyaml-rust2's own parser event stream rejecting YAML whose anchor/alias references would expand to an excessive number of allocated bytes (billion-laughs-style), independent of nesting depthlockfile::read_lockfile_content— shared read-and-error-wrap helper for lock file parsersdeps_dev::DepsDevClient— deps.dev client for typosquat-similarity and GOSSIP cooldown/low-usage findings, plus the supply-chain trust signal, resolving a dependency's linked source repository, OpenSSF Scorecard score, and SLSA/attestation provenance status (SupplyChainTrustSignal,ScorecardSummary,ProvenanceStatus)licenses::LicensePolicy— SPDX allow/deny-list evaluation shared by every ecosystem'slicense_policydiagnostic, plusEcosystem::fetch_license/license_source()sealed-trait hooks for tier-3 ecosystems whose license isn't already present in the hot-path registry responsediagnostic::Diagnostic/RelatedInformation— sanitize and cap their message/code text at construction (control characters, bidi/invisible-character overrides, unbounded length), exposed only throughmessage()/code()getters so no caller can bypass the sanitization after the factredact::url_for_tracing/RedactedUrl— masks credentials and token-shaped host/path segments (GitLab job tokens, base64url and marker-gated hex tokens) in tracing output;PackageName::for_tracing()sweeps control characters (CWE-117)redact::redact_parse_error_for_log— redacts credential-shaped substrings from a parser error before it reaches logs or an LSP-visible diagnosticrate_limit::RateLimitGate— process-lifetime cooldown gate shared by ecosystem registry clients to stop hammering an upstream once it has rate-limited or auth-rejected a request- Error types — Unified error handling with
thiserror
Installation
[]
= "2.0"
[!IMPORTANT] Requires Rust 1.98 or later.
Implementing a new ecosystem
use ;
Versioning
deps-core's public trait signatures (Ecosystem, Dependency, ParseResult,
EcosystemFormatter) — and its public lsp_helpers / completion helper functions —
are typed directly against tower_lsp_server::ls_types types. 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 deps-core 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.
If you implement Ecosystem outside this workspace, depend on the exact matching
tower-lsp-server version via deps_core::tower_lsp_server rather than adding your own
separate direct dependency on tower-lsp-server, to avoid it drifting out of sync with the
version deps-core was built against.