summaryrefslogtreecommitdiff
path: root/cli/ops
diff options
context:
space:
mode:
authorAli Hasani <a.hassssani@gmail.com>2020-05-19 03:16:02 +0430
committerGitHub <noreply@github.com>2020-05-19 00:46:02 +0200
commit6072755eadb7342a409f43260e5a17b956703a1c (patch)
tree35ec9b10eddafdc2b0dacecc439aa8d9f785529a /cli/ops
parent88b24261ba467c20d4ef90224b07c19a71398f0f (diff)
Implement Deno.symlink() for windows (#5533)
Diffstat (limited to 'cli/ops')
-rw-r--r--cli/ops/fs.rs40
1 files changed, 35 insertions, 5 deletions
diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs
index 068dbaf7e..9d5be3077 100644
--- a/cli/ops/fs.rs
+++ b/cli/ops/fs.rs
@@ -687,6 +687,15 @@ struct SymlinkArgs {
promise_id: Option<u64>,
oldpath: String,
newpath: String,
+ #[cfg(not(unix))]
+ options: Option<SymlinkOptions>,
+}
+
+#[cfg(not(unix))]
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct SymlinkOptions {
+ _type: String,
}
fn op_symlink(
@@ -710,13 +719,34 @@ fn op_symlink(
symlink(&oldpath, &newpath)?;
Ok(json!({}))
}
- // TODO Implement symlink, use type for Windows
#[cfg(not(unix))]
{
- // Unlike with chmod/chown, here we don't
- // require `oldpath` to exist on Windows
- let _ = oldpath; // avoid unused warning
- Err(OpError::not_implemented())
+ use std::os::windows::fs::{symlink_dir, symlink_file};
+
+ match args.options {
+ Some(options) => match options._type.as_ref() {
+ "file" => symlink_file(&oldpath, &newpath)?,
+ "dir" => symlink_dir(&oldpath, &newpath)?,
+ _ => return Err(OpError::type_error("unsupported type".to_string())),
+ },
+ None => {
+ let old_meta = std::fs::metadata(&oldpath);
+ match old_meta {
+ Ok(metadata) => {
+ if metadata.is_file() {
+ symlink_file(&oldpath, &newpath)?
+ } else if metadata.is_dir() {
+ symlink_dir(&oldpath, &newpath)?
+ }
+ }
+ Err(_) => return Err(OpError::type_error(
+ "you must pass a `options` argument for non-existent target path in windows"
+ .to_string(),
+ )),
+ }
+ }
+ };
+ Ok(json!({}))
}
})
}