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

install: fix issue #3814 #3950

Merged
merged 11 commits into from
Dec 6, 2022
Merged

Conversation

bruecke
Copy link
Contributor

@bruecke bruecke commented Sep 17, 2022

This pull request fixes the the issue mentioned in #3814, so installing multiple files using the "create leading dirs" option combined with the target parameter is now working and the GNU test is passing.

Furthermore this PR fixes more issues:

  1. The verbose option, when using -D, was printing all directories to stdout, instead of only the missing ones.
  2. Also installing only a single file using -Dt is now working as expected.
  3. Installing a single file into a destination file, but the source being a directory, did not fail with the correct error message.
  • Copy GNU test case
  • Add testcase to verify the correct behaviour

@sylvestre
Copy link
Contributor

I guess you saw:


---- test_install::test_install_creating_leading_dirs_with_single_source_and_target_dir stdout ----
current_directory_resolved: 
touch: /tmp/.tmpOS9IXF/source_file_1
run: /home/runner/work/coreutils/coreutils/target/debug/coreutils install -D source_file_1 /tmp/.tmpOS9IXF/missing_target_dir/
thread 'test_install::test_install_creating_leading_dirs_with_single_source_and_target_dir' panicked at ''install: cannot install 'source_file_1' to '/tmp/.tmpOS9IXF/missing_target_dir/': Is a directory
' does not contain 'missing_target_dir/' is not a directory'', tests/common/util.rs:420:9

Copy link
Contributor

@sylvestre sylvestre left a comment

Choose a reason for hiding this comment

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

ping?

@bruecke
Copy link
Contributor Author

bruecke commented Oct 4, 2022

I guess you saw:


---- test_install::test_install_creating_leading_dirs_with_single_source_and_target_dir stdout ----
current_directory_resolved: 
touch: /tmp/.tmpOS9IXF/source_file_1
run: /home/runner/work/coreutils/coreutils/target/debug/coreutils install -D source_file_1 /tmp/.tmpOS9IXF/missing_target_dir/
thread 'test_install::test_install_creating_leading_dirs_with_single_source_and_target_dir' panicked at ''install: cannot install 'source_file_1' to '/tmp/.tmpOS9IXF/missing_target_dir/': Is a directory
' does not contain 'missing_target_dir/' is not a directory'', tests/common/util.rs:420:9

Sorry for the late reply. Was a little busy.

Yes I know of this. The problem has been there before: When a non-existing directory path is given as target ending on a '/', the install command fails, but with a wrong error message. At least it is not the same as the original GNU install does.
This test only uncovers that problem.

I also already have a fix for unix systems. I will push it now.
Do we need to support "install" also on windows?

@tertsdiepraam
Copy link
Member

Install is currently unix-only. You can check that in the docs (https://uutils.github.io/coreutils-docs/user/utils/install.html, icons in the top right). Or in the global Cargo.toml, though it is a bit hard to read.

@sylvestre
Copy link
Contributor

But I wonder if there is a good reason not to run on Windows?

@bruecke bruecke requested a review from sylvestre October 15, 2022 13:00
@bruecke
Copy link
Contributor Author

bruecke commented Oct 15, 2022

Install is currently unix-only. You can check that in the docs (https://uutils.github.io/coreutils-docs/user/utils/install.html, icons in the top right). Or in the global Cargo.toml, though it is a bit hard to read.

I've that seen in the Cargo.toml, but I also think that I've found some special test cases for Windows - something about very long filenames or so. Therefore I was unsure.
Nonetheless with the latest commit it should also work on any non-Unix platform. It is probably slower than the Unix-solution and I was not able to test it yet.

Can this pull request be merged then?

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/install/create-leading is no longer failing!
Congrats! The gnu test tests/rm/rm2 is no longer failing!
GNU test failed: tests/misc/tee. tests/misc/tee is passing on 'main'. Maybe you have to rebase?

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/install/create-leading is no longer failing!
Congrats! The gnu test tests/rm/rm2 is no longer failing!

@bruecke
Copy link
Contributor Author

bruecke commented Oct 15, 2022

While trying to increase the code coverage, I tried some more test cases and compared them with the orig. GNU install.
Turns out it was not behaving the same. I will push another commit next.

Here's the test code to try it our yourself:

export C=coreutils/target/debug/

rm -rf dir1 no-dir2 dir3 file

mkdir -p dir1 dir3
touch file

${C}install file dir1 no-dir2 # fails w/ "is not a directory"
${C}install file dir1 dir3    # fails w/ "omitting directory", but copies file first
${C}install dir1 dir3         # fails w/ "omitting directory"
${C}install dir1              # fails w/ "missing destination file operand", then prints usage
${C}install                   # fails w/ "missing file operand", then prints usage
${C}install -D -t no-dir2     # fails w/ "missing file operand", then prints usage
                              # and does not create target dir

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/install/create-leading is no longer failing!

Code was missing the logic to create the target dir when multiple files
should be copied and target dir is given by -t option.
This simplifies the copy logic also when only one file should be copied
to the target dir.
Also adds a unit test to verify the same behaviour as the gnu tools.
Tests various combinations of "-D" with and w/o "-t" when installing
either a single file or multiple files into a non existing directory.

  install -D file1 file2 (-t) not_existing_dir
  install -D file1 (-t) not_existing_dir/

Also fixes file formatting, spelling and adds some more test asserts.
The install command failed with a different error message than the
original GNU install tool. Checking for a trailing slash fixes this.
Only works on unix though.
This increases the CI test coverage and also checks for more corner
cases to ensure uu_install is compliant with GNU's original.

    export C=coreutils/target/debug/

    rm -rf dir1 no-dir2 dir3 file
    mkdir -p dir1 dir3
    touch file

    ${C}install dir1/file1 dir1/.. no-dir2
    ${C}install dir1/file1 dir1/.. dir3
    ${C}install dir1/.. dir3
Also check that install returns the correct error messages, when only a
target directory is given via -t and that is is not created (-D option).
This ensures correct (GNU install like) behavior. Tests from the last
commit will pass now.
@sylvestre sylvestre force-pushed the install_fix_issue_#3814 branch from 9ede8f8 to ea8dd62 Compare October 22, 2022 08:23
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/install/create-leading is no longer failing!

1 similar comment
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/install/create-leading 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.

Just one question, otherwise ready to be merged I think! Sorry for taking so long :)

#[cfg(not(unix))]
fn is_potential_directory_path(path: &Path) -> bool {
let path_str = path.to_string_lossy();
path_str.ends_with(MAIN_SEPARATOR) || path_str.ends_with('/') || path.is_dir()
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if the second case here is really expected behaviour. Does windows accept trailing / in paths?

Copy link
Contributor

Choose a reason for hiding this comment

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

ping ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just one question, otherwise ready to be merged I think! Sorry for taking so long :)

No worries! We all have personal lives sometimes :)

I'm wondering if the second case here is really expected behaviour. Does windows accept trailing / in paths?

AFAIK it does. I'm not sure, whether that is a valid delimiter in the standard cmd.exe or powershell already, or if this is only allowed when you use a MinGW or Git-bash shell. Nonetheless you can find the same check already in here uucore::features::fs::canonicalize().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

    let has_to_be_directory =
        (miss_mode == MissingHandling::Normal || miss_mode == MissingHandling::Existing) && {
            let path_str = original.to_string_lossy();
            path_str.ends_with(MAIN_SEPARATOR) || path_str.ends_with('/')
        };

Copy link
Member

Choose a reason for hiding this comment

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

Alright! Sounds good. We can merge this if you fix the conflicts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The branch is now up to date. Still merging is not possible.
Am I missing something @sylvestre and @tertsdiepraam ?

Copy link
Member

@tertsdiepraam tertsdiepraam Dec 6, 2022

Choose a reason for hiding this comment

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

Maybe the main of your repo is not up to date with the upstream one? I usually do something like this to ensure my main is set to the upstream one:

git switch main
git fetch upstream
git reset --hard upstream/main

Note: this will delete any changes on your local main

Copy link
Member

Choose a reason for hiding this comment

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

Nevermind, merging is blocked because of the requested changes by @sylvestre, it doesn't have anything to do with git.

@github-actions
Copy link

github-actions bot commented Dec 5, 2022

GNU testsuite comparison:

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

@sylvestre sylvestre merged commit 42b9b7b into uutils:main Dec 6, 2022
@sylvestre
Copy link
Contributor

yeah, thanks, approved!

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