Skip to content

Commit dd8cf64

Browse files
committed
refactor(core): remove local_version from specifier
1 parent 1e02b23 commit dd8cf64

60 files changed

Lines changed: 8483 additions & 859 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rustfmt.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
comment_width = 140
12
group_imports = "One"
23
imports_granularity = "One"
34
max_width = 140

src/commands/ui/dependency.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,6 @@ fn get_raw_expected_specifier(dependency: &Dependency) -> String {
177177
.expected
178178
.borrow()
179179
.as_ref()
180-
.map(|expected| expected.get_raw())
180+
.map(|expected| expected.get_raw().to_string())
181181
.unwrap_or_default()
182182
}

src/commands/ui/instance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub fn get_actual(instance: &Instance) -> String {
117117
if actual.is_empty() {
118118
"VERSION_IS_MISSING".yellow().to_string()
119119
} else {
120-
actual
120+
actual.to_string()
121121
}
122122
}
123123

@@ -130,7 +130,7 @@ fn get_local_hint(ctx: &Context, instance: &Instance) -> String {
130130
}
131131

132132
pub fn get_expected(instance: &Instance) -> String {
133-
instance.expected_specifier.borrow().as_ref().unwrap().get_raw()
133+
instance.expected_specifier.borrow().as_ref().unwrap().get_raw().to_string()
134134
}
135135

136136
pub fn get_location(ctx: &Context, instance: &Instance) -> String {

src/context.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub struct Context {
5050
pub registry_client: Option<Arc<dyn RegistryClient>>,
5151
/// All updates from the npm registry which have been chosen either by the
5252
/// user via a prompt or automatically by choosing the latest version
53-
pub updates_by_internal_name: HashMap<String, Vec<Specifier>>,
53+
pub updates_by_internal_name: HashMap<String, Vec<Rc<Specifier>>>,
5454
/// All version groups, their dependencies, and their instances
5555
pub version_groups: Vec<VersionGroup>,
5656
}
@@ -128,7 +128,7 @@ impl Context {
128128
let semaphore = Arc::new(Semaphore::new(self.config.rcfile.max_concurrent_requests));
129129
let progress_bars = Arc::new(MultiProgress::new());
130130
let mut handles: Vec<(String, JoinHandle<Result<AllPackageVersions, RegistryError>>)> = vec![];
131-
let mut all_updates_by_internal_name: HashMap<String, Vec<Specifier>> = HashMap::new();
131+
let mut all_updates_by_internal_name: HashMap<String, Vec<Rc<Specifier>>> = HashMap::new();
132132
let mut failed_updates: Vec<String> = vec![];
133133

134134
for update_url in self.get_unique_update_urls() {
@@ -159,7 +159,7 @@ impl Context {
159159
let all_updates = all_updates_by_internal_name.entry(internal_name.clone()).or_default();
160160
for version in package_meta.versions.iter() {
161161
if !version.contains("created") && !version.contains("modified") {
162-
all_updates.push(Specifier::new(version, None));
162+
all_updates.push(Specifier::new(version));
163163
}
164164
}
165165
}

src/dependency.rs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,7 @@
1212
1313
use {
1414
crate::{
15-
context::Context,
16-
instance::Instance,
17-
instance_state::InstanceState,
18-
package_json::PackageJson,
19-
specifier::{semver_range::SemverRange, Specifier},
15+
context::Context, instance::Instance, instance_state::InstanceState, package_json::PackageJson, specifier::Specifier,
2016
version_group::VersionGroupVariant,
2117
},
2218
itertools::Itertools,
@@ -49,7 +45,7 @@ pub struct Dependency {
4945
/// The expected version specifier which all instances of this dependency
5046
/// should be set to, in the event that they should all use the same version.
5147
/// RefCell allows mutation during inspection without &mut Context.
52-
pub expected: RefCell<Option<Specifier>>,
48+
pub expected: RefCell<Option<Rc<Specifier>>>,
5349
/// Whether the internal name for this dependency is an alias.
5450
pub has_alias: bool,
5551
/// Every instance of this dependency in this version group.
@@ -63,7 +59,7 @@ pub struct Dependency {
6359
/// The name of the dependency, e.g., "react", "@types/node"
6460
pub internal_name: String,
6561
/// The version to pin all instances to when variant is `Pinned`
66-
pub pinned_specifier: Option<Specifier>,
62+
pub pinned_specifier: Option<Rc<Specifier>>,
6763
/// package.json files developed in the monorepo when variant is `SnappedTo`.
6864
/// Rc<RefCell<T>> for shared ownership with interior mutability.
6965
pub snapped_to_packages: Option<Vec<Rc<RefCell<PackageJson>>>>,
@@ -76,7 +72,7 @@ impl Dependency {
7672
pub fn new(
7773
internal_name: String,
7874
variant: VersionGroupVariant,
79-
pinned_specifier: Option<Specifier>,
75+
pinned_specifier: Option<Rc<Specifier>>,
8076
snapped_to_packages: Option<Vec<Rc<RefCell<PackageJson>>>>,
8177
) -> Dependency {
8278
Dependency {
@@ -125,18 +121,18 @@ impl Dependency {
125121
}
126122

127123
/// Set the expected version specifier to the given value
128-
pub fn set_expected_specifier(&self, specifier: &Specifier) -> &Self {
129-
*self.expected.borrow_mut() = Some(specifier.clone());
124+
pub fn set_expected_specifier(&self, specifier: &Rc<Specifier>) -> &Self {
125+
*self.expected.borrow_mut() = Some(Rc::clone(specifier));
130126
self
131127
}
132128

133129
/// Return the local instance's version specifier, if it exists
134-
pub fn get_local_specifier(&self) -> Option<Specifier> {
130+
pub fn get_local_specifier(&self) -> Option<Rc<Specifier>> {
135131
self
136132
.local_instance
137133
.borrow()
138134
.as_ref()
139-
.map(|instance| instance.descriptor.specifier.clone())
135+
.map(|instance| Rc::clone(&instance.descriptor.specifier))
140136
}
141137

142138
/// Whether the dependency name is a valid npm package name, is invalid, or
@@ -157,43 +153,42 @@ impl Dependency {
157153
/// Is this dependency a package developed in this repository, which has a
158154
/// missing or invalid .version property?
159155
pub fn has_local_instance_with_invalid_specifier(&self) -> bool {
160-
self.get_local_specifier().is_some_and(|local| {
161-
if let Specifier::BasicSemver(semver) = local {
162-
!matches!(semver.range_variant, SemverRange::Exact)
163-
} else {
164-
true
165-
}
166-
})
156+
self
157+
.get_local_specifier()
158+
.is_some_and(|local| !matches!(&*local, Specifier::Exact(_)))
167159
}
168160

169161
/// Does every instance in this group have a specifier which is exactly the
170162
/// same?
171163
pub fn every_specifier_is_already_identical(&self) -> bool {
172164
if let Some(first_actual) = self.instances.first().map(|instance| &instance.descriptor.specifier) {
173-
self.instances.iter().all(|instance| instance.descriptor.specifier == *first_actual)
165+
self.instances.iter().all(|instance| {
166+
Rc::ptr_eq(&instance.descriptor.specifier, first_actual) || instance.descriptor.specifier.get_raw() == first_actual.get_raw()
167+
})
174168
} else {
175169
false
176170
}
177171
}
178172

179-
pub fn get_unique_specifiers(&self) -> Vec<Specifier> {
173+
pub fn get_unique_specifiers(&self) -> Vec<Rc<Specifier>> {
180174
let mut unique_specifiers = Vec::new();
181175
for instance in self.instances.iter() {
182-
if !unique_specifiers.contains(&instance.descriptor.specifier) {
183-
unique_specifiers.push(instance.descriptor.specifier.clone());
176+
let spec = &instance.descriptor.specifier;
177+
if !unique_specifiers.iter().any(|s: &Rc<Specifier>| s.get_raw() == spec.get_raw()) {
178+
unique_specifiers.push(Rc::clone(spec));
184179
}
185180
}
186181
unique_specifiers
187182
}
188183

189184
/// Get the highest (or lowest) semver specifier in this group.
190-
pub fn get_highest_or_lowest_specifier(&self) -> Option<Specifier> {
185+
pub fn get_highest_or_lowest_specifier(&self) -> Option<Rc<Specifier>> {
191186
let prefer_highest = matches!(self.variant, VersionGroupVariant::HighestSemver);
192187
let preferred_order = if prefer_highest { Ordering::Greater } else { Ordering::Less };
193188
self
194189
.get_instances()
195190
.filter(|instance| instance.descriptor.specifier.get_node_version().is_some())
196-
.map(|instance| instance.descriptor.specifier.clone())
191+
.map(|instance| Rc::clone(&instance.descriptor.specifier))
197192
.fold(None, |preferred, specifier| match preferred {
198193
None => Some(specifier),
199194
Some(preferred) => {
@@ -214,9 +209,9 @@ impl Dependency {
214209
///
215210
/// When only applying eg. patch updates, some specifiers will be assigned to
216211
/// different updates if they are not on the same minor version.
217-
pub fn get_eligible_registry_updates(&self, ctx: &Context) -> Option<HashMap<Specifier, Vec<Specifier>>> {
212+
pub fn get_eligible_registry_updates(&self, ctx: &Context) -> Option<HashMap<String, Vec<Rc<Specifier>>>> {
218213
ctx.updates_by_internal_name.get(&self.internal_name).map(|updates| {
219-
let mut specifiers_by_eligible_update: HashMap<Specifier, Vec<Specifier>> = HashMap::new();
214+
let mut specifiers_by_eligible_update: HashMap<String, Vec<Rc<Specifier>>> = HashMap::new();
220215
self.get_unique_specifiers().iter().for_each(|installed| {
221216
updates
222217
.iter()
@@ -234,8 +229,9 @@ impl Dependency {
234229
}
235230
})
236231
.inspect(|highest_update| {
237-
let affected = specifiers_by_eligible_update.entry((*highest_update).clone()).or_default();
238-
affected.push(installed.clone());
232+
let key = highest_update.get_raw().to_string();
233+
let affected = specifiers_by_eligible_update.entry(key).or_default();
234+
affected.push(Rc::clone(installed));
239235
});
240236
});
241237
specifiers_by_eligible_update
@@ -250,13 +246,13 @@ impl Dependency {
250246
///
251247
/// Even though the actual specifiers on disk might currently match, we should
252248
/// suggest it match what we the snapped to specifier should be once fixed
253-
pub fn get_snapped_to_specifier(&self, every_instance_in_the_project: &[Rc<Instance>]) -> Option<Specifier> {
249+
pub fn get_snapped_to_specifier(&self, every_instance_in_the_project: &[Rc<Instance>]) -> Option<Rc<Specifier>> {
254250
if let Some(snapped_to_packages) = &self.snapped_to_packages {
255251
for instance in every_instance_in_the_project {
256252
if *instance.descriptor.internal_name == *self.internal_name {
257253
for snapped_to_package in snapped_to_packages {
258254
if instance.descriptor.package.borrow().name == snapped_to_package.borrow().name {
259-
return Some(instance.descriptor.specifier.clone());
255+
return Some(Rc::clone(&instance.descriptor.specifier));
260256
}
261257
}
262258
}

src/group_selector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl GroupSelector {
152152
#[inline]
153153
fn matches_specifier_types(&self, descriptor: &InstanceDescriptor) -> bool {
154154
matches_identifiers(
155-
&descriptor.specifier.get_config_identifier(),
155+
descriptor.specifier.get_config_identifier(),
156156
&self.include_specifier_types,
157157
&self.exclude_specifier_types,
158158
)

0 commit comments

Comments
 (0)