Add option to metadata request to return the canonicalized path in the response; bump to 0.9.0

pull/38/head v0.9.0
Chip Senkbeil 3 years ago
parent d3a1cad7b3
commit 9a67418227
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

2
Cargo.lock generated

@ -179,7 +179,7 @@ dependencies = [
[[package]]
name = "distant"
version = "0.8.0"
version = "0.9.0"
dependencies = [
"bytes",
"derive_more",

@ -2,7 +2,7 @@
name = "distant"
description = "Operate on a remote computer through file and process manipulation"
categories = ["command-line-utilities"]
version = "0.8.0"
version = "0.9.0"
authors = ["Chip Senkbeil <chip@senkbeil.org>"]
edition = "2018"
homepage = "https://github.com/chipsenkbeil/distant"

@ -301,8 +301,17 @@ fn format_shell(res: Response) -> ResponseOut {
.collect::<Vec<String>>()
.join("\n"),
)),
ResponsePayload::Metadata { data } => ResponseOut::StdoutLine(format!(
ResponsePayload::Metadata {
canonicalized_path,
file_type,
len,
readonly,
accessed,
created,
modified,
} => ResponseOut::StdoutLine(format!(
concat!(
"Canonicalized Path: {:?}\n",
"Type: {}\n",
"Len: {}\n",
"Readonly: {}\n",
@ -310,12 +319,13 @@ fn format_shell(res: Response) -> ResponseOut {
"Last Accessed: {}\n",
"Last Modified: {}",
),
data.file_type.as_ref(),
data.len,
data.readonly,
data.created.unwrap_or_default(),
data.accessed.unwrap_or_default(),
data.modified.unwrap_or_default(),
canonicalized_path.unwrap_or_default(),
file_type.as_ref(),
len,
readonly,
created.unwrap_or_default(),
accessed.unwrap_or_default(),
modified.unwrap_or_default(),
)),
ResponsePayload::ProcEntries { entries } => ResponseOut::StdoutLine(format!(
"{}",

@ -1,7 +1,7 @@
use crate::core::{
constants::MAX_PIPE_CHUNK_SIZE,
data::{
self, DirEntry, FileType, Metadata, Request, RequestPayload, Response, ResponsePayload,
self, DirEntry, FileType, Request, RequestPayload, Response, ResponsePayload,
RunningProcess,
},
state::{Process, ServerState},
@ -58,7 +58,7 @@ pub(super) async fn process(
RequestPayload::Remove { path, force } => remove(path, force).await,
RequestPayload::Copy { src, dst } => copy(src, dst).await,
RequestPayload::Rename { src, dst } => rename(src, dst).await,
RequestPayload::Metadata { path } => metadata(path).await,
RequestPayload::Metadata { path, canonicalize } => metadata(path, canonicalize).await,
RequestPayload::ProcRun { cmd, args } => {
proc_run(tenant.to_string(), addr, state, tx, cmd, args).await
}
@ -280,35 +280,39 @@ async fn rename(src: PathBuf, dst: PathBuf) -> Result<ResponsePayload, Box<dyn E
Ok(ResponsePayload::Ok)
}
async fn metadata(path: PathBuf) -> Result<ResponsePayload, Box<dyn Error>> {
let metadata = tokio::fs::metadata(path).await?;
async fn metadata(path: PathBuf, canonicalize: bool) -> Result<ResponsePayload, Box<dyn Error>> {
let metadata = tokio::fs::metadata(path.as_path()).await?;
let canonicalized_path = if canonicalize {
Some(tokio::fs::canonicalize(path).await?)
} else {
None
};
Ok(ResponsePayload::Metadata {
data: Metadata {
accessed: metadata
.accessed()
.ok()
.and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|d| d.as_millis()),
created: metadata
.created()
.ok()
.and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|d| d.as_millis()),
modified: metadata
.modified()
.ok()
.and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|d| d.as_millis()),
len: metadata.len(),
readonly: metadata.permissions().readonly(),
file_type: if metadata.is_dir() {
FileType::Dir
} else if metadata.is_file() {
FileType::File
} else {
FileType::SymLink
},
canonicalized_path,
accessed: metadata
.accessed()
.ok()
.and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|d| d.as_millis()),
created: metadata
.created()
.ok()
.and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|d| d.as_millis()),
modified: metadata
.modified()
.ok()
.and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|d| d.as_millis()),
len: metadata.len(),
readonly: metadata.permissions().readonly(),
file_type: if metadata.is_dir() {
FileType::Dir
} else if metadata.is_file() {
FileType::File
} else {
FileType::SymLink
},
})
}

@ -170,6 +170,12 @@ pub enum RequestPayload {
Metadata {
/// The path to the file, directory, or symlink on the remote machine
path: PathBuf,
/// Whether or not to include a canonicalized version of the path, meaning
/// returning the canonical, absolute form of a path with all
/// intermediate components normalized and symbolic links resolved
#[structopt(short, long)]
canonicalize: bool,
},
/// Runs a process on the remote machine
@ -280,10 +286,32 @@ pub enum ResponsePayload {
errors: Vec<Error>,
},
/// Response to reading metadata
/// Represents metadata about some filesystem object (file, directory, symlink) on remote machine
Metadata {
/// Metadata associated with queried path
data: Metadata,
/// Canonicalized path to the file or directory, resolving symlinks, only included
/// if flagged during the request
canonicalized_path: Option<PathBuf>,
/// Represents the type of the entry as a file/dir/symlink
file_type: FileType,
/// Size of the file/directory/symlink in bytes
len: u64,
/// Whether or not the file/directory/symlink is marked as unwriteable
readonly: bool,
/// Represents the last time (in milliseconds) when the file/directory/symlink was accessed;
/// can be optional as certain systems don't support this
accessed: Option<u128>,
/// Represents when (in milliseconds) the file/directory/symlink was created;
/// can be optional as certain systems don't support this
created: Option<u128>,
/// Represents the last time (in milliseconds) when the file/directory/symlink was modified;
/// can be optional as certain systems don't support this
modified: Option<u128>,
},
/// Response to starting a new process
@ -366,32 +394,6 @@ pub struct DirEntry {
pub depth: usize,
}
/// Represents metadata about some filesystem object (file, directory, symlink) on remote machine
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]
pub struct Metadata {
/// Represents the type of the entry as a file/dir/symlink
pub file_type: FileType,
/// Size of the file/directory/symlink in bytes
pub len: u64,
/// Whether or not the file/directory/symlink is marked as unwriteable
pub readonly: bool,
/// Represents the last time (in milliseconds) when the file/directory/symlink was accessed;
/// can be optional as certain systems don't support this
pub accessed: Option<u128>,
/// Represents when (in milliseconds) the file/directory/symlink was created;
/// can be optional as certain systems don't support this
pub created: Option<u128>,
/// Represents the last time (in milliseconds) when the file/directory/symlink was modified;
/// can be optional as certain systems don't support this
pub modified: Option<u128>,
}
/// Represents the type associated with a dir entry
#[derive(Copy, Clone, Debug, PartialEq, Eq, AsRefStr, IsVariant, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", deny_unknown_fields)]

Loading…
Cancel
Save