-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
209 additions
and
93 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,97 @@ | ||
use std::io; | ||
|
||
use clap::Args; | ||
use eyre::{eyre, Result}; | ||
use itertools::Itertools; | ||
use eyre::{Context, OptionExt, Result}; | ||
use lux_lib::{ | ||
config::{Config, LuaVersion}, | ||
operations, | ||
package::PackageReq, | ||
tree::RockMatches, | ||
config::Config, luarocks::luarocks_installation::LuaRocksInstallation, operations::Sync, | ||
package::PackageName, progress::MultiProgress, project::Project, rockspec::Rockspec, | ||
}; | ||
|
||
// NOTE: This is currently functionally equivalent | ||
// to `lux uninstall`, but that will change | ||
// when we can use it to edit projects' lux.toml files. | ||
|
||
#[derive(Args)] | ||
pub struct Remove { | ||
/// The package or packages to remove. | ||
packages: Vec<PackageReq>, | ||
} | ||
|
||
pub async fn remove(remove_args: Remove, config: Config) -> Result<()> { | ||
let tree = config.tree(LuaVersion::from(&config)?)?; | ||
/// Package or list of packages to remove from the dependencies. | ||
package: Vec<PackageName>, | ||
|
||
let package_matches = remove_args | ||
.packages | ||
.iter() | ||
.map(|package_req| tree.match_rocks(package_req)) | ||
.try_collect::<_, Vec<_>, io::Error>()?; | ||
/// Remove a development dependency. | ||
/// Also called `dev`. | ||
#[arg(short, long, alias = "dev", visible_short_aliases = ['d', 'b'])] | ||
build: Option<Vec<PackageName>>, | ||
|
||
let (packages, nonexistent_packages, duplicate_packages) = package_matches.into_iter().fold( | ||
(Vec::new(), Vec::new(), Vec::new()), | ||
|(mut p, mut n, mut d), rock_match| { | ||
match rock_match { | ||
RockMatches::NotFound(req) => n.push(req), | ||
RockMatches::Single(package) => p.push(package), | ||
RockMatches::Many(packages) => d.extend(packages), | ||
}; | ||
/// Remove a test dependency. | ||
#[arg(short, long)] | ||
test: Option<Vec<PackageName>>, | ||
} | ||
|
||
(p, n, d) | ||
}, | ||
); | ||
pub async fn remove(data: Remove, config: Config) -> Result<()> { | ||
let mut project = Project::current()?.ok_or_eyre("No project found")?; | ||
let tree = project.tree(&config)?; | ||
let progress = MultiProgress::new_arc(); | ||
|
||
if !nonexistent_packages.is_empty() { | ||
// TODO(vhyrro): Render this in the form of a tree. | ||
return Err(eyre!( | ||
"The following packages were not found: {:#?}", | ||
nonexistent_packages | ||
)); | ||
if !data.package.is_empty() { | ||
project | ||
.remove(lux_lib::project::DependencyType::Regular(data.package)) | ||
.await?; | ||
// NOTE: We only update the lockfile if one exists. | ||
// Otherwise, the next `lx build` will remove the packages. | ||
if let Some(lockfile) = project.try_lockfile()? { | ||
let mut lockfile = lockfile.write_guard(); | ||
let packages = project | ||
.toml() | ||
.into_validated()? | ||
.dependencies() | ||
.current_platform() | ||
.clone(); | ||
Sync::new(&tree, &mut lockfile, &config) | ||
.packages(packages) | ||
.progress(progress.clone()) | ||
.sync_dependencies() | ||
.await | ||
.wrap_err("syncing dependencies with the project lockfile failed.")?; | ||
} | ||
} | ||
|
||
if !duplicate_packages.is_empty() { | ||
return Err(eyre!( | ||
" | ||
Multiple packages satisfying your version requirements were found: | ||
{:#?} | ||
Please specify the exact package to uninstall: | ||
> lux remove '<name>@<version>' | ||
", | ||
duplicate_packages, | ||
)); | ||
let build_packages = data.build.unwrap_or_default(); | ||
if !build_packages.is_empty() { | ||
project | ||
.remove(lux_lib::project::DependencyType::Build(build_packages)) | ||
.await?; | ||
if let Some(lockfile) = project.try_lockfile()? { | ||
let luarocks = LuaRocksInstallation::new(&config)?; | ||
let mut lockfile = lockfile.write_guard(); | ||
let packages = project | ||
.toml() | ||
.into_validated()? | ||
.build_dependencies() | ||
.current_platform() | ||
.clone(); | ||
Sync::new(luarocks.tree(), &mut lockfile, luarocks.config()) | ||
.packages(packages) | ||
.progress(progress.clone()) | ||
.sync_build_dependencies() | ||
.await | ||
.wrap_err("syncing build dependencies with the project lockfile failed.")?; | ||
} | ||
} | ||
|
||
operations::Remove::new(&config) | ||
.packages(packages) | ||
.remove() | ||
.await?; | ||
let test_packages = data.test.unwrap_or_default(); | ||
if !test_packages.is_empty() { | ||
project | ||
.remove(lux_lib::project::DependencyType::Test(test_packages)) | ||
.await?; | ||
if let Some(lockfile) = project.try_lockfile()? { | ||
let mut lockfile = lockfile.write_guard(); | ||
let packages = project | ||
.toml() | ||
.into_validated()? | ||
.test_dependencies() | ||
.current_platform() | ||
.clone(); | ||
Sync::new(&tree, &mut lockfile, &config) | ||
.packages(packages) | ||
.progress(progress.clone()) | ||
.sync_test_dependencies() | ||
.await | ||
.wrap_err("syncing test dependencies with the project lockfile failed.")?; | ||
} | ||
} | ||
|
||
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