Skip to content

Replace Windows symlinks with volta run scripts#1755

Merged
chriskrycho merged 3 commits intovolta-cli:mainfrom
charlespierce:no_symlinks_windows
Jul 9, 2024
Merged

Replace Windows symlinks with volta run scripts#1755
chriskrycho merged 3 commits intovolta-cli:mainfrom
charlespierce:no_symlinks_windows

Conversation

@charlespierce
Copy link
Copy Markdown
Contributor

@charlespierce charlespierce commented May 16, 2024

Closes #1397

Info

  • Huge kudos to @rcsilva83 and @Xstoudi for a bunch of iteration in No more symlinks on Windows #1552 on removing symlinks for Windows, to allow dropping the requirement for Developer Mode.
  • Based on discussions in that PR, we had a new idea for replacing symlink shims on Windows by using scripts that call volta run <package>.
  • This is a first-pass implementation of creating simple script-based shims for executing 3rd-party binaries on Windows.
  • This should be a no-op for Unix.

Changes

  • Used junction to create NTFS junctions instead of directory symlinks (this part is directly copied from No more symlinks on Windows #1552)
  • Updated the shim module to have different implementations of create for Unix and Windows.
    • The Unix implementation is the same as it was before.
    • The Windows implementation creates a very simple .cmd script that calls volta run for the shim. It also continues to create a custom Git Bash script, though that script is updated to now call volta run directly, instead of calling the existing shim via cmd.exe
  • Create a new v4 layout since the shim file on Windows is now <binary>.cmd instead of <binary>.exe.
  • Created a migration to v4 that removes and regenerates the shims, making sure that the old symlinks are removed. The migration also updates any existing directory symlinks to use junctions as well.

Tested

  • Installed packages using the current Volta version (i.e. with symlinks).
  • Installed a new version of Volta based on these changes.
  • Verified that running the existing packages still works and that the shims were properly migrated.
  • Turned off developer mode.
  • Verified that even without developer mode, I could install and run new packages 🎉
  • Did some very basic performance tests, on my local machine I wasn't seeing any statistically significant differences between the symlink-based approach and the volta run approach ⚡

Using symlinks on Windows requires that our users enable Developer
mode, which isn't always possible. For directory links, there is an
easy solution: NTFS Junctions. These work the same as symlinks but
do not require administrator privileges nor developer mode.
Rather than using symlinks, which require administrator privileges
or developer mode on Windows, we can instead use small scripts that
call out to 'volta run' to actually handle the execution of 3rd
party binaries.

This also adds a migration to a new v4 layout, which allows Windows
installs to migrate immediately to using the script-based shims.
@charlespierce charlespierce force-pushed the no_symlinks_windows branch from 2ddbf4a to fa04c75 Compare May 16, 2024 06:26
@Xstoudi
Copy link
Copy Markdown

Xstoudi commented Jun 5, 2024

Hey @charlespierce, great work!

Did you find time to check how it affects performance?
How much time do you think is needed to merge/release? Tbh this is somehow a go/no-go to use Volta in entreprise-grade Windows environment.

I'd be happy to help if some more work is needed to go forward with it, let me know.

@charlespierce
Copy link
Copy Markdown
Contributor Author

Was able to get some testing done, and from what I can tell it doesn't have any major effect on performance, so this should be good to go 🎉

Comment on lines +95 to +102
pub fn shim_file(&self, toolname: &str) -> PathBuf {
// On Windows, shims are created as `<name>.cmd` since they
// are thin scripts that use `volta run` to execute the command
#[cfg(windows)]
let toolname = format!("{}{}", toolname, ".cmd");

path_buf!(self.shim_dir.clone(), toolname)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For posterity, this is the only difference between the v3 and v4 layouts, and this is the diff:

    pub fn shim_file(&self, toolname: &str) -> PathBuf {
-       path_buf!(self.shim_dir.clone(), executable(toolname))
+       // On Windows, shims are created as `<name>.cmd` since they
+       // are thin scripts that use `volta run` to execute the command
+       #[cfg(windows)]
+       let toolname = format!("{}{}", toolname, ".cmd");
+
+       path_buf!(self.shim_dir.clone(), toolname)
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dismiss the use of symlinks on Windows

3 participants