-
Notifications
You must be signed in to change notification settings - Fork 12
Dep.path on a file inside a symlinked directory doesn't work #25
Comments
Thank you for any help you can provide on this issue. We chose to pursue Jenga because (among other things) it handles symlinks in every other respect aside from this issue. |
We're looking at a fix. If this is blocking you, I suppose changing this code from fs.ml:
to |
Thank you @sliquister. We will try this. |
Tested and works. Thanks @sliquister! I guess I'll keep this issue open since maintaining a fork with a single change doesn't solve it for others =). |
@sliquister : This is really great, thank you. Would you mind pushing an update to |
Update: seems to only work with absolute path symlinks. If the symlink is relative, and points to somewhere above the root, we get the (somewhat expected) error:
|
I made the change, not sure how long it takes before it shows up here. I'm guessing a few days with the bleeding edge packages, I don't know about the stabler ones. About the symlink to outside the root, this is intentional and it's not specific to symlinks. We just don't want dependencies on the location of the repository, so the repository can be relocated without causing rebuilds. |
@sliquister : I'm curious how preventing relative symlinks helps this. Relative symlinks are really helpful because it actually allows me to check in several packages into a repo that should all interconnect via symlinks, but then also check in those symlinks into the repo (because they're relative, they won't be committed as absolute paths to my hard drive directories). That means I can create a repo that has: This isn't a contrived use case because we actually hit this lack of support for relative symlinks while building a project that had the above configuration. |
To be clear, it's not relative symlinks that are problematic, it's any relative dependency, so long as they reach outside the root. Maybe avoiding rebuilds is not the right reason. Still
I'm confused about your example: since you have a single repository that contains /packages/Package1 and /packages/Package2, you can have the jengaroot in /packages rather than in /packages/Package2, and then the symlinks stay below the root. And in fact I don't see what the symlinks are needed for. |
About the failure:
This will come, for example, if jengaroot executes:
The error is intended to block what we consider a probable user bug: forming a path by ".."ing w.r.t. a repo-root-relative path which reaches above the root of the repo. We did consider, but decided against, returning the absolute path. However, this appears to be exactly what you want in this situation... Good news. It's easy to get the the behaviour you want by jumping through just a tiny hoop:
|
@sliquister
The reason is that each package should have its own jengaroot. |
@Nick-Chapman I'm forming some deps through |
At the heart of the matter, jenga's support for symlinks is at best flaky. Changing [follow_links:true] just makes jenga use [stat] instead of [lstat]. This might be better for your purposes, but wont work properly in polling jenga if the link is repointed. The proper solution requires jenga to track the dependencies at each stage of a symlink chain. I believe Leo started some work a while back to make this work properly. I'm not sure if there was something blocking its completion, or if it just dropped down the priority stack since we tend to avoid symlinks at JS. |
Actually it might not just be polling jenga which is broken by using stat instead of lstat. |
Sorry. The close issue was just my fat fingers. |
I think changing all |
Actually, Arseniy already did quite a bit of work on symlinks and the support is now pretty reasonable. This file describes the current state of symlink support. |
If you want to work around your issue I would suggest changing stat (Path.relative_or_absolute ~dir link_destination) in the let abs_dir = Path.absolute (Path.to_absolute_string dir) in
stat (Path.relative_or_absolute ~dir:abs_dir link_destination) I haven't tested this solution, but I reckon it should work. This should force all links to be considered as pointing to an absolute path. This will allow your use case, but it means that there will be more absolute paths in the database so moving it will require more recompilation. |
@lpw25 Is there any reason why this should not be upstreamed? If this is something that would not get in the way of your workflow, we would like to avoid maintaining a fork of |
It is something that would get in the way of our workflow unfortunately. We work hard to have very few absolute paths in our builds, and this would noticeably damage that. A more subtle fix, which only uses absolute paths when the path reaches outside the root, would probably be alright. |
Okay, that's reasonable. I'm curious, does it get in the way of your workflow because you move directories around on disk frequently? |
I'm not sure about frequently, but it is useful to be able to move a directory without suddenly needing to rebuild the world. It's possible some of our CI stuff relies on it. |
Avoiding recompilation is only part of the issue. Avoiding absolute paths is necessary to be able to reproduce exactly the same build artifacts. We don't actually achieve perfect build determinism, but we like to get closer where we can. |
Actually, maybe this doesn't affect build determinism because these path never leak to build rules. Even stronger, I don't think they ever end up in the database so recompilation should not be affected either. Leo, you seem to have reached a different conclusion? |
Ah yes, you are right that it does not reach the database. Only the in-memory memoization tables see the path. It would still be slightly better to treat paths inside the root properly as it would mean fewer calls to stat, but it is not particularly important. |
So to recap, there would be no objection to upstreaming a change that would convert to absolute paths only if the directories are symlinks? |
Yes I think it would be fine |
Say I have
top/foo/a.txt
wherefoo/
is symlinked, creating a dependency on the path fails:Discussion:
cc @lpw25
The text was updated successfully, but these errors were encountered: