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

fix: normalizing a relative path returns an absolute path #251

Merged
merged 6 commits into from
Oct 21, 2021

Conversation

itmecho
Copy link
Contributor

@itmecho itmecho commented Oct 5, 2021

This PR is an attempt to fix #250 which came from this issue in telescope: nvim-telescope/telescope.nvim#1171

The issue is that when a file contains ..., it ends up prefixed with a / (probably different on windows but I can't test that). This is a valid filename in frameworks like NextJS (example)

The change I made to path.lua fixes the issue apart from when the paths also has .. segments. I could use some help figuring that part out. I think it's to do with path.root() but I'm not too sure why the behaviour is affected by the filename as I'm on linux and from what I can tell, that will always return /?

Todo

  • Properly normalize files containing ..., i.e. dir1/[...test].ts
  • Properly normalize files containing both ... and .. segments, i.e. dir1/dir2/../[...test].ts

This still doesn't work for paths containing both .. parts as well as
...
@itmecho
Copy link
Contributor Author

itmecho commented Oct 5, 2021

OK so it's when it finds paths containing .., it prepends the root to the path here

out_file = path.root(filename) .. table.concat(parts, path.sep)

@itmecho itmecho changed the title path: fix for normalizing files including ... [WIP] path: fix for normalizing files including ... Oct 5, 2021
@itmecho itmecho marked this pull request as draft October 5, 2021 20:07
@itmecho
Copy link
Contributor Author

itmecho commented Oct 5, 2021

Maybe I misunderstood, I don't think it's actually a problem with files containing ... although that highlights the actual issue.

I think it's whenever a path has a .. segment, it ends up normalizing differently to if it doesn't have a .. segment, even if they should be the same path:

:lua print(require('plenary.path'):new('dir1/test.txt'):normalize())
dir1/text.txt

:lua print(require('plenary.path'):new('dir1/dir2/../test.txt'):normalize())
/dir1/text.txt

Does anyone know why that logic prepends the path.root()?

@itmecho itmecho changed the title [WIP] path: fix for normalizing files including ... [WIP] fix: normalizing relative paths gives different result depending on whether the path contains .. Oct 5, 2021
@itmecho
Copy link
Contributor Author

itmecho commented Oct 5, 2021

OK I moved the is_absolute logic to the top of the file and then use it to check if the filename is absolute. Now it will only return an absolute path is the input filename is absolute.

All tests pass including the 2 new ones I added for testing relative paths

@itmecho itmecho marked this pull request as ready for review October 5, 2021 21:29
@itmecho itmecho changed the title [WIP] fix: normalizing relative paths gives different result depending on whether the path contains .. fix: normalizing a relative path returns an absolute path Oct 5, 2021
@itmecho
Copy link
Contributor Author

itmecho commented Oct 5, 2021

Also tested it with telescope and it now correctly opens a file named pages/api/auth/[...nextauth].ts which it wasn't doing before

@Conni2461
Copy link
Collaborator

I dont know why this was added with this PR #140

Your changes look good to me. Can you fix stylua? Ignore the other CI we dont have a nightly image to pull (again)

@itmecho
Copy link
Contributor Author

itmecho commented Oct 6, 2021

Done!

@Conni2461
Copy link
Collaborator

Conni2461 commented Oct 6, 2021

Okay i thought about this again and i think that easy. Example i am in /home/conni and do this little script.

local Path = require"plenary.path"

local p = Path:new("../../usr/local/share/nvim/runtime/lua/../autoload/ada.vim")
print(vim.inspect(p))
print(p:normalize())

I expect normalize to be /usr/local/share/nvim/runtime/autoload/ada.vim (and it is on master) after your patch its usr/local/share/nvim/runtime/autoload/ada.vim

Edit: In the object we have the correct value under _absoulte thanks to uv.fs_realpath but that also resolves symbolic links and we dont want to do that.

@Conni2461
Copy link
Collaborator

The whole path lib is long overdue for a refactor and splitup into something different. We shouldnt run fs_realpath on every new path object. It should be more lightweight. But thats a story for another day.

@itmecho
Copy link
Contributor Author

itmecho commented Oct 6, 2021

Ah I didn't think of that =\ I'm not sure how you'd know that it should be absolute in that case without comparing it to _absolute in some way?

@Conni2461
Copy link
Collaborator

comparing against _absolute is also not a solution. Imagine we have this file. /home/conni/link which is a symbolic link to a file /usr/bin/bash then _absolute will be /usr/bin/bash. The current path object just has flaws we need to work around right now, to fix the bug and then we can rework everything and take our time to do something better (or worse) 😆

What we could do is count parts of _cwd (which is absolute) and see how many parts are taken away from the beginning. So if _cwd has two parts (/home/conni) and input has ../../ at the beginning (aka two parts or more should also be valid) then we need to append / and remove those parts otherwise if it only have one ../ we only need to remove it.

Does this make sense?

@itmecho
Copy link
Contributor Author

itmecho commented Oct 6, 2021

Got you! I'll have a crack at it

This should return an absolute path if the initial .. count matches the
number of parts in the cwd (Path:_cwd)
@itmecho
Copy link
Contributor Author

itmecho commented Oct 6, 2021

OK I think I've got it working now! All previous tests pass and I added two more which should cover the cases you found

@itmecho
Copy link
Contributor Author

itmecho commented Oct 18, 2021

@Conni2461 don't want to bother you but is there anything I can do to help this along?

Copy link
Collaborator

@Conni2461 Conni2461 left a comment

Choose a reason for hiding this comment

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

Sorry i forgot about it 😬

i think this looks good to me but i am not 100% sure its the most optimal solution. We can just try it out 😆

@Conni2461 Conni2461 merged commit de5acdc into nvim-lua:master Oct 21, 2021
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.

Path:normalize() breaks when path contains ...
2 participants