-
Notifications
You must be signed in to change notification settings - Fork 14
Description
I love linklocal
😄. I'd like to use it as part of our toolset in splitting up my team's large JS codebase into smaller packages. I'm a big fan of using local links and avoiding global version clobbering/hell.
However, a lot of my team members run Windows for their dev environments, and in Windows there are multiple link-like file system entities (hard links, symbolic links and junctions). They're also a less commonly used feature in Windows (e.g. Explorer creates 'shortcuts', not symlinks, hard links or junctions). I'm not an expert on Windows filesystem security settings, but it appears that the following bad experience happens in Windows.
- If your account is marked as a member of the Administrators group
- and User Account Control is enabled (the security system that prompts you for admin actions)
- then you cannot create symbolic link entities in Windows.
Non-admin users also cannot create "symbolic links" by default, but they can be granted the permission.
References:
- https://en.wikipedia.org/wiki/NTFS_junction_point
- https://en.wikipedia.org/wiki/NTFS_symbolic_link
- MSDN documentation on which privileges are required to create symbolic links
- MSDN documentation on how UAC affects privileges
I believe this is the default state for the first user account on Windows, and a likely configuration for developers. While there are workarounds (disable UAC, add link privilege for non-admin accounts), I believe it's in the spirit of linklocal to support isolated execution (e.g. running as non-admin so that machine globals cannot be touched).
Investigation
I did some preliminary investigation, and the use of junctions on Windows seems to work in this scenario and not require elevation. Switching to "all junctions all the time" on Windows is easy by removing the OS version check from this line:
if (os.platform()=='win32' && parseInt(os.release())<6) {
So that the if-block is the same for all versions of Windows.
Verification
- Configuration
- Windows 10 64-bit OS, NTFS file system
- 64-bit NodeJS v0.12.9
- NPM v3.5.2 (I saw that the travis.yml bootstraps latest NPM)
- User in administrator group, but command line is unelevated
- Verified that existing linklocal tests fail
npm test
- Verified that switching to junctions allows for tests to pass in the non-elevated config
- Verified that node module loader identity resolution succeeds for link type = junction. Specifically... given:
- pkgA/node_modules/pkgB/node_modules/pkgD/
- pkgA/node_modules/pkgC/node_modules/pkgD/
- where both paths are actually junctions of some other path ([root]/pkgD)
- then Node runtime unifies and recognises that all paths are actually the same module. Any variables and side effects are shared and acted upon the same pkgD, instead of separate copies. In otherwards, the linked paths act as if NPM had dedupe'd them, without having to move the paths.
Open Questions:
- Do you consider the use of junctions all the time in Windows a small change or a breaking change?Since junctions are interpreted as symbolic links in the Node runtime, it does not seem to be a significant break. Of course, native node modules can call Windows APIs and observe the difference.
I'm happy to chip in, but I think it'd be great to hear what kind of fix would be desired for this (e.g. just changing to junctions, or maybe adding a switch to explicitly specify the link type for Windows)