nooooooom / merge-dirs

Node module for synchronously and recursively merging multiple folders or collections of files into one folder.
MIT License
3 stars 0 forks source link

Ignore Patterns for Nested Hidden Files? #3

Open jacobkossman opened 9 months ago

jacobkossman commented 9 months ago

I don't believe ignore patterns on nested hidden files work. For the below example the file .gitignore and .shopifyignore directly in the root of the base folder do not show up in the build folder but nested files such as base/sections/.gitkeep are still present within the build dest folder.

Am I missing something obvious in the glob?

    mergeDirs({
        targets: [
            {
                dest: '../build',
                src: [
                    '../base/*',
                    '../instance/*'
                ],
                ignore: [
                    '../**/node_modules/**',
                    '../**/package.json',
                    '../**/package-lock.json',
                    '../**/merge-dirs.js',
                    '../**/schematic.js',
                    '../**/*.config.js',
                    '../**/*.md',
                    '../**/*.txt',
                    '../**/src/**',
                    '../**/.github',
                    '../**/.vscode',
                    '../**/.gitignore',
                    '../**/.shopifyignore',
                    '../**/.gitkeep'
                ],
                flatten: true
            }
        ]
    });
nooooooom commented 9 months ago

I'll test your case and get back to you later, this may take a few minutes.

nooooooom commented 9 months ago

Hi, I have found the problem. In the usage of fast-glob, an asterisk (*) means matches everything except slashes (path separators), but this will only match the first level of nesting.

However, ignore based on the matched files, so when you enter '../base/*' to indicate the files you want to match, fast-glob will first find all files under base (only first level of nesting), such as base/sections, when it is filtered through the ignore option, there is no way to exclude base/sections/.gitkeep, because base/sections/.gitkeep does not appear in all matches among the files that came out.

So you need to change '../base/*' to '../base/**', which will let fast-glob find all files (any level of nesting), then base/sections /.gitkeep will take effect.

jacobkossman commented 9 months ago

I think there's something wrong specifically with hidden files inside a folder though.

Per your comment, I've updated it to ../base/** but it still (incorrectly) moves the .gitkeep files inside of folders. It moves everything else properly, even multiple levels deep when using ../base/* but will (correctly) not move a .gitkeep in the root of base or instance so I'm not sure what the issue is 🤔

nooooooom commented 9 months ago

Look here A double star or globstar (**) — matches zero or more directories.(https://github.com/mrmlnc/fast-glob?tab=readme-ov-file#basic-syntax). If you want to keep the files in the first-level files, you should configure the ignore option like this '../*/**/.gitkeep'.

If I don't fully understand what you mean, you can write down the special use cases in code. For example how do you need to move the file root/.gitignore -> dest/.gitignore, and you need to ignore the file root/.gitignore x-> dest/.gitignore.

nooooooom commented 9 months ago

I may have misunderstandings in terms of language.

jacobkossman commented 9 months ago

Apologies, it is confusing.

file structure:

-- base/
  -- folder1/
    -- file1.js
    -- file2.js
    -- folder3/
  -- folder2/

-- instance/
  -- folder1/
    -- .gitkeep
    -- file3.js
  -- folder2/
    -- .gitkeep
  .gitkeep
  .gitignore

the final structure should be:

-- build/
  -- folder1/
    -- file1.js
    -- file2.js
    -- file3.js
    -- folder3/
  -- folder 2/

but instead this is what happens:

-- build/
  -- folder1/
    -- .gitkeep
    -- file1.js
    -- file2.js
    -- file3.js
    -- folder3/
  -- folder 2/
    -- .gitkeep

note that the root .gitkeep is removed, but the nested ones are kept. it moves the .js files and folders correctly but nested hidden files do not seem to be detected regardless * vs **

nooooooom commented 9 months ago

Apologies, it is confusing.

file structure:

-- base/
  -- folder1/
    -- file1.js
    -- file2.js
    -- folder3/
  -- folder2/

-- instance/
  -- folder1/
    -- .gitkeep
    -- file3.js
  -- folder2/
    -- .gitkeep
  .gitkeep
  .gitignore

the final structure should be:

-- build/
  -- folder1/
    -- file1.js
    -- file2.js
    -- file3.js
    -- folder3/
  -- folder 2/

but instead this is what happens:

-- build/
  -- folder1/
    -- .gitkeep
    -- file1.js
    -- file2.js
    -- file3.js
    -- folder3/
  -- folder 2/
    -- .gitkeep

note that the root .gitkeep is removed, but the nested ones are kept. it moves the .js files and folders correctly but nested hidden files do not seem to be detected regardless * vs **

Thank you for your detailed report. It seems that the problem may occur in files that names starting with .. I will test the relevant use cases and will reply to you with my test results later.

nooooooom commented 9 months ago

I noticed that it was wrong for me to want users to understand the matching logic of fast-glob. I think no matter how the user writes the matching expression of the file path, I should try my best to meet the needs of recursive merging. I will update a new version later to improve this function, which includes the following functions:

This may take a while, I'm sorry for the inconvenience.