Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #53 #111

Merged
merged 11 commits into from Jun 7, 2022
Merged

Resolves #53 #111

merged 11 commits into from Jun 7, 2022

Conversation

thedanvail
Copy link
Contributor

Adds a more graceful exit when the directory does not exist.

If the desired behavior is any different (for example, printing the absolute path of the nonexistent directory), I can update with the absolute path.

Adds a more graceful exit when the directory does not exist.
Copy link
Member

@aviramha aviramha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution!
I have left few notes in the code.
Feel free to ask for clarifications/guidance if needed.
Also, you are more than welcome to consult with us in our Discord server.

CHANGELOG.md Outdated Show resolved Hide resolved
let mut file = File::create(file_path.clone()).unwrap();
let mut file = match File::create(&file_path) {
Ok(file) => file,
Err(_) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be better to bind the error here and add it to the message (as it can fail for many reasons, one reason can be directory not existing)

Err(_) => {
file_path.pop();
eprintln!("Directiory \"{}\" does not exist.", file_path.display());
std::process::exit(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be better if we changed the signature of the function to Result<String> then just return the err here.

Ok(file) => file,
Err(_) => {
file_path.pop();
eprintln!("Directiory \"{}\" does not exist.", file_path.display());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to use trace library macros (error).

Decided to utilize `anyhow` at the recommendation of @aviramha - went with the `with_context` option as that seemed the most elegant solution.
@thedanvail
Copy link
Contributor Author

@aviramha I tried to take all of your comments into consideration as I updated using anyhow to handle an invalid path.
Additional meta-information:

  1. This is my first open source PR, so I apologize if I'm not quite following best practices
  2. I found this issue through the This Week In Rust call for collaboration - just so you know!

@aviramha
Copy link
Member

aviramha commented Jun 3, 2022

@thedanvail

  1. Great! Thanks for choosing us to be your first contribution. Beware, OSS contributing can be addictive!
  2. Cool! Thanks for letting us know :)

Copy link
Member

@aviramha aviramha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context can be great, but a few more tweaks are needed to merge this.
Thanks!

@@ -117,7 +120,7 @@ fn exec(args: &ExecArgs) -> Result<()> {
if args.accept_invalid_certificates {
std::env::set_var("MIRRORD_ACCEPT_INVALID_CERTIFICATES", "true");
}
let library_path = extract_library(None);
let library_path = extract_library(None).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use ? here instead of unwrap

@@ -138,7 +141,7 @@ fn main() {
match cli.commands {
Commands::Exec(args) => exec(&args).unwrap(),
Commands::Extract { path } => {
extract_library(Some(path));
extract_library(Some(path)).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change fn main to return Result<()> then you can use ? here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I change the main function signature to return Result<()>, then we'd have to remove the unwrap()s/? to return the Result - or we can leave in the unwrap()s/? and leave out Result from the return type - which behavior would be preferred?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? is a syntatic sugar that returns when a Result/Option has Err/None else it returns the inner value.
So the change would to add ? and change the return type to Result
https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that, but the issue is, if I run cargo check with the following code

fn main() -> Result<()> {
    registry()
        .with(fmt::layer())
        .with(EnvFilter::from_default_env())
        .init();
    prompt_outdated_version();

    let cli = Cli::parse();
    match cli.commands {
        Commands::Exec(args) => exec(&args)?,
        Commands::Extract { path } => {
            extract_library(Some(path))?;
        }
    }
}

I receive the following error:

Screen-Shot-2022-06-03-at-2-44-03-PM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry but the image isn't available.. you can upload directly to GitHub by pasting the image here.
Considering the snippet, I think I know what the issue is. You can just drop the ? in both arms and it'd work because both exec and extract_library return Result, so no need to unwrap it and you can just return their return value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in your changes - since extract_library returns a Result<String> instead of Result<()>, I just return a normal Ok(()). I think that should cover everything!

Copy link
Member

@aviramha aviramha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few small tweaks left :)
Sorry for being hard, but we want to make sure everything is great.
Also please fix conflicts with the main branch so we GH can run our automated tests.

CHANGELOG.md Outdated
@@ -6,6 +6,8 @@ Previous versions had CHANGELOG per component, we decided to combine all reposit
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## [Unreleased]
### Changed
- Added a graceful exit for system paths that do not exist.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reword - "Added graceful exit for library extraction logic in case of error"

let library_file = env!("CARGO_CDYLIB_FILE_MIRRORD_LAYER");
let library_path = std::path::Path::new(library_file);
let file_name = library_path.components().last().unwrap();
let file_path = match dest_dir {
Some(dest_dir) => std::path::Path::new(&dest_dir).join(file_name),
None => temp_dir().as_path().join(file_name),
};
let mut file = File::create(file_path.clone()).unwrap();
let mut file = File::create(&file_path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't know for sure the reason it failed is due to path not existing, so I'd just add using context the file path ("Path .. creation failed")

@@ -136,9 +139,10 @@ fn main() {

let cli = Cli::parse();
match cli.commands {
Commands::Exec(args) => exec(&args).unwrap(),
Commands::Exec(args) => exec(&args),
Commands::Extract { path } => {
extract_library(Some(path));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you would have warning here if you wont add ?

Copy link
Contributor Author

@thedanvail thedanvail Jun 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nay - the function returns Result<()>, and because we added that to the main() -> Result<()> as well, this compiles as is. If I add the ? operator - Commands::Exec(args) => exec(&args)?, - cargo check returns the following:

error[E0308]: `?` operator has incompatible types
   --> mirrord-cli/src/main.rs:142:33
    |
142 |         Commands::Exec(args) => exec(&args)?,
    |                                 ^^^^^^^^^^^^ expected enum `Result`, found `()`
    |
    = note: `?` operator cannot convert from `()` to `Result<(), anyhow::Error>`
    = note:   expected enum `Result<(), anyhow::Error>`
            found unit type `()`
help: try removing this `?`
    |
142 -         Commands::Exec(args) => exec(&args)?,
142 +         Commands::Exec(args) => exec(&args),
    | 
help: try wrapping the expression in `Ok`
    |
142 |         Commands::Exec(args) => Ok(exec(&args)?),
    |                                 +++            +

For more information about this error, try `rustc --explain E0308`.
error: could not compile `mirrord` due to previous error

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be best to have ? in the end of all arm branches (on exec + Extract) then outside the match branch (in the end of function) just to have Ok(()) which means that if it got there, we're all good.

@thedanvail
Copy link
Contributor Author

Few small tweaks left :) Sorry for being hard, but we want to make sure everything is great. Also please fix conflicts with the main branch so we GH can run our automated tests.

No, please be as hard as you'd like! I'm trying to take as many notes as I can to get better at Rust and so I can be better at my next OSS PR. I sincerely appreciate your patience with me during this process!

I believe I have updated to reflect your suggestions and updated to fix the merge conflicts. I'm currently between a couple flights, so I didn't have time to check the status before the plane took off, but should be good now!

@aviramha
Copy link
Member

aviramha commented Jun 6, 2022

Few small tweaks left :) Sorry for being hard, but we want to make sure everything is great. Also please fix conflicts with the main branch so we GH can run our automated tests.

No, please be as hard as you'd like! I'm trying to take as many notes as I can to get better at Rust and so I can be better at my next OSS PR. I sincerely appreciate your patience with me during this process!

I believe I have updated to reflect your suggestions and updated to fix the merge conflicts. I'm currently between a couple flights, so I didn't have time to check the status before the plane took off, but should be good now!

Awesome, just see my last comment in the conversation about the ?.

@thedanvail
Copy link
Contributor Author

Done and done!

@thedanvail
Copy link
Contributor Author

(Just updated with cargo fmt)

@thedanvail
Copy link
Contributor Author

I looked at the last CI run, and it looks like the cargo clippy issues are in mirrord-layer, which I did not touch in this PR. Let me know if I should do anything further.

@aviramha
Copy link
Member

aviramha commented Jun 7, 2022

Yes you're right. We're not binding clippy to a specific version so such cases can happen :)
Thanks for the contribution!

@aviramha aviramha merged commit 604ad8f into metalbear-co:main Jun 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants