Skip to content

Commit

Permalink
feat: add all flag to pop clean (#233)
Browse files Browse the repository at this point in the history
* fix: implemented new subcommand for cleaning all cache contnt

* fix: improved documentation for new clean flag; implemented unit test based on all flag

* test: improved unit tests for

* lint: ran code formatter on all changed files

* fix: update outro message for cancelled prompt in clean command
  • Loading branch information
bolajahmad authored Jul 24, 2024
1 parent 658fc3a commit a2b88f8
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 40 deletions.
184 changes: 146 additions & 38 deletions crates/pop-cli/src/commands/clean.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

use crate::cli::traits::*;
use crate::{cli::traits::*, style::style};
use anyhow::Result;
use clap::{Args, Subcommand};
use std::{
Expand All @@ -20,7 +20,14 @@ pub(crate) struct CleanArgs {
pub(crate) enum Command {
/// Remove cached artifacts.
#[clap(alias = "c")]
Cache,
Cache(CleanCommandArgs),
}

#[derive(Args)]
pub struct CleanCommandArgs {
/// Pass flag to remove all artifacts
#[arg(short = 'a', long)]
pub(crate) all: bool,
}

/// Removes cached artifacts.
Expand All @@ -29,6 +36,8 @@ pub(crate) struct CleanCacheCommand<'a, CLI: Cli> {
pub(crate) cli: &'a mut CLI,
/// The cache to be used.
pub(crate) cache: PathBuf,
/// Whether to clean all artifacts.
pub(crate) all: bool,
}

impl<'a, CLI: Cli> CleanCacheCommand<'a, CLI> {
Expand All @@ -54,38 +63,71 @@ impl<'a, CLI: Cli> CleanCacheCommand<'a, CLI> {
self.cache.to_str().expect("expected local cache is invalid")
))?;

// Prompt for selection of artifacts to be removed
let selected = {
let mut prompt =
self.cli.multiselect("Select the artifacts you wish to remove:").required(false);
for (name, path, size) in &contents {
prompt = prompt.item(path, name, format!("{}MiB", size / 1_048_576))
if self.all {
// Display all artifacts to be deleted and get confirmation
let list = style(format!(
"\n{}",
&contents
.iter()
.map(|(name, _, size)| format!("{} : {}MiB", name, size / 1_048_576))
.collect::<Vec<_>>()
.join("; \n")
))
.to_string();

if !self
.cli
.confirm(format!("Would you like to cleanup all cached artifacts...\n {list} \n"))
.interact()?
{
self.cli.outro_cancel("ℹ️ No artifacts removed")?;
return Ok(());
}
prompt.interact()?
};
if selected.is_empty() {
self.cli.outro("ℹ️ No artifacts removed")?;
return Ok(());
};

// Confirm removal
let prompt = match selected.len() {
1 => "Are you sure you want to remove the selected artifact?".into(),
_ => format!(
"Are you sure you want to remove the {} selected artifacts?",
selected.len()
),
};
if !self.cli.confirm(prompt).interact()? {
self.cli.outro("ℹ️ No artifacts removed")?;
return Ok(());
}
for (_, file, _) in &contents {
// confirm removal
remove_file(&file)?;
}

// Finally remove selected artifacts
for file in &selected {
remove_file(file)?
self.cli.outro(format!("ℹ️ {} artifacts removed", contents.len()))?;
} else {
// Prompt for selection of artifacts to be removed
let selected = {
let mut prompt = self
.cli
.multiselect("Select the artifacts you wish to remove:")
.required(false);
for (name, path, size) in &contents {
prompt = prompt.item(path, name, format!("{}MiB", size / 1_048_576))
}
prompt.interact()?
};
if selected.is_empty() {
self.cli.outro("ℹ️ No artifacts removed")?;
return Ok(());
};

// Confirm removal
let prompt = match selected.len() {
1 => "Are you sure you want to remove the selected artifact?".into(),
_ => format!(
"Are you sure you want to remove the {} selected artifacts?",
selected.len()
),
};
if !self.cli.confirm(prompt).interact()? {
self.cli.outro("ℹ️ No artifacts removed")?;
return Ok(());
}

// Finally remove selected artifacts
for file in &selected {
remove_file(file)?
}

self.cli.outro(format!("ℹ️ {} artifacts removed", selected.len()))?;
}
self.cli.outro(format!("ℹ️ {} artifacts removed", selected.len()))?;

Ok(())
}
}
Expand Down Expand Up @@ -119,7 +161,7 @@ mod tests {
let cache = PathBuf::new();
let mut cli = MockCli::new().expect_intro(&"Remove cached artifacts");

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

cli.verify()
}
Expand All @@ -129,7 +171,7 @@ mod tests {
let cache = PathBuf::new();
let mut cli = MockCli::new().expect_outro_cancel(&"🚫 The cache does not exist.");

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

cli.verify()
}
Expand All @@ -141,7 +183,7 @@ mod tests {
let mut cli = MockCli::new()
.expect_outro(&format!("ℹ️ The cache at {} is empty.", cache.to_str().unwrap()));

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

cli.verify()
}
Expand All @@ -156,7 +198,7 @@ mod tests {
let mut cli = MockCli::new()
.expect_info(format!("ℹ️ The cache is located at {}", cache.to_str().unwrap()));

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

cli.verify()
}
Expand All @@ -177,7 +219,7 @@ mod tests {
Some(items),
);

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

cli.verify()
}
Expand All @@ -200,7 +242,7 @@ mod tests {
)
.expect_outro("ℹ️ No artifacts removed");

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

for artifact in artifacts {
assert!(artifact.exists())
Expand All @@ -226,7 +268,73 @@ mod tests {
.expect_confirm("Are you sure you want to remove the selected artifact?", false)
.expect_outro("ℹ️ No artifacts removed");

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

cli.verify()
}

#[test]
fn clean_cache_cleans_dir_when_all_flag_specified() -> Result<()> {
let temp = tempfile::tempdir()?;
let cache = temp.path().to_path_buf();
let artifacts = ["polkadot-parachain", "pop-node"];
let mut items = vec![];
for artifact in &artifacts {
File::create(cache.join(artifact))?;
items.push((artifact, "0MiB".to_string()));
}

let list = style(format!(
"\n{}",
items
.iter()
.map(|(name, size)| format!("{} : {}", name, size))
.collect::<Vec<_>>()
.join("; \n")
))
.to_string();

let mut cli = MockCli::new()
.expect_confirm(
format!("Would you like to cleanup all cached artifacts...\n {list} \n"),
true,
)
.expect_outro("ℹ️ 2 artifacts removed");

CleanCacheCommand { cli: &mut cli, cache, all: true }.execute()?;

cli.verify()
}

#[test]
fn clean_cache_all_removes_nothing_if_unconfirmed() -> Result<()> {
let temp = tempfile::tempdir()?;
let cache = temp.path().to_path_buf();
let artifacts = ["polkadot-parachain", "pop-node"];
let mut items = vec![];
for artifact in &artifacts {
File::create(cache.join(artifact))?;
items.push((artifact, "0MiB".to_string()));
}

let list = style(format!(
"\n{}",
items
.iter()
.map(|(name, size)| format!("{} : {}", name, size))
.collect::<Vec<_>>()
.join("; \n")
))
.to_string();

let mut cli = MockCli::new()
.expect_confirm(
format!("Would you like to cleanup all cached artifacts...\n {list} \n"),
false,
)
.expect_outro_cancel("ℹ️ No artifacts removed");

CleanCacheCommand { cli: &mut cli, cache: cache.clone(), all: true }.execute()?;

cli.verify()
}
Expand All @@ -250,7 +358,7 @@ mod tests {
.expect_confirm("Are you sure you want to remove the 3 selected artifacts?", true)
.expect_outro("ℹ️ 3 artifacts removed");

CleanCacheCommand { cli: &mut cli, cache }.execute()?;
CleanCacheCommand { cli: &mut cli, cache, all: false }.execute()?;

for artifact in artifacts {
assert!(!artifact.exists())
Expand Down
4 changes: 2 additions & 2 deletions crates/pop-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ impl Command {
},
},
Self::Clean(args) => match args.command {
clean::Command::Cache => {
clean::Command::Cache(cmd_args) => {
// Initialize command and execute
clean::CleanCacheCommand { cli: &mut Cli, cache: cache()? }
clean::CleanCacheCommand { cli: &mut Cli, cache: cache()?, all: cmd_args.all }
.execute()
.map(|_| Value::Null)
},
Expand Down

0 comments on commit a2b88f8

Please sign in to comment.