Skip to content

Commit

Permalink
fix(node-maintainer): return a more useful error message when symlink…
Browse files Browse the repository at this point in the history
…/junction creation both fail on Windows (#270)

Ref: #267
  • Loading branch information
zkat committed May 21, 2023
1 parent e7d0d12 commit e254c39
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
26 changes: 26 additions & 0 deletions crates/node-maintainer/src/error.rs
Expand Up @@ -107,6 +107,32 @@ pub enum NodeMaintainerError {
#[diagnostic(transparent)]
NassunError(#[from] nassun::NassunError),

/// Failed to create either a symlink or a junction while linking
/// dependencies using the isolated linker.
///
/// This can happen if the user does not have permission to create
/// symlinks on a Windows system, and the fallback junction operation
/// fails for some reason--likely because junctions are also unsupported.
///
/// Since only administrator-elevated users can create symlinks on
/// Windows, the best workaround for this issue is to switch to the
/// hoisted linker.
///
/// In Orogene, this is the `--hoisted` flag, or `options { hoisted true;
/// }` in oro.kdl.
#[cfg(windows)]
#[error("Failed to create either a symlink or junction from {} to {}.", .0.display(), .1.display())]
#[diagnostic(
code(node_maintainer::junctions_not_supported),
url(docsrs),
help("The isolated linker requires your Windows user to either be able to create symlinks, which requires Administrator privileges, or create junctions, which require an NTFS filesystem, among other things. If you see this message, you might consider switching to the 'hoisted' linker instead.")
)]
JunctionsNotSupported(
std::path::PathBuf,
std::path::PathBuf,
#[source] std::io::Error,
),

#[cfg(target_arch = "wasm32")]
/// Generic error returned from Nassun.
#[error(transparent)]
Expand Down
4 changes: 3 additions & 1 deletion crates/node-maintainer/src/linkers/isolated.rs
Expand Up @@ -569,7 +569,9 @@ async fn link_deps(
// We don't check the link target here because we assume prune() has already been run and removed any incorrect links.
#[cfg(windows)]
std::os::windows::fs::symlink_dir(&relative, &dep_nm_entry)
.or_else(|_| junction::create(&dep_store_dir, &dep_nm_entry)).io_context(|| format!("Failed to create symlink or juncion for dependency, from {} to {}.", dep_store_dir.display(), dep_nm_entry.display()))?;
.or_else(|_| junction::create(&dep_store_dir, &dep_nm_entry)).map_err(|e| {
NodeMaintainerError::JunctionsNotSupported(dep_store_dir, dep_nm_entry, e)
})?;
#[cfg(unix)]
std::os::unix::fs::symlink(&relative, &dep_nm_entry).io_context(|| format!("Failed to create symlink while linking dependency, from {} to {}.", relative.display(), dep_nm_entry.display()))?;
}
Expand Down

0 comments on commit e254c39

Please sign in to comment.