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

split: suffix length refactor #5449

Merged
merged 5 commits into from
Nov 3, 2023

Conversation

zhitkoff
Copy link
Contributor

Refactoring suffix length processing, distinguishing between dynamic auto-widening vs. pre-calculated auto-width and addressing an edge case of passing 0 as a value for suffix length in command line option,
i.e. split -a0 file
or split --suffix-length=0 file

@zhitkoff
Copy link
Contributor Author

@sylvestre would you mind reviewing this one?

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.

Cool! Nice tests! I have a few small suggestions, but looks good overall, especially given all the edge case we have to take into account.

Comment on lines 725 to 728
let opt = matches.get_one::<String>(OPT_NUMERIC_SUFFIXES); // if option was specified, but without value - this will return None as there is no default value
if opt.is_some() {
suffix_start = opt
.unwrap()
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let opt = matches.get_one::<String>(OPT_NUMERIC_SUFFIXES); // if option was specified, but without value - this will return None as there is no default value
if opt.is_some() {
suffix_start = opt
.unwrap()
// if option was specified, but without value - this will return None as there is no default value
if let Some(opt) = matches.get_one::<String>(OPT_NUMERIC_SUFFIXES) {
suffix_start = opt

// and not from default value
if matches.value_source(OPT_SUFFIX_LENGTH) == Some(ValueSource::CommandLine) {
// Disable dynamic auto-widening if suffix length was specified in command line with value > 0
if matches.value_source(OPT_SUFFIX_LENGTH) == Some(ValueSource::CommandLine)
Copy link
Member

Choose a reason for hiding this comment

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

I'd really appreciate if we could avoid this check. I think we should remove the default value for OPT_SUFFIX_LENGTH because that default value does have the same meaning as the same value provided by the user, which is why we have to do these ugly checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so, for this option we need to account for the following scenarios as they all have different outcomes, especially in combination with other options (like --numeric-suffixes, --hex-suffixes and --number):

  1. value was not provided in cmd line
  2. value was provided in cmd line and it is > 0
  3. value was provided in cmd line and it is == 0

and these need to be done at least in two different places.

If we drop default value on this options, we would still need to distinguish between these 3 scenarios in all applicable combinations. It would just be different checks and possibly parsing to usize more then once or introducing additional temp variables, since we cannot do all of these checks in one place - due to how it works in combination with other options.

I will try a few different ways and see if it can be simplified.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pushed new version that should address this one as well

/// set auto widening OFF AND auto pre-calculate required suffix length based on number of files needed
/// - If suffix length is specified as 0 in any other situation
/// keep auto widening ON and suffix length to default value
///
Copy link
Member

Choose a reason for hiding this comment

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

I can't put a comment on that line, but if we're refactoring this, I think it makes sense to make (SuffixType, usize, bool, usize) a Suffix type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, I considered it. The best way is to separate suffix (or whole Settings) and Strategy into their own modules/files though, otherwise it would be cumbersome to pass this new Suffix type to FilenameIterator in filenames.rs. And if we keep the current way suffix values are passed to it, then there is no much simplification - just in calling suffix_from.
Would you be OK with that approach?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or ... new Suffix type goes to filenames.rs, but Strategy would need to moved into its own crate/file, since the suffix_from (which I would imagine should be part of impl Suffix) uses it.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need separate crates. Even for modules using them in submodules should be fine, but I'll leave this up to you.

@zhitkoff
Copy link
Contributor Author

@tertsdiepraam with latest changes, could you please let me know if you have other comments/suggestions?

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.

Looks really good! Just one small question.

Also please be careful with moving things around. If you want to do that, it's best to do it in a separate commit. That makes it easier to review.

.get_one::<String>(OPT_ADDITIONAL_SUFFIX)
.unwrap()
.to_string();
if additional.contains('/') {
Copy link
Member

Choose a reason for hiding this comment

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

Should this be \ as well for Windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, pushed an update

.get_one::<String>(OPT_ADDITIONAL_SUFFIX)
.unwrap()
.to_string();
if additional.contains('/') || additional.contains('\\') {
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 the check should probably be done with this function https://doc.rust-lang.org/std/path/fn.is_separator.html to be entirely correct, because only / should work on Unix and both \ and / should work on Windows (and there might be other exceptions for other platforms).

It would probably look something like this:

Suggested change
if additional.contains('/') || additional.contains('\\') {
if additional.chars().any(std::path::is_separator) {

Mention me again when it's done and we'll merge this :)

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.

Great, thanks! Can be merged once the CI is green!

Copy link

github-actions bot commented Nov 2, 2023

GNU testsuite comparison:

Congrats! The gnu test tests/rm/rm2 is no longer failing!
Congrats! The gnu test tests/tail/inotify-dir-recreate is no longer failing!
Skip an intermittent issue tests/rm/rm1
GNU test failed: tests/tail/truncate. tests/tail/truncate is passing on 'main'. Maybe you have to rebase?

@zhitkoff
Copy link
Contributor Author

zhitkoff commented Nov 2, 2023

@tertsdiepraam looks like it is good to merge. The GNU test failures are unrelated - something is not right with tail

@sylvestre sylvestre force-pushed the split-suffix-length-refactor branch from 6f12c33 to 62887c7 Compare November 2, 2023 16:17
Copy link

github-actions bot commented Nov 2, 2023

GNU testsuite comparison:

Congrats! The gnu test tests/rm/rm2 is no longer failing!
Skip an intermittent issue tests/rm/rm1

@cakebaker cakebaker merged commit f8c474e into uutils:main Nov 3, 2023
@cakebaker
Copy link
Contributor

Thanks!

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.

3 participants