0

My objective is to upload a file on ipfs.io using Rust programming language. I am firing a command-line tool to do so and the command itself works but when implemented using Rust, it fails.

The actual command is:

➜  ~ ipfs add ~/dev/learning-rust/upload-file-to-ipfs/src/main.rs
added QmPUGDCiLvjEiETVDVMHqgJ8xxtQ5Hu7YEMzFqRfE8vDfq main.rs

Now, my Rust code is:

use std::io;
use std::process::Command;


fn main() {
    // ask user to provide the file path to be uploaded on ipfs
    println!("Please enter the file path to upload on IPFS: ");
    let mut file_path = String::new();
    io::stdin()
        .read_line(&mut file_path)
        .expect("Failed to read temperature.");
    // uploading a file
    let output = Command::new("ipfs")
        .arg("add")
        .arg(file_path)
        .output()
        .expect("ipfs command failed to start");
    println!("Output is: {:?}", output);
    // println!("The hash digest is: {:?}", output.stdout);
}

This fails with the following error:

Output is: Output { status: ExitStatus(ExitStatus(256)), stdout: "", stderr: "Error: lstat /Users/aviralsrivastava/dev/learning-rust/upload-file-to-ipfs/src/main.rs\n: no such file or directory\n\nUSAGE\n  ipfs add <path>... - Add a file or directory to ipfs.\n\n  ipfs add [--recursive | -r] [--quiet | -q] [--quieter | -Q] [--silent] [--progress | -p] [--trickle | -t] [--only-hash | -n] [--wrap-with-directory | -w] [--hidden | -H] [--chunker=<chunker> | -s] [--pin=false] [--raw-leaves] [--nocopy] [--fscache] [--cid-version=<cid-version>] [--] <path>...\n\n  Adds contents of <path> to ipfs. Use -r to add directories (recursively).\n\nUse \'ipfs add --help\' for more information about this command.\n\n" }

I referred to this to answer and read the official documentation, all in vain.

How do I upload a file given absolute and/or relative path and return the hash in the print statement?

Aviral Srivastava
  • 4,058
  • 8
  • 29
  • 81

1 Answers1

2

Your problem isn't with Command it's with read_line, which will read all bytes up to and including the newline character (see here). Therefore your path ends up containing the newline character, which is why the file cannot be found.

To solve this, you need to make sure that the file path doesn't contain the trailing newline, e.g. by calling trim_end on it before passing it to the command.

fjh
  • 12,121
  • 4
  • 46
  • 46
  • How do I make my code take the input and upload it instead? I tried hard-coding the values and it works but I am unable to use a variable that takes input and use it to upload the file. – Aviral Srivastava Feb 17 '20 at 23:25
  • @AviralSrivastava You just need to drop the newline when (or before) passing the path to the command. Replacing `.arg(file_path)` with `.arg(file_path.trim_end())` should work, for example. – fjh Feb 17 '20 at 23:33
  • Add this in the answer so that I can accept it. – Aviral Srivastava Feb 17 '20 at 23:36