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

"Experimental" fs.cp(), fs.cpSync(), fsPromises.cp() methods don't handle recursion when there is a filter #49092

Closed
lll000111 opened this issue Aug 10, 2023 · 6 comments · Fixed by #49289
Labels
fs Issues and PRs related to the fs subsystem / file system.

Comments

@lll000111
Copy link

lll000111 commented Aug 10, 2023

Version

18.17.0

Platform

Windows

Subsystem

No response

What steps will reproduce the bug?

Any simple recursive call to cp to recursively copy a director, when there is a filter that does not always return true

I used

    await cp('src', 'lib', {
        recursive: true,
        filter: (source, _destination) => {
            console.log(source, _destination, source.endsWith('.css'));
            return source.endsWith('.css');
        }
    });

to copy only .css files after creating "lib/" from "src/" with tsc in a React JSX library project, and it stopped right at the top level directory.

I also checked non-promise cp() and cpSync().

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

Expected: Recurse over all files and subdirectories no matter what the filter function returns

What do you see instead?

Recursion stops completely when the filter function returns false. The rest of the not yet visited files and sub directories are ignored and not handled.

Additional information

Note: All directories are definitely present since my example use case copies CSS files from src/ into lib/ after compiling the project with tsc. However, this leaves open the question of what would happen if the destination directory does not exist? Feature question: When using a filter it's possible to skip directories. Of course, one could ask the programmer to handle directories and return true in such cases? Or would it also be okay to add a feature to create any missing directories? Not sure how it behaves right now. In any case, that's only an additional consideration and not the issue of this... issue.

@lll000111
Copy link
Author

Related: #44598

@VoltrexKeyva VoltrexKeyva added the fs Issues and PRs related to the fs subsystem / file system. label Aug 10, 2023
@aduh95
Copy link
Contributor

aduh95 commented Aug 10, 2023

@nodejs/fs

@LiviaMedeiros
Copy link
Contributor

Currently, options.filter() is applied to both directories and files. Falsey value returned for directory means that it won't be copied nor traversed. 'src'.endsWith('.css') === false, hence the src directory itself is not traversed.
To achieve copying the whole directory structure but filtering non-directories, something like this would work:

    await cp('src', 'lib', {
        recursive: true,
-       filter: (source, _destination) => {
+       filter: async (source, _destination) => {
            console.log(source, _destination, source.endsWith('.css'));
-           return source.endsWith('.css');
+           return (await lstat(source)).isDirectory() || source.endsWith('.css');
        }
    });

If this is a very common usecase, we might consider adding some sort of options.filterUsingStats() that will take objects rather than path strings. It would make isDirectory() check simpler, and allow cp() to avoid calling stat twice on dirents that pass the filter.

@lll000111
Copy link
Author

I'd be okay with the current function — if the documentation made that clear. Right now it only says "Function to filter copied files/directories. Return true to copy the item, false to ignore it.", and while technically not traversing can be seen as ignoring, I think it should be stated explicitly.

@aduh95
Copy link
Contributor

aduh95 commented Aug 11, 2023

Would you like to send a PR to update the docs?

@shubham9411
Copy link
Contributor

Hi @aduh95, I have added a PR for updating the docs for this. #49289

aduh95 pushed a commit that referenced this issue Aug 26, 2023
PR-URL: #49289
Fixes: #49092
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
UlisesGascon pushed a commit that referenced this issue Sep 10, 2023
PR-URL: #49289
Fixes: #49092
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
alexfernandez pushed a commit to alexfernandez/node that referenced this issue Nov 1, 2023
PR-URL: nodejs#49289
Fixes: nodejs#49092
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
targos pushed a commit that referenced this issue Nov 27, 2023
PR-URL: #49289
Fixes: #49092
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
sercher added a commit to sercher/graaljs that referenced this issue Apr 25, 2024
PR-URL: nodejs/node#49289
Fixes: nodejs/node#49092
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
sercher added a commit to sercher/graaljs that referenced this issue Apr 25, 2024
PR-URL: nodejs/node#49289
Fixes: nodejs/node#49092
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants