-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add channel add feature on project subcommand. (#347)
Added the #254 but with the `project` prefix. So the main cli entry point stays as clean as possible. This is beneficial for future expansion.
- Loading branch information
1 parent
a09f4b9
commit 4943582
Showing
8 changed files
with
257 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use crate::environment::{load_lock_file, update_lock_file, update_prefix}; | ||
use crate::prefix::Prefix; | ||
use crate::Project; | ||
use clap::Parser; | ||
use itertools::Itertools; | ||
use miette::IntoDiagnostic; | ||
use rattler_conda_types::{Channel, ChannelConfig, Platform}; | ||
|
||
/// Adds a channel to the project file and updates the lockfile. | ||
#[derive(Parser, Debug, Default)] | ||
pub struct Args { | ||
/// The channel name or URL | ||
#[clap(required = true, num_args=1..)] | ||
pub channel: Vec<String>, | ||
|
||
/// Don't update the environment, only add changed packages to the lock-file. | ||
#[clap(long)] | ||
pub no_install: bool, | ||
} | ||
|
||
pub async fn execute(mut project: Project, args: Args) -> miette::Result<()> { | ||
// Determine which channels are missing | ||
let channel_config = ChannelConfig::default(); | ||
let channels = args | ||
.channel | ||
.into_iter() | ||
.map(|channel_str| { | ||
Channel::from_str(&channel_str, &channel_config).map(|channel| (channel_str, channel)) | ||
}) | ||
.collect::<Result<Vec<_>, _>>() | ||
.into_diagnostic()?; | ||
|
||
let missing_channels = channels | ||
.into_iter() | ||
.filter(|(_name, channel)| !project.channels().contains(channel)) | ||
.collect_vec(); | ||
|
||
if missing_channels.is_empty() { | ||
eprintln!( | ||
"{}All channel(s) have already been added.", | ||
console::style(console::Emoji("✔ ", "")).green(), | ||
); | ||
return Ok(()); | ||
} | ||
|
||
// Load the existing lock-file | ||
let lock_file = load_lock_file(&project).await?; | ||
|
||
// Add the channels to the lock-file | ||
project.add_channels(missing_channels.iter().map(|(name, _channel)| name))?; | ||
|
||
// Try to update the lock-file with the new channels | ||
let lock_file = update_lock_file(&project, lock_file, None).await?; | ||
project.save()?; | ||
|
||
// Update the installation if needed | ||
if !args.no_install { | ||
// Get the currently installed packages | ||
let prefix = Prefix::new(project.root().join(".pixi/env"))?; | ||
let installed_packages = prefix.find_installed_packages(None).await?; | ||
|
||
// Update the prefix | ||
update_prefix(&prefix, installed_packages, &lock_file, Platform::current()).await?; | ||
} | ||
|
||
// Report back to the user | ||
for (name, channel) in missing_channels { | ||
eprintln!( | ||
"{}Added {} ({})", | ||
console::style(console::Emoji("✔ ", "")).green(), | ||
name, | ||
channel.base_url() | ||
); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
pub mod add; | ||
|
||
use crate::Project; | ||
use clap::Parser; | ||
use std::path::PathBuf; | ||
|
||
/// Commands to manage project channels. | ||
#[derive(Parser, Debug)] | ||
pub struct Args { | ||
/// The path to 'pixi.toml' | ||
#[clap(long, global = true)] | ||
pub manifest_path: Option<PathBuf>, | ||
|
||
/// The subcommand to execute | ||
#[clap(subcommand)] | ||
pub command: Command, | ||
} | ||
|
||
#[derive(Parser, Debug)] | ||
pub enum Command { | ||
Add(add::Args), | ||
} | ||
|
||
pub async fn execute(args: Args) -> miette::Result<()> { | ||
let project = Project::load_or_else_discover(args.manifest_path.as_deref())?; | ||
|
||
match args.command { | ||
Command::Add(args) => add::execute(project, args).await, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use clap::Parser; | ||
use std::path::PathBuf; | ||
|
||
pub mod channel; | ||
|
||
#[derive(Debug, Parser)] | ||
pub enum Command { | ||
Channel(channel::Args), | ||
} | ||
// Modify the project configuration file through the command line. | ||
#[derive(Debug, Parser)] | ||
pub struct Args { | ||
#[command(subcommand)] | ||
command: Command, | ||
/// The path to 'pixi.toml' | ||
#[arg(long)] | ||
pub manifest_path: Option<PathBuf>, | ||
} | ||
|
||
pub async fn execute(cmd: Args) -> miette::Result<()> { | ||
match cmd.command { | ||
Command::Channel(args) => channel::execute(args).await?, | ||
}; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
mod common; | ||
|
||
use crate::{common::package_database::PackageDatabase, common::PixiControl}; | ||
use rattler_conda_types::{Channel, ChannelConfig}; | ||
use tempfile::TempDir; | ||
use url::Url; | ||
|
||
#[tokio::test] | ||
async fn add_channel() { | ||
// Create a local package database with no entries and write it to disk. This ensures that we | ||
// have a valid channel. | ||
let package_database = PackageDatabase::default(); | ||
let initial_channel_dir = TempDir::new().unwrap(); | ||
package_database | ||
.write_repodata(initial_channel_dir.path()) | ||
.await | ||
.unwrap(); | ||
|
||
// Run the init command | ||
let pixi = PixiControl::new().unwrap(); | ||
pixi.init() | ||
.with_local_channel(initial_channel_dir.path()) | ||
.await | ||
.unwrap(); | ||
|
||
// Create and add another local package directory | ||
let additional_channel_dir = TempDir::new().unwrap(); | ||
package_database | ||
.write_repodata(additional_channel_dir.path()) | ||
.await | ||
.unwrap(); | ||
pixi.project_channel_add() | ||
.with_local_channel(additional_channel_dir.path()) | ||
.await | ||
.unwrap(); | ||
|
||
// There should be a loadable project manifest in the directory | ||
let project = pixi.project().unwrap(); | ||
|
||
// Our channel should be in the list of channels | ||
let local_channel = Channel::from_str( | ||
Url::from_directory_path(additional_channel_dir.path()) | ||
.unwrap() | ||
.to_string(), | ||
&ChannelConfig::default(), | ||
) | ||
.unwrap(); | ||
assert!(project.channels().contains(&local_channel)); | ||
} |