Skip to content

Commit 6b2ef7d

Browse files
committed
Refactor resolution controller
1 parent c1746fb commit 6b2ef7d

File tree

2 files changed

+73
-40
lines changed

2 files changed

+73
-40
lines changed

compiler-cli/src/dependencies.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ fn get_manifest_details(paths: &ProjectPaths) -> Result<(PackageConfig, Manifest
104104
cli::Reporter::new(),
105105
Mode::Dev,
106106
);
107-
let (_, manifest) = dependency_manager.get_manifest(paths, &config, Vec::new())?;
107+
let manifest = dependency_manager
108+
.resolve_versions(paths, &config, Vec::new())?
109+
.manifest;
108110
Ok((config, manifest))
109111
}
110112

compiler-cli/src/dependencies/dependency_manager.rs

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,23 @@ impl DependencyManagerConfig {
5454
}
5555
}
5656

57+
pub struct Resolved {
58+
pub manifest: Manifest,
59+
pub versions_changed: bool,
60+
}
61+
62+
impl Resolved {
63+
/// Create a `Resolved`, comparing the old and new versions of the manifest to work out
64+
/// if resolution resulted in any changes.
65+
pub fn with_updates(old: &Manifest, new: Manifest) -> Self {
66+
let versions_changed = old.packages != new.packages;
67+
Self {
68+
manifest: new,
69+
versions_changed,
70+
}
71+
}
72+
}
73+
5774
pub struct DependencyManager<Telem, P> {
5875
runtime: tokio::runtime::Handle,
5976
package_fetcher: P,
@@ -68,50 +85,61 @@ where
6885
P: dependency::PackageFetcher,
6986
Telem: Telemetry,
7087
{
71-
pub fn get_manifest(
88+
/// Resolve the dependency versions used by a package.
89+
///
90+
/// If the `use_manifest` configuration was set to `false` then it'll always resolve all the
91+
/// versions, even if there are already versions locked in the manifest.
92+
pub fn resolve_versions(
7293
&self,
7394
paths: &ProjectPaths,
7495
config: &PackageConfig,
7596
packages_to_update: Vec<EcoString>,
76-
) -> Result<(bool, Manifest)> {
77-
// If there's no manifest (or we have been asked not to use it) then resolve
78-
// the versions anew
79-
let should_resolve = match self.use_manifest {
80-
_ if !paths.manifest().exists() => {
81-
tracing::debug!("manifest_not_present");
82-
true
83-
}
84-
UseManifest::No => {
85-
tracing::debug!("ignoring_manifest");
86-
true
97+
) -> Result<Resolved> {
98+
// If there's no manifest then the only thing we can do is attempt to update the versions.
99+
if !paths.manifest().exists() {
100+
tracing::debug!("manifest_not_present");
101+
let manifest = self.perform_version_resolution(paths, config, None, Vec::new())?;
102+
return Ok(Resolved {
103+
manifest,
104+
versions_changed: true,
105+
});
106+
}
107+
108+
let existing_manifest = read_manifest_from_disc(paths)?;
109+
110+
// If we have been asked not to use the manifest then
111+
let manifest_for_resolver = match self.use_manifest {
112+
UseManifest::No => None,
113+
UseManifest::Yes => {
114+
// If the manifest is to be used and the requirements have not changed then there's
115+
// no point in performing resolution, it'll always result in the same versions
116+
// already specified in the manifest.
117+
if packages_to_update.is_empty()
118+
&& is_same_requirements(
119+
&existing_manifest.requirements,
120+
&config.all_direct_dependencies()?,
121+
paths.root(),
122+
)?
123+
{
124+
return Ok(Resolved {
125+
manifest: existing_manifest,
126+
versions_changed: false,
127+
});
128+
}
129+
130+
// Otherwise, use the manifest to inform resolution.
131+
Some(&existing_manifest)
87132
}
88-
UseManifest::Yes => false,
89133
};
90134

91-
if should_resolve {
92-
let manifest = self.resolve_versions(paths, config, None, Vec::new())?;
93-
return Ok((true, manifest));
94-
}
95-
96-
let manifest = read_manifest_from_disc(paths)?;
97-
98-
// If there are no requested updates, and the config is unchanged
99-
// since the manifest was written then it is up to date so we can return it unmodified.
100-
if packages_to_update.is_empty()
101-
&& is_same_requirements(
102-
&manifest.requirements,
103-
&config.all_direct_dependencies()?,
104-
paths.root(),
105-
)?
106-
{
107-
tracing::debug!("manifest_up_to_date");
108-
Ok((false, manifest))
109-
} else {
110-
tracing::debug!("manifest_outdated");
111-
let manifest =
112-
self.resolve_versions(paths, config, Some(&manifest), packages_to_update)?;
113-
Ok((true, manifest))
114-
}
135+
tracing::debug!("manifest_outdated");
136+
let new_manifest = self.perform_version_resolution(
137+
paths,
138+
config,
139+
manifest_for_resolver,
140+
packages_to_update,
141+
)?;
142+
Ok(Resolved::with_updates(&existing_manifest, new_manifest))
115143
}
116144

117145
pub fn download(
@@ -148,7 +176,10 @@ where
148176
}
149177

150178
// Determine what versions we need
151-
let (manifest_updated, manifest) = self.get_manifest(paths, &config, packages_to_update)?;
179+
let Resolved {
180+
manifest,
181+
versions_changed: manifest_updated,
182+
} = self.resolve_versions(paths, &config, packages_to_update)?;
152183
let local = LocalPackages::read_from_disc(paths)?;
153184

154185
// Remove any packages that are no longer required due to gleam.toml changes
@@ -186,7 +217,7 @@ where
186217
Ok(manifest)
187218
}
188219

189-
fn resolve_versions(
220+
fn perform_version_resolution(
190221
&self,
191222
project_paths: &ProjectPaths,
192223
config: &PackageConfig,

0 commit comments

Comments
 (0)