Skip to content

Commit daefb03

Browse files
rebase stuff
1 parent 52201b0 commit daefb03

File tree

4 files changed

+174
-178
lines changed

4 files changed

+174
-178
lines changed

crates/pixi_cli/src/global/update.rs

Lines changed: 7 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ use pixi_config::{Config, ConfigCli};
55
use pixi_global::StateChanges;
66
use pixi_global::common::{EnvironmentUpdate, InstallChange, check_all_exposed};
77
use pixi_global::project::ExposedType;
8-
use pixi_global::{EnvironmentName, Project};
8+
use pixi_global::{EnvironmentName, Project, StateChange};
99
use serde::Serialize;
10-
use std::collections::HashMap;
1110

1211
/// Updates environments in the global environment.
1312
#[derive(Parser, Debug, Clone)]
@@ -129,10 +128,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {
129128
project: &mut Project,
130129
dry_run: bool,
131130
json_output: bool,
132-
) -> miette::Result<(
133-
StateChanges,
134-
Option<EnvironmentUpdate>,
135-
)> {
131+
) -> miette::Result<(StateChanges, Option<EnvironmentUpdate>)> {
136132
let mut state_changes = StateChanges::default();
137133

138134
let should_check_for_updates = true;
@@ -165,22 +161,22 @@ pub async fn execute(args: Args) -> miette::Result<()> {
165161
if should_check_for_updates {
166162
if dry_run || json_output {
167163
// dry-run mode: performs solving only
168-
let environment_update = solve_for_dry_run(project, env_name).await?;
164+
let environment_update = project.solve_for_dry_run(env_name).await?;
169165

170166
// Only add to state changes if there are actual changes
171167
if !environment_update.is_empty() {
172168
dry_run_environment_update = Some(environment_update.clone());
173169
state_changes.insert_change(
174170
env_name,
175-
global::StateChange::UpdatedEnvironment(environment_update),
171+
StateChange::UpdatedEnvironment(environment_update),
176172
);
177173
}
178174
} else {
179175
// Normal mode: actually install
180176
let environment_update = project.install_environment(env_name).await?;
181177
state_changes.insert_change(
182178
env_name,
183-
global::StateChange::UpdatedEnvironment(environment_update),
179+
StateChange::UpdatedEnvironment(environment_update),
184180
);
185181
}
186182
}
@@ -208,171 +204,6 @@ pub async fn execute(args: Args) -> miette::Result<()> {
208204
Ok((state_changes, dry_run_environment_update))
209205
}
210206

211-
/// Performs only the solving step to determine what would change in dry-run mode
212-
/// This extracts the solving logic from install_environment without the installation
213-
async fn solve_for_dry_run(
214-
project: &Project,
215-
env_name: &EnvironmentName,
216-
) -> miette::Result<crate::global::common::EnvironmentUpdate> {
217-
use crate::global::common::{EnvironmentUpdate, InstallChange};
218-
use miette::{IntoDiagnostic, WrapErr};
219-
use pixi_command_dispatcher::{BuildEnvironment, PixiEnvironmentSpec};
220-
use pixi_spec_containers::DependencyMap;
221-
use rattler_conda_types::{GenericVirtualPackage, Platform};
222-
use rattler_virtual_packages::{VirtualPackage, VirtualPackageOverrides};
223-
224-
let environment = project
225-
.environment(env_name)
226-
.ok_or_else(|| miette::miette!("Environment {} not found", env_name.fancy_display()))?;
227-
228-
let channels = environment
229-
.channels()
230-
.into_iter()
231-
.map(|channel| {
232-
channel
233-
.clone()
234-
.into_channel(project.global_channel_config())
235-
})
236-
.collect::<Result<Vec<_>, _>>()
237-
.into_diagnostic()?;
238-
239-
let platform = environment.platform.unwrap_or_else(Platform::current);
240-
241-
// For update operations, use "*" (any version) to find latest available packages
242-
let mut pixi_specs = DependencyMap::default();
243-
let mut dependencies_names = Vec::new();
244-
245-
for (name, _spec) in &environment.dependencies.specs {
246-
let any_version_spec = pixi_spec::PixiSpec::default();
247-
pixi_specs.insert(name.clone(), any_version_spec);
248-
dependencies_names.push(name.clone());
249-
}
250-
251-
let command_dispatcher = project.command_dispatcher().map_err(|e| {
252-
miette::miette!(
253-
"Cannot access command dispatcher for dry-run solving: {}",
254-
e
255-
)
256-
})?;
257-
258-
let virtual_packages = if platform
259-
.only_platform()
260-
.map(|p| p == Platform::current().only_platform().unwrap_or(""))
261-
.unwrap_or(false)
262-
{
263-
VirtualPackage::detect(&VirtualPackageOverrides::default())
264-
.into_diagnostic()
265-
.wrap_err(format!(
266-
"Failed to determine virtual packages for environment {}",
267-
env_name.fancy_display()
268-
))?
269-
.iter()
270-
.cloned()
271-
.map(GenericVirtualPackage::from)
272-
.collect()
273-
} else {
274-
vec![]
275-
};
276-
277-
let channels = channels
278-
.into_iter()
279-
.map(|channel| channel.base_url.clone())
280-
.collect::<Vec<_>>();
281-
282-
let build_environment = BuildEnvironment::simple(platform, virtual_packages);
283-
let solve_spec = PixiEnvironmentSpec {
284-
name: Some(env_name.to_string()),
285-
dependencies: pixi_specs,
286-
build_environment: build_environment.clone(),
287-
channels: channels.clone(),
288-
channel_config: project.global_channel_config().clone(),
289-
..Default::default()
290-
};
291-
292-
// SOLVE ONLY
293-
let pixi_records = command_dispatcher
294-
.solve_pixi_environment(solve_spec)
295-
.await?;
296-
297-
// Compare with current installed packages to detect changes
298-
let prefix = project.environment_prefix(env_name).await?;
299-
let current_records = prefix.find_installed_packages().unwrap_or_default();
300-
301-
// Calculate what would change
302-
let install_changes = if current_records.is_empty() && !pixi_records.is_empty() {
303-
// Environment doesn't exist yet
304-
pixi_records
305-
.into_iter()
306-
.map(|record| {
307-
(
308-
record.package_record().name.clone(),
309-
InstallChange::Installed(record.package_record().version.clone().into()),
310-
)
311-
})
312-
.collect()
313-
} else {
314-
// Compare current vs solved packages
315-
let current_packages: HashMap<_, _> = current_records
316-
.iter()
317-
.map(|r| {
318-
(
319-
r.repodata_record.package_record.name.clone(),
320-
&r.repodata_record.package_record.version,
321-
)
322-
})
323-
.collect();
324-
325-
let mut changes = HashMap::new();
326-
327-
// Check for upgrades and new packages
328-
for record in &pixi_records {
329-
let name = &record.package_record().name;
330-
let new_version = &record.package_record().version;
331-
332-
if let Some(current_version) = current_packages.get(name) {
333-
let current_version_converted: rattler_conda_types::Version =
334-
(*current_version).clone().into();
335-
let new_version_converted: rattler_conda_types::Version =
336-
new_version.clone().into();
337-
if current_version_converted != new_version_converted {
338-
changes.insert(
339-
name.clone(),
340-
InstallChange::Upgraded(
341-
current_version_converted,
342-
new_version_converted,
343-
),
344-
);
345-
}
346-
} else {
347-
changes.insert(
348-
name.clone(),
349-
InstallChange::Installed(new_version.clone().into()),
350-
);
351-
}
352-
}
353-
354-
// Check for removed packages
355-
for (name, _version) in current_packages {
356-
if !pixi_records.iter().any(|r| r.package_record().name == name) {
357-
changes.insert(name.clone(), InstallChange::Removed);
358-
}
359-
}
360-
361-
changes
362-
};
363-
364-
// Filter to only include changes to top-level dependencies (packages user explicitly installed)
365-
let filtered_changes: HashMap<_, _> = install_changes
366-
.into_iter()
367-
.filter(|(package_name, _change)| {
368-
// Only keep changes for packages that are in the user's dependency list
369-
dependencies_names.contains(package_name)
370-
})
371-
.collect();
372-
373-
Ok(EnvironmentUpdate::new(filtered_changes, dependencies_names))
374-
}
375-
376207
// Update all environments if the user did not specify any
377208
let env_names = match args.environments {
378209
Some(env_names) => env_names,
@@ -383,7 +214,8 @@ pub async fn execute(args: Args) -> miette::Result<()> {
383214
state_changes.report();
384215
#[cfg(unix)]
385216
{
386-
let completions_dir = global::completions::CompletionsDir::from_env().await?;
217+
let completions_dir =
218+
pixi_global::completions::CompletionsDir::from_env().await?;
387219
completions_dir.prune_old_completions()?;
388220
}
389221
}

crates/pixi_global/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ pub enum StateChange {
383383

384384
#[must_use]
385385
#[derive(Debug, Default, Clone)]
386-
pub(crate) struct StateChanges {
386+
pub struct StateChanges {
387387
changes: HashMap<EnvironmentName, Vec<StateChange>>,
388388
}
389389

0 commit comments

Comments
 (0)