storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.14k stars 9.25k forks source link

[Bug]: infinite paths on Add a new story: ENAMETOOLONG. Function unavailable #28227

Open haraldrudell opened 3 months ago

haraldrudell commented 3 months ago

Describe the bug

When attempting to document a new component, component search fails

BUG: A large RED popup window with white text beginning An error occurred while searching for components in the project. ENAMETOOLONG: name too long, scandir '/

IMPACT: No components can be documented using the UI may occur for any user on any host

SYMPTOMTS: —1 the paths listed are away from the project directory but in the root file-system directory in which the project is located —2 Storyboard is for some reason scanning directories outside the project directory —3 The BUG can occur for any user on any host

Apparently, scanning is not filtered for cyclic symbolic paths. A map of absolute paths is going to be required file systems do not guarantee the path to a particular node being unique even when symlinks are resolved, so a limit on recursion must be implemented, like Go limits to 100 symlinks

CAUSE: some permitted use of symlinks in the file system that Storybook decides to scan but is unable to successfully complete

Reproduction link

N/A

Reproduction steps

install vanilla storybook on browser Storybook page, click +next to Find Components search box In lightbox Add a new story ./components/*/.tsx search box, type a character

System

macOS 14.5 vite React Storybook 8.1+

Additional context

No response

haraldrudell commented 3 months ago

Appears to be caused by, in this case, a Go project having a fakeGoPATH directory structure eventually symlinked back to its own go.mod in a relative parent directory ls -l … xyz -> ../../../..

I think this was something before Go modules became widely used

What one could do here is to model that scandir code on Go’s filepath.EvalSymlinks https://pkg.go.dev/path/filepath#EvalSymlinks @Google wrote that, it works

this code here walks anything avoiding recursion from cyclic paths. It doesn’t include the latest learnings but won’t crash I don’t know for anybody else doing this. Like @Facebook doesn’t https://pkg.go.dev/github.com/haraldrudell/parl@v0.4.184/pfs#Traverser

walking symlinks is a huge problem space

This code could be easily transpiled to ECMAScript and it will work every time

shilman commented 3 months ago

@valentinpalkovic I am able to reproduce this in a sandbox:

  1. Remove /sandbox from .gitignore
  2. Run the sandbox and search for button => it will return a bunch of results
  3. Link a parent directory ln -s ../../.. boom
  4. Run the sandbox and search for button => it will hang -- I think it is traversing the symlink infinitely

I tried adding the following options to globby but it did not fix the problem:

    followSymbolicLinks: false,
    onlyFiles: true,

When I remove gitignore: true from the options:

  1. It does fix the problem (followSymLinks is respected)
  2. The glob runs twice as fast (500ms vs 1000+ms with gitignore)

Therefore it seems globby gitignore is buggy and also introduces a performance regression. I wonder if we can get a fix into globby?

valentinpalkovic commented 3 months ago

In my opinion, setting followSymbolicLinks: false wouldn't be an option. Symlinks are common, and when properly set up, they usually don't cause loops.

Since globby respects the user's gitignore, wouldn't a further entry in the gitignore file solve the issue by excluding the symlinked folder?

@shilman Also, could you experiment with the deep option? By default, it is set to Infinity. Maybe we should limit the folder depth to, for example, 100.

valentinpalkovic commented 3 months ago

@haraldrudell Just for context: We haven't implemented the glob search by ourselves, but we rely on the globby library. If you think cyclical symlinks should be treated in a different way, then I think it makes sense to open a bug report there, unless it is not configurable by globby itself.

shilman commented 3 months ago

@valentinpalkovic I don't think deep is a good solution. deep: 50 still blows up, and deep: 20 works but takes 10 seconds to complete a single search.

This bug is important to me because I want to use fileSearch as part of some telemetry and I need it to be performant. It would run on startup once per day (I'd cache the results). I suppose I could pass followSymbolicLinks: false JUST for the telemetry case and we could leave it to true for the search UI. But it's a bummer that gitignore doesn't play nice with followSymLinks.