Skip to main content

wdl_modules/
resolver.rs

1//! Public resolver API.
2//!
3//! The trait definitions (`Resolver`, `ResolverError`, `MaterializedFile`,
4//! etc.) are always available. The Git-backed implementation and supporting
5//! infrastructure (cache, config, fetch, lock, trust, etc.) are gated
6//! behind the `resolver` cargo feature so that consumers like `wdl-doc`
7//! that only need the manifest/lockfile/hashing types do not pay for
8//! `git2` and friends.
9
10#[cfg(feature = "git-resolver")]
11pub(crate) mod cache;
12#[cfg(feature = "git-resolver")]
13pub(crate) mod config;
14pub(crate) mod error;
15#[cfg(feature = "git-resolver")]
16pub(crate) mod fetch;
17#[cfg(feature = "git-resolver")]
18mod git;
19#[cfg(feature = "git-resolver")]
20pub mod lock;
21#[cfg(feature = "git-resolver")]
22pub(crate) mod policy;
23pub(crate) mod scope;
24#[cfg(feature = "git-resolver")]
25pub(crate) mod trust;
26pub(crate) mod types;
27#[cfg(feature = "git-resolver")]
28pub(crate) mod verify;
29#[cfg(feature = "git-resolver")]
30pub(crate) mod versions;
31
32use async_trait::async_trait;
33use semver::Version;
34
35use crate::dependency::DependencyName;
36use crate::dependency::DependencySource;
37use crate::module::Module;
38#[cfg(feature = "git-resolver")]
39pub use crate::resolver::config::GitPlatform;
40#[cfg(feature = "git-resolver")]
41pub use crate::resolver::config::LargeFileWarning;
42#[cfg(feature = "git-resolver")]
43pub use crate::resolver::config::LargeFileWarningError;
44#[cfg(feature = "git-resolver")]
45pub use crate::resolver::config::ModulesConfig;
46#[cfg(feature = "git-resolver")]
47pub use crate::resolver::config::TransferLimit;
48#[cfg(feature = "git-resolver")]
49pub use crate::resolver::config::TransferLimitError;
50#[cfg(feature = "git-resolver")]
51pub use crate::resolver::config::TrustMode;
52#[cfg(feature = "git-resolver")]
53pub use crate::resolver::error::GitRefKind;
54pub use crate::resolver::error::MissingFileKind;
55pub use crate::resolver::error::ResolverError;
56#[cfg(feature = "git-resolver")]
57pub use crate::resolver::git::CacheCleanStats;
58#[cfg(feature = "git-resolver")]
59pub use crate::resolver::git::GitResolver;
60#[cfg(feature = "git-resolver")]
61pub use crate::resolver::git::GitResolverBuilder;
62#[cfg(feature = "git-resolver")]
63pub use crate::resolver::git::VerifyLockedReport;
64#[cfg(feature = "git-resolver")]
65pub use crate::resolver::policy::ResolverPolicy;
66pub use crate::resolver::scope::DependencyScope;
67#[cfg(feature = "git-resolver")]
68pub use crate::resolver::trust::TrustStore;
69#[cfg(feature = "git-resolver")]
70pub use crate::resolver::trust::TrustStoreError;
71#[cfg(feature = "git-resolver")]
72pub use crate::resolver::trust::TrustedIdentity;
73pub use crate::resolver::types::MaterializedFile;
74pub use crate::resolver::types::ResolvedDependency;
75pub use crate::resolver::types::ResolvedModule;
76pub use crate::resolver::types::ResolvedTree;
77use crate::symbolic_path::SymbolicPath;
78
79/// Resolves WDL module imports to concrete files on disk.
80#[async_trait]
81pub trait Resolver: std::fmt::Debug + Send + Sync {
82    /// Materializes a single symbolic import on disk and returns the path
83    /// to the resulting file.
84    ///
85    /// The primary call site for `wdl-analysis`. When the analyzer
86    /// encounters a symbolic import like `import openwdl/csvkit/cut`, it
87    /// asks the resolver for the file path that statement should route
88    /// to, then parses the result with the existing import machinery as
89    /// if the user had written `import "<that path>"`.
90    ///
91    /// `consumer` is the importing module: its manifest declares the
92    /// symbolic path's head component, and its root rebases any
93    /// relative `LocalPath` dependencies. `path` is the parsed
94    /// symbolic path. The resolver looks up the head component in
95    /// `consumer.manifest.dependencies`, materializes the dep's module
96    /// folder if not yet cached, and resolves either the manifest's
97    /// `entrypoint` (when the symbolic path has no sub-path) or
98    /// `<sub-path>.wdl` under the module folder.
99    async fn materialize(
100        &self,
101        consumer: &Module,
102        path: &SymbolicPath,
103    ) -> Result<MaterializedFile, ResolverError>;
104
105    /// Resolves every transitive dependency declared by `consumer`.
106    ///
107    /// Walks `consumer.manifest.dependencies`, recurses into each dep's
108    /// own manifest, and records every module visited along the way.
109    /// Relative `LocalPath` entries are resolved against the declaring
110    /// module's root. Detects cycles.
111    async fn resolve_tree(&self, consumer: &Module) -> Result<ResolvedTree, ResolverError>;
112
113    /// Lists discovered versions for a dependency source that satisfy
114    /// the requirement, in descending semver order.
115    ///
116    /// Used by CLI commands that surface available versions to the user
117    /// and internally by `resolve_tree` to select the version a Git dep
118    /// resolves to.
119    async fn discover_versions(
120        &self,
121        name: &DependencyName,
122        source: &DependencySource,
123        scope: DependencyScope,
124    ) -> Result<Vec<Version>, ResolverError>;
125}