Skip to content

Commit e6ba16d

Browse files
authored
Add Helpful Message Regarding Windows Symlink (#129)
1 parent d312abb commit e6ba16d

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
restore-keys: |
9191
${{ runner.os }}-cargo-test-
9292
93-
- run: task test -- --nocapture
93+
- run: task test
9494

9595
clippy:
9696
runs-on: ubuntu-latest

src/main.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
#[cfg(windows)]
2+
use std::os::windows;
13
use std::{
2-
fs::create_dir_all,
4+
fs,
35
path::{Path, PathBuf},
46
};
57

6-
use anyhow::Result;
8+
use anyhow::{bail, Result};
79
use clap::{AppSettings, Parser, ValueHint};
810

911
use crate::subcommand::{
@@ -12,9 +14,9 @@ use crate::subcommand::{
1214
};
1315

1416
mod archives;
17+
mod files;
1518
mod node_version;
1619
mod subcommand;
17-
mod files;
1820

1921
#[derive(Parser, Clone, Debug)]
2022
enum Subcommands {
@@ -95,7 +97,7 @@ impl Config {
9597

9698
fn ensure_dir_exists(path: &Path) {
9799
if !path.exists() {
98-
create_dir_all(path)
100+
fs::create_dir_all(path)
99101
.unwrap_or_else(|err| panic!("Could not create {:?} - {}", path, err));
100102

101103
println!("Created nvm dir at {:?}", path);
@@ -106,12 +108,43 @@ fn ensure_dir_exists(path: &Path) {
106108
}
107109
}
108110

111+
#[cfg(windows)]
112+
const SYMLINK_ERROR: &str = "You do not seem to have permissions to create symlinks.
113+
This is most likely due to Windows requiring Admin access for it unless you enable Developer Mode.
114+
115+
Either run the program as Administrator or enable Developer Mode:
116+
https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development#active-developer-mode
117+
118+
Read more:
119+
https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10";
120+
121+
#[cfg(windows)]
122+
fn ensure_symlinks_work(config: &Config) -> Result<()> {
123+
let target_path = &config.get_dir().join("test");
124+
125+
if windows::fs::symlink_dir(&config.get_shims_dir(), target_path).is_err() {
126+
bail!("{SYMLINK_ERROR}");
127+
}
128+
129+
fs::remove_dir(target_path).expect("Could not remove test symlink...");
130+
131+
Ok(())
132+
}
133+
109134
fn main() -> Result<()> {
110135
let config: Config = Config::parse();
136+
#[cfg(windows)]
137+
let is_initial_run = !config.get_dir().exists();
111138

112139
ensure_dir_exists(&config.get_dir());
113140
ensure_dir_exists(&config.get_versions_dir());
114141

142+
#[cfg(windows)]
143+
if is_initial_run {
144+
let result = ensure_symlinks_work(&config);
145+
result?;
146+
}
147+
115148
match config.command {
116149
Subcommands::List(ref options) => ListCommand::run(&config, options),
117150
Subcommands::Install(ref options) => InstallCommand::run(&config, options),

0 commit comments

Comments
 (0)