Skip to content

Commit

Permalink
feat(iroh): make out argument required for iroh get (#1786)
Browse files Browse the repository at this point in the history
When using `iroh get` always require `--out` to specify the place to
store the output.

```sh
# stdout
> iroh get --ticket <TICKET> --out STDOUT
# directory
> iroh get --ticket <TICKET> --out ./my-dir
```

Closes #843
  • Loading branch information
dignifiedquire committed Nov 9, 2023
1 parent d471477 commit 0e0f641
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 18 deletions.
39 changes: 37 additions & 2 deletions iroh/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,16 @@ pub enum FullCommands {
/// DERP region of the provider
#[clap(long)]
region: Option<u16>,
/// Directory in which to save the file(s), defaults to writing to STDOUT
/// Directory in which to save the file(s). When passed `STDOUT` will be written to stdout,
/// otherwise the content will be stored in the provided path.
///
/// If the directory exists and contains a partial download, the download will
/// be resumed.
///
/// Otherwise, all files in the collection will be overwritten. Other files
/// in the directory will be left untouched.
#[clap(long, short)]
out: Option<PathBuf>,
out: OutputTarget,
#[clap(conflicts_with_all = &["hash", "peer", "addrs", "token"])]
/// Ticket containing everything to retrieve the data from a provider.
#[clap(long)]
Expand All @@ -224,6 +225,27 @@ pub enum FullCommands {
},
}

/// Where the data should be stored.
#[derive(Debug, Clone, derive_more::Display, PartialEq, Eq)]
pub enum OutputTarget {
/// Writes to stdout
#[display("STDOUT")]
Stdout,
/// Writes to the provided path
#[display("{}", _0.display())]
Path(PathBuf),
}

impl From<String> for OutputTarget {
fn from(s: String) -> Self {
if s == "STDOUT" {
return OutputTarget::Stdout;
}

OutputTarget::Path(s.into())
}
}

impl FullCommands {
pub async fn run(
self,
Expand Down Expand Up @@ -1132,4 +1154,17 @@ mod tests {
BlobSource::Path("hello/world".into()),
);
}

#[test]
fn test_output_target() {
assert_eq!(
OutputTarget::from(OutputTarget::Stdout.to_string()),
OutputTarget::Stdout
);

assert_eq!(
OutputTarget::from(OutputTarget::Path("hello/world".into()).to_string()),
OutputTarget::Path("hello/world".into()),
);
}
}
11 changes: 6 additions & 5 deletions iroh/src/commands/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ use iroh_net::derp::DerpMode;

use crate::commands::show_download_progress;

use super::OutputTarget;

#[derive(Debug)]
pub struct GetInteractive {
pub rt: iroh_bytes::util::runtime::Handle,
Expand Down Expand Up @@ -99,11 +101,10 @@ impl GetInteractive {
Ok(())
}

pub async fn get_interactive(self, out_dir: Option<PathBuf>) -> Result<()> {
if let Some(out_dir) = out_dir {
self.get_to_dir(out_dir).await
} else {
self.get_to_stdout().await
pub async fn get_interactive(self, out_dir: OutputTarget) -> Result<()> {
match out_dir {
OutputTarget::Path(dir) => self.get_to_dir(dir).await,
OutputTarget::Stdout => self.get_to_stdout().await,
}
}

Expand Down
21 changes: 10 additions & 11 deletions iroh/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ fn make_get_cmd(iroh_data_dir: &Path, ticket: &str, out: Option<PathBuf>) -> duc
["get", "--ticket", ticket, "--out", out.to_str().unwrap()],
)
} else {
cmd(iroh_bin(), ["get", "--ticket", ticket])
cmd(iroh_bin(), ["get", "--ticket", ticket, "--out", "STDOUT"])
}
.env_remove("RUST_LOG")
.env("IROH_DATA_DIR", iroh_data_dir)
Expand Down Expand Up @@ -694,12 +694,12 @@ fn test_provide_get_loop_single(
hash: Hash,
) -> Result<()> {
let out = match output {
Output::Stdout => None,
Output::Stdout => "STDOUT".to_string(),
Output::Path => {
let dir = testdir!();
Some(dir.join("out"))
dir.join("out").display().to_string()
}
Output::Custom(out) => Some(out),
Output::Custom(ref out) => out.display().to_string(),
};

let num_blobs = if path.is_dir() {
Expand Down Expand Up @@ -733,10 +733,9 @@ fn test_provide_get_loop_single(
args.push("--addrs");
args.push(addr);
}
if let Some(ref out) = out {
args.push("--out");
args.push(out.to_str().unwrap());
}
args.push("--out");
args.push(&out);

args.push("--region");
args.push(&region);
let hash_str = hash.to_string();
Expand All @@ -757,12 +756,12 @@ fn test_provide_get_loop_single(

// test output
let expect_content = std::fs::read(path)?;
match out {
None => {
match output {
Output::Stdout => {
assert!(!get_output.stdout.is_empty());
assert_eq!(expect_content, get_output.stdout);
}
Some(out) => {
_ => {
let content = std::fs::read(out)?;
assert_eq!(expect_content, content);
}
Expand Down

0 comments on commit 0e0f641

Please sign in to comment.