Skip to content

Conversation

@howjmay
Copy link
Contributor

@howjmay howjmay commented Feb 13, 2023

Closes #3812

@sylvestre
Copy link
Contributor

I know it is a draft and we will squash them but could you please make the commit message a bit more explicit :)

@howjmay
Copy link
Contributor Author

howjmay commented Feb 13, 2023

I know it is a draft and we will squash them but could you please make the commit message a bit more explicit :)

I'm sorry. Let me squash them and present a little better commit first.

@howjmay howjmay force-pushed the cksum-a branch 2 times, most recently from cfd060c to 25a3d86 Compare February 13, 2023 17:04
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!
GNU test failed: tests/misc/timeout. tests/misc/timeout is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/misc/cksum. tests/misc/cksum is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!
GNU test failed: tests/misc/cksum. tests/misc/cksum is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!
GNU test failed: tests/misc/cksum. tests/misc/cksum is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/misc/timeout. tests/misc/timeout is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!
GNU test failed: tests/misc/cksum. tests/misc/cksum is passing on 'main'. Maybe you have to rebase?

@howjmay howjmay force-pushed the cksum-a branch 5 times, most recently from e0fcfe2 to a87ad2e Compare February 14, 2023 07:44
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!

3 similar comments
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!
GNU test failed: tests/misc/timeout. tests/misc/timeout is passing on 'main'. Maybe you have to rebase?

@howjmay howjmay force-pushed the cksum-a branch 4 times, most recently from f872e52 to 7fc81ec Compare February 14, 2023 12:49
@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/tail-2/inotify-dir-recreate. tests/tail-2/inotify-dir-recreate is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/misc/timeout. tests/misc/timeout is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/misc/timeout. tests/misc/timeout is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/tail-2/inotify-dir-recreate. tests/tail-2/inotify-dir-recreate is passing on 'main'. Maybe you have to rebase?

@howjmay howjmay force-pushed the cksum-a branch 2 times, most recently from c512388 to 8032c96 Compare February 14, 2023 17:59
Implement option -a --algorithm.
Move digest to src/uucore/src/lib/features and rename it to hash.

fix lint

fix Cargo.toml
@howjmay howjmay marked this pull request as ready for review February 18, 2023 13:02
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/misc/timeout is no longer failing!

Copy link
Member

@tertsdiepraam tertsdiepraam left a comment

Choose a reason for hiding this comment

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

Since it's almost completely implemented in uucore now, maybe we could make the abstraction less leaky? What I mean is that hashsum and cksum do not have to depend on all the separate crates anymore if uucore exposes wrappers around the types from all the separate crates. For instance:

// Note that the field is private, so can't be constructed directly from cksum or hashsum
pub struct Sha1(sha1::Sha1);

impl Digest for Sha1 { ... }

Then detect_algo also just becomes:

match program {
    "sha1" => Sha1::new(),
    ...
}

Where new has the return type Box<dyn Digest>. Do you think that's possible? Ultimately that might even be an interesting crate to publish separately (though not in this PR).

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!

@@ -0,0 +1,486 @@
// spell-checker:ignore memmem algo
Copy link
Contributor

Choose a reason for hiding this comment

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

please add the license header

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Member

@tertsdiepraam tertsdiepraam left a comment

Choose a reason for hiding this comment

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

I like how the abstraction turned out! I have a few more suggestions, but at some point we should probably just merge this and continue improving it in other PRs.

@tertsdiepraam
Copy link
Member

tertsdiepraam commented Feb 21, 2023

The object safety thing is annoying. I tried some things to get rid of it. What worked is to never box it, because we don't really have to. Instead we can do this:

fn cksum_algo<'a, I>(algorithm: &str, files: I) -> UResult<()>
where
    I: Iterator<Item = &'a OsStr>,
{
    match algorithm {
        "sysv" => cksum::<_, SYSV>("SYSV", files),
        "bsd" => cksum::<_, BSD>("BSD", files),
        ...
}

fn cksum<'a, I, D>(algo_name: &'static str, files: I) -> UResult<()>
where
    I: Iterator<Item = &'a OsStr>,
    D: Digest
{ ... }

pub trait Digest {
    const OUTPUT_BITS: usize;
    const OUTPUT_BYTES: usize = (Self::OUTPUT_BITS + 7) / 8;
    fn new() -> Self;
    fn hash_update(&mut self, input: &[u8]);
    fn hash_finalize(&mut self, out: &mut [u8]);
    fn result_str(&mut self) -> String {
        let mut buf: Vec<u8> = vec![0; Self::OUTPUT_BYTES];
        self.hash_finalize(&mut buf);
        encode(buf)
    }
}

But I can also do this after this PR is merged.

Copy link
Member

@tertsdiepraam tertsdiepraam left a comment

Choose a reason for hiding this comment

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

Alright, it's time to wrap this up. Like I said, the trait might need a bit of a redesign, but that's not really related to this PR. I have one final comment and then it's good in my opinion.

@howjmay
Copy link
Contributor Author

howjmay commented Feb 22, 2023

The object safety thing is annoying. I tried some things to get rid of it. What worked is to never box it, because we don't really have to. Instead we can do this:

fn cksum_algo<'a, I>(algorithm: &str, files: I) -> UResult<()>
where
    I: Iterator<Item = &'a OsStr>,
{
    match algorithm {
        "sysv" => cksum::<_, SYSV>("SYSV", files),
        "bsd" => cksum::<_, BSD>("BSD", files),
        ...
}

fn cksum<'a, I, D>(algo_name: &'static str, files: I) -> UResult<()>
where
    I: Iterator<Item = &'a OsStr>,
    D: Digest
{ ... }

pub trait Digest {
    const OUTPUT_BITS: usize;
    const OUTPUT_BYTES: usize = (Self::OUTPUT_BITS + 7) / 8;
    fn new() -> Self;
    fn hash_update(&mut self, input: &[u8]);
    fn hash_finalize(&mut self, out: &mut [u8]);
    fn result_str(&mut self) -> String {
        let mut buf: Vec<u8> = vec![0; Self::OUTPUT_BYTES];
        self.hash_finalize(&mut buf);
        encode(buf)
    }
}

But I can also do this after this PR is merged.

Cool I can give it a try in another PR.

"sha512" => ("SHA512", Box::new(Sha512::new()) as Box<dyn Digest>, 512),
"blake2b" => ("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512),
"sm3" => ("SM3", Box::new(Sm3::new()) as Box<dyn Digest>, 512),
_ => panic!("unknown algorithm"),
Copy link
Member

Choose a reason for hiding this comment

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

One more thing. This is probably not a great error to show to the user. We can restrict the values clap accepts with Arg::possible_values, so that this panic will never be reached.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but I need a default option in match.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah the _ case will need to be there still, but we can change it to unreachable!("unknown algorithm: clap should have prevented this case")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@tertsdiepraam
Copy link
Member

I'll do that change to Digest because by experimenting I already basically have a branch ready. I'll ping you for review though, I'll be interested to see your feedback on it.

@howjmay
Copy link
Contributor Author

howjmay commented Feb 22, 2023

Thank you!

.long(options::ALGORITHM)
.short('a')
.help("select the digest type to use. See DIGEST below")
.value_name("ALGORITHM"),
Copy link
Member

Choose a reason for hiding this comment

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

Here you can add .value_parser(["bsd", "sysv", ...]) to actually restrict the arguments. Tha't's what I was referring to in the other comment. Here's an example of du doing the same thing: https://github.com/uutils/coreutils/blob/main/src/uu/du/src/du.rs#L877.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for advice. I have put a fix

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing!

@tertsdiepraam
Copy link
Member

Alright, time to merge this! Thanks!

@tertsdiepraam tertsdiepraam merged commit 3554565 into uutils:main Feb 23, 2023
@howjmay
Copy link
Contributor Author

howjmay commented Feb 23, 2023

thank you too!

@howjmay howjmay deleted the cksum-a branch February 23, 2023 16:17
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.

cksum: implement -a

3 participants