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

UUID and sha256 digest functions #1170

Merged
merged 13 commits into from
May 4, 2022
Merged

UUID and sha256 digest functions #1170

merged 13 commits into from
May 4, 2022

Conversation

mbodmer
Copy link
Contributor

@mbodmer mbodmer commented May 1, 2022

issue #1018 mentioned a uuid function would be helpful.

Here is my attempt to deliver this. Also I've included sha256 hashing functions for strings and files.

To create a meaningful unittest for uuid() I had to refactor the Test struct in test.rs, I hope this is acceptable. The challenge was to keep the current interface but allow for custom verification. Well, here is my attempt. I'm new to rust, so bear with me.

@mbodmer
Copy link
Contributor Author

mbodmer commented May 2, 2022

#1011

@casey
Copy link
Owner

casey commented May 3, 2022

Thanks for this PR! There's already Test::stderr_regex, and I think it might be cleaner to add a Test::stdout_regex to test that the output matches a pattern, instead of adding a new kind of validator. for UUIDs, it should be okay to check that it matches the pattern /........-....-....-....-............/

For the hash functions, can you use the implementation from https://github.com/RustCrypto/hashes? I think it's better maintained.

@mbodmer
Copy link
Contributor Author

mbodmer commented May 3, 2022

Hi, thanks for your review. I have now added stdout_regex in the sense of the existing stderr_regex. I agree, much less complexity that way. Also I have replaced the hashing dependency with rust-crypto. Hope this helps.

@mbodmer
Copy link
Contributor Author

mbodmer commented May 3, 2022

I'm not sure whether the general name digest()/digest_file() for the functions is too broad. Any requests for a better more concise name? :-)
eg: sha256()/sha256_file()

@casey
Copy link
Owner

casey commented May 3, 2022

I'm not sure whether the general name digest()/digest_file() for the functions is too broad. Any requests for a better more concise name? :-) eg: sha256()/sha256_file()

I think I agree, sha256() and sha256_file() are probably better, so if you're reading a justfile and you don't know the function you can see what it does without having to look up documentation.

@mbodmer
Copy link
Contributor Author

mbodmer commented May 3, 2022

Ok, they are now renamed to the more specific sha256(), sha256_file()

Copy link
Owner

@casey casey left a comment

Choose a reason for hiding this comment

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

Nice, looking good. I added a few minor comments.

README.md Outdated
@@ -1016,6 +1016,12 @@ These functions can fail, for example if a path does not have an extension, whic

- `error(message)` - Abort execution and report error `message` to user.

#### UUID and Hash Generation

- `sha256(textdata)` Generates a sha256 hash of the given text data. Example: `sha256("just hello")`
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
- `sha256(textdata)` Generates a sha256 hash of the given text data. Example: `sha256("just hello")`
- `sha256(string)` Return the SHA-256 hash of `string` as a hexadecimal string.

README.md Outdated
#### UUID and Hash Generation

- `sha256(textdata)` Generates a sha256 hash of the given text data. Example: `sha256("just hello")`
- `sha256_file(path)` Generates a sha256 hash of the given file. Example: `sha256_file("/path/to/file")`
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
- `sha256_file(path)` Generates a sha256 hash of the given file. Example: `sha256_file("/path/to/file")`
- `sha256_file(path)` Return the SHA-256 hash of the file at `path` as a hexadecimal string.

README.md Outdated

- `sha256(textdata)` Generates a sha256 hash of the given text data. Example: `sha256("just hello")`
- `sha256_file(path)` Generates a sha256 hash of the given file. Example: `sha256_file("/path/to/file")`
- `uuid()` - Randomly generates a hyphenated UUID string.
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
- `uuid()` - Randomly generates a hyphenated UUID string.
- `uuid()` - Return a randomly generated UUID.

src/function.rs Outdated
Comment on lines 264 to 265
let mut file = std::fs::File::open(path).unwrap();
std::io::copy(&mut file, &mut hasher).unwrap();
Copy link
Owner

Choose a reason for hiding this comment

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

These unwraps should both be handled. Something like:

Suggested change
let mut file = std::fs::File::open(path).unwrap();
std::io::copy(&mut file, &mut hasher).unwrap();
let mut file = std::fs::File::open(path).map_err(|err| format!("Failed to open file at `{}`: {}", path, err))?;
std::io::copy(&mut file, &mut hasher).map_err(|err| format!("Failed to read file at `{}`: {}", path, err)?;

#[test]
fn sha256_file() {
let mut tmpfile = tempfile::NamedTempFile::new().unwrap();
writeln!(tmpfile, "just is great").unwrap();
Copy link
Owner

Choose a reason for hiding this comment

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

❤️

let justfile_content = format!("x := sha256_file('{}')", tmppath.to_str().unwrap());

Test::new()
.justfile(justfile_content)
Copy link
Owner

Choose a reason for hiding this comment

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

You can use the somewhat odd tree function to populate the tempdir with files:

Suggested change
.justfile(justfile_content)
.justfile("x := sha256_file('file')")
.tree(tree! {
file: "just is great",
})

@mbodmer
Copy link
Contributor Author

mbodmer commented May 4, 2022

Thanks for the extensive review, I think I've covered all your issues now, feel free to check again

@mbodmer mbodmer requested a review from casey May 4, 2022 18:31
Copy link
Owner

@casey casey left a comment

Choose a reason for hiding this comment

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

Nice, looks good, although I just realized that there's a bug. just doesn't change the working directory, so you'll need to join the path in sha256_file with context.search.working_directory, i.e. context.search.working_directory.join(path).

Could you also add a test for this? It should fail on the current PR, and then pass once path is joined with the working directory. You can use Test::current_dir to make just start in a sub-directory of the tmpdir. You can try to do sha256_file on a file in tempdir.

@mbodmer
Copy link
Contributor Author

mbodmer commented May 4, 2022

Sorry for force pushing, I've had to rewrite the history to rebase the branch, since you've also modified the lockfile and stupid me checked it in, in a commit together with other changes.
Can you give me more details, I don't understand where, how and what causes the bug you've mentioned.

@casey
Copy link
Owner

casey commented May 4, 2022

Lets say you have the following files:

/justfile
/bar
/foo/

And you're currently in /foo/. /justfile contains:

baz:
  echo {{sha256_file("bar")}}}

You do:

$ just

The just executable looks for the justfile and sees that it's in /, so it sets search.working_directory to /. However, it does not call env::set_current_dir with /, so the current directory is still /bar. So then sha256_file("bar") will fail, because there is no /foo/bar.

@mbodmer
Copy link
Contributor Author

mbodmer commented May 4, 2022

Ok, I think now I understand, thanks. Will try

@mbodmer mbodmer requested a review from casey May 4, 2022 22:31
src/function.rs Outdated Show resolved Hide resolved
Copy link
Owner

@casey casey left a comment

Choose a reason for hiding this comment

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

Looks good! I went ahead and removed a _ that is now unnecessary.

@casey casey enabled auto-merge (squash) May 4, 2022 23:16
@casey casey merged commit 862d6a5 into casey:master May 4, 2022
@mbodmer
Copy link
Contributor Author

mbodmer commented May 5, 2022

Thanks

@casey casey mentioned this pull request Jan 25, 2023
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.

2 participants