-
-
Notifications
You must be signed in to change notification settings - Fork 38
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: handle broken symbolic links that were listing as missing files #164
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks mostly good. I'll want to come up with a regression test for this case, to test keep coverage at 100%.
check_manifest.py
Outdated
broken_symlinks = set(existing_source_files_with_broken_simlinks) - set(existing_source_files) | ||
if broken_symlinks: | ||
ui.warning("some symbolic links listed as being under source control are pointing to missing files:\n%s" | ||
% format_list(["%s -> %s (missing)" % (x, os.path.realpath(x)) for x in broken_symlinks])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, is it better to use os.path.realpath(x) here, or is it better to use os.readlink(x) here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've switch to os.readlink
to try it but the result ended up being the same?
Apparently it can returns relative path sometime according to the documentation but I don't know when. I guess this will be more readable in some situations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the difference would be if you had two symlinks, like a -> b and b -> c. os.realpath('a') would return 'c', but os.readlink('a') would return 'b'.
But we know that in this case b doesn't exist, so it can't be a symlink to c.
How about symlinks to directories? a -> b/c, where b -> d, and d/c is missing. os.realpath('a') is 'd/c', and os.readlink('a') is 'b/c'. Which would be better to show in the error message?
To me readlink() feels a bit better.
6cc1261
to
fe7963c
Compare
I don't know how I managed to miss the test file 😅 I've added a test but I'm not fully sure I did it correctly and in the good section :/ |
fe7963c
to
8214954
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for the test!
Weirdly I cannot reproduce the GitHub Actions CI failure locally (with SKIP_NO_TESTS=1 FORCE_TEST_VCS=svn tox -e py310
).
For the Appveyor failures, see inline comments:
os.symlink(os.path.join(self.tmpdir, "some-file"), | ||
os.path.join(self.tmpdir, "some-symbolic-link")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seeing the Appveyor CI failure on Windows, I think
os.symlink(os.path.join(self.tmpdir, "some-file"), | |
os.path.join(self.tmpdir, "some-symbolic-link")) | |
os.symlink(os.path.join(self.tmpdir, "some-file"), "some-symbolic-link") |
might work better ...
os.unlink('some-file') | ||
check_manifest() | ||
self.assertIn("some symbolic links listed as being under source control are pointing to missing files:\n" | ||
f" some-symbolic-link -> {os.path.join(self.tmpdir, 'some-file')} (missing)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... because then you might be able to use
f" some-symbolic-link -> {os.path.join(self.tmpdir, 'some-file')} (missing)", | |
" some-symbolic-link -> some-file (missing)", |
here.
Of course, Windows being Windows, there's a chance that even relative symlinks will be converted into those weird absolute UNC paths, in which case plan B is
# On Windows os.readlink() returns weird UNC paths so we cannot hardcode os.path.join(self.tmpdir, "...") here
link_target = os.readlink(os.path.join(self.tmpdir, "some-symbolic-link"))
followed by using
f" some-symbolic-link -> {os.path.join(self.tmpdir, 'some-file')} (missing)", | |
f" some-symbolic-link -> {link_target} (missing)", |
here.
Hello,
This MR is to fix a hard to debug situation.
Consider this situation:
Later on:
This MR changes the output from:
To:
I'm not sure this is the best output so feel free to modify it.
As a side note, this MR doesn't handle this situation for the "missing from sdist" analysis and it should probably be added as you can tell from this screenshot:
Thanks a lot for this tool ❤️