mirror of
https://github.com/veeso/termscp.git
synced 2025-12-06 17:15:35 -08:00
debug log belongs in cache directory not config directory (#179)
* log files are now written to cache dir instead of config dir * lint * fmt
This commit is contained in:
committed by
GitHub
parent
9bf23b3f6b
commit
9009002b6e
@@ -482,9 +482,9 @@ Just a reminder: **you can edit only textual file**; binary files are not suppor
|
||||
|
||||
termscp writes a log file for each session, which is written at
|
||||
|
||||
- `$HOME/.config/termscp/termscp.log` on Linux/BSD
|
||||
- `$HOME/Library/Application Support/termscp/termscp.log` on MacOs
|
||||
- `FOLDERID_RoamingAppData\termscp\termscp.log` on Windows
|
||||
- `$HOME/.cache/termscp/termscp.log` on Linux/BSD
|
||||
- `$HOME/Library/Caches/termscp/termscp.log` on MacOs
|
||||
- `FOLDERID_LocalAppData\termscp\termscp.log` on Windows
|
||||
|
||||
the log won't be rotated, but will just be truncated after each launch of termscp, so if you want to report an issue and you want to attach your log file, keep in mind to save the log file in a safe place before using termscp again.
|
||||
The logging by default reports in *INFO* level, so it is not very verbose.
|
||||
|
||||
@@ -481,9 +481,9 @@ En caso de que el archivo esté ubicado en un host remoto, el archivo se descarg
|
||||
|
||||
termscp escribe un archivo de registro para cada sesión, que se escribe en
|
||||
|
||||
- `$HOME/.config/termscp/termscp.log` en Linux/BSD
|
||||
- `$HOME/Library/Application Support/termscp/termscp.log` en MacOs
|
||||
- `FOLDERID_RoamingAppData\termscp\termscp.log` en Windows
|
||||
- `$HOME/.cache/termscp/termscp.log` en Linux/BSD
|
||||
- `$HOME/Library/Caches/termscp/termscp.log` en MacOs
|
||||
- `FOLDERID_LocalAppData\termscp\termscp.log` en Windows
|
||||
|
||||
el registro no se rotará, sino que se truncará después de cada lanzamiento de termscp, por lo que si desea informar un problema y desea adjuntar su archivo de registro, recuerde guardar el archivo de registro en un lugar seguro antes de usar termscp de nuevo.
|
||||
El registro por defecto informa en el nivel *INFO*, por lo que no es muy detallado.
|
||||
|
||||
@@ -479,9 +479,9 @@ Si le fichier se trouve sur l'hôte distant, le fichier sera d'abord télécharg
|
||||
|
||||
termscp écrit un fichier journal pour chaque session, qui est écrit à
|
||||
|
||||
- `$HOME/.config/termscp/termscp.log` sous Linux/BSD
|
||||
- `$HOME/Library/Application Support/termscp/termscp.log` sous MacOs
|
||||
- `FOLDERID_RoamingAppData\termscp\termscp.log` sous Windows
|
||||
- `$HOME/.cache/termscp/termscp.log` sous Linux/BSD
|
||||
- `$HOME/Library/Caches/termscp/termscp.log` sous MacOs
|
||||
- `FOLDERID_LocalAppData\termscp\termscp.log` sous Windows
|
||||
|
||||
le journal ne sera pas tourné, mais sera simplement tronqué après chaque lancement de termscp, donc si vous souhaitez signaler un problème et que vous souhaitez joindre votre fichier journal, n'oubliez pas de sauvegarder le fichier journal dans un endroit sûr avant de l'utiliser termescp à nouveau.
|
||||
|
||||
|
||||
@@ -478,9 +478,9 @@ Nel caso il file si trovi su host remoto, il file verrà prima scaricato tempora
|
||||
|
||||
termscp scrive un file di log per ogni sessione, nel percorso seguente:
|
||||
|
||||
- `$HOME/.config/termscp/termscp.log` su Linux/BSD
|
||||
- `$HOME/Library/Application Support/termscp/termscp.log` su MacOs
|
||||
- `FOLDERID_RoamingAppData\termscp\termscp.log` su Windows
|
||||
- `$HOME/.cache/termscp/termscp.log` su Linux/BSD
|
||||
- `$HOME/Library/Caches/termscp/termscp.log` su MacOs
|
||||
- `FOLDERID_LocalAppData\termscp\termscp.log` su Windows
|
||||
|
||||
Il log non viene ruotato, ma viene troncato ad ogni lancio di termscp, quindi se devi riportare un issue, non avviare termscp fino a che non avrai salvato il file di log.
|
||||
I log sono di default riportati a livello *INFO*, quindi non sono particolarmente parlanti.
|
||||
|
||||
@@ -480,9 +480,9 @@ In case the file is located on remote host, the file will be first downloaded in
|
||||
|
||||
termscp writes a log file for each session, which is written at
|
||||
|
||||
- `$HOME/.config/termscp/termscp.log` on Linux/BSD
|
||||
- `$HOME/Library/Application Support/termscp/termscp.log` on MacOs
|
||||
- `FOLDERID_RoamingAppData\termscp\termscp.log` on Windows
|
||||
- `$HOME/.cache/termscp/termscp.log` on Linux/BSD
|
||||
- `$HOME/Library/Caches/termscp/termscp.log` on MacOs
|
||||
- `FOLDERID_LocalAppData\termscp\termscp.log` on Windows
|
||||
|
||||
the log won't be rotated, but will just be truncated after each launch of termscp, so if you want to report an issue and you want to attach your log file, keep in mind to save the log file in a safe place before using termscp again.
|
||||
The logging by default reports in *INFO* level, so it is not very verbose.
|
||||
|
||||
@@ -472,9 +472,9 @@ Termscp有很多功能,你可能已经注意到了,其中之一就是可以
|
||||
|
||||
termscp会为每个会话创建一个日志文件,该文件在
|
||||
|
||||
- `$HOME/.config/termscp/termscp.log` -- Linux/BSD
|
||||
- `$HOME/Library/Application Support/termscp/termscp.log` -- MacOs
|
||||
- `FOLDERID_RoamingAppData\termscp\termscp.log` -- Windows
|
||||
- `$HOME/.cache/termscp/termscp.log` -- Linux/BSD
|
||||
- `$HOME/Library/Caches/termscp/termscp.log` -- MacOs
|
||||
- `FOLDERID_LocalAppData\termscp\termscp.log` -- Windows
|
||||
|
||||
日志不会被轮换,但只会在每次启动 termcp 后被截断,因此如果您想报告问题并希望附加您的日志文件,请记住在使用前将日志文件保存在安全的地方 再次termscp。
|
||||
默认情况下,日志记录在 *INFO* 级别报告,因此它不是很详细。
|
||||
|
||||
@@ -21,8 +21,6 @@ use crate::utils::tty;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
|
||||
/// ### NextActivity
|
||||
///
|
||||
/// NextActivity identifies the next identity to run once the current has ended
|
||||
pub enum NextActivity {
|
||||
Authentication,
|
||||
@@ -30,8 +28,6 @@ pub enum NextActivity {
|
||||
SetupActivity,
|
||||
}
|
||||
|
||||
/// ### ActivityManager
|
||||
///
|
||||
/// The activity manager takes care of running activities and handling them until the application has ended
|
||||
pub struct ActivityManager {
|
||||
context: Option<Context>,
|
||||
|
||||
@@ -49,8 +49,6 @@ impl std::fmt::Display for SerializerError {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### serialize
|
||||
///
|
||||
/// Serialize `UserHosts` into TOML and write content to writable
|
||||
pub fn serialize<S>(serializable: &S, mut writable: Box<dyn Write>) -> Result<(), SerializerError>
|
||||
where
|
||||
@@ -77,8 +75,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// ### deserialize
|
||||
///
|
||||
/// Read data from readable and deserialize its content as TOML
|
||||
pub fn deserialize<S>(mut readable: Box<dyn Read>) -> Result<S, SerializerError>
|
||||
where
|
||||
|
||||
@@ -9,8 +9,6 @@ use crate::utils::parser::parse_color;
|
||||
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use tuirealm::tui::style::Color;
|
||||
|
||||
/// ### Theme
|
||||
///
|
||||
/// Theme contains all the colors lookup table for termscp
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||
pub struct Theme {
|
||||
|
||||
@@ -6,8 +6,6 @@ use super::FileTransferProtocol;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// ### FileTransferParams
|
||||
///
|
||||
/// Holds connection parameters for file transfers
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileTransferParams {
|
||||
|
||||
@@ -41,8 +41,6 @@ pub enum HostErrorType {
|
||||
DeleteFailed,
|
||||
}
|
||||
|
||||
/// ### HostError
|
||||
///
|
||||
/// HostError is a wrapper for the error type and the exact io error
|
||||
#[derive(Debug)]
|
||||
pub struct HostError {
|
||||
|
||||
@@ -136,8 +136,6 @@ fn parse_remote_address(remote: &str) -> Result<FileTransferParams, String> {
|
||||
utils::parser::parse_remote_opt(remote).map_err(|e| format!("Bad address option: {e}"))
|
||||
}
|
||||
|
||||
/// ### run
|
||||
///
|
||||
/// Run task and return rc
|
||||
fn run(run_opts: RunOpts) -> i32 {
|
||||
match run_opts.task {
|
||||
|
||||
@@ -13,8 +13,6 @@ use crate::system::{
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// ### import_theme
|
||||
///
|
||||
/// Import theme at provided path into termscp
|
||||
pub fn import_theme(p: &Path) -> Result<(), String> {
|
||||
if !p.exists() {
|
||||
@@ -34,8 +32,6 @@ pub fn import_theme(p: &Path) -> Result<(), String> {
|
||||
.map_err(|e| format!("Could not import theme: {e}"))
|
||||
}
|
||||
|
||||
/// ### install_update
|
||||
///
|
||||
/// Install latest version of termscp if an update is available
|
||||
pub fn install_update() -> Result<String, String> {
|
||||
match Update::default()
|
||||
@@ -65,8 +61,6 @@ pub fn install_update() -> Result<String, String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### get_config_dir
|
||||
///
|
||||
/// Get configuration directory
|
||||
fn get_config_dir() -> Result<PathBuf, String> {
|
||||
match environment::init_config_dir() {
|
||||
@@ -80,8 +74,6 @@ fn get_config_dir() -> Result<PathBuf, String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### get_config_client
|
||||
///
|
||||
/// Get configuration client
|
||||
fn get_config_client() -> Option<ConfigClient> {
|
||||
match get_config_dir() {
|
||||
|
||||
@@ -10,8 +10,6 @@ use self_update::{
|
||||
Status,
|
||||
};
|
||||
|
||||
/// ### UpdateStatus
|
||||
///
|
||||
/// The status of the update in case of success
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum UpdateStatus {
|
||||
|
||||
@@ -730,7 +730,7 @@ mod tests {
|
||||
// Limit is 2
|
||||
assert_eq!(client.iter_recents().count(), 2);
|
||||
// Check that 192.168.1.1 has been removed
|
||||
let key: String = client.iter_recents().nth(0).unwrap().to_string();
|
||||
let key: String = client.iter_recents().next().unwrap().to_string();
|
||||
assert!(matches!(
|
||||
client
|
||||
.hosts
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
// Ext
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// ### get_config_dir
|
||||
///
|
||||
/// Get termscp configuration directory path.
|
||||
/// Returns None, if it's not possible to get it
|
||||
/// Get termscp config directory path and initialize it.
|
||||
/// Returns None if it's not possible to initialize it
|
||||
pub fn init_config_dir() -> Result<Option<PathBuf>, String> {
|
||||
// Get file
|
||||
#[cfg(not(test))]
|
||||
@@ -19,27 +17,51 @@ pub fn init_config_dir() -> Result<Option<PathBuf>, String> {
|
||||
lazy_static! {
|
||||
static ref CONF_DIR: Option<PathBuf> = Some(std::env::temp_dir());
|
||||
}
|
||||
if CONF_DIR.is_some() {
|
||||
// Get path of bookmarks
|
||||
let mut p: PathBuf = CONF_DIR.as_ref().unwrap().clone();
|
||||
// Append termscp dir
|
||||
p.push("termscp/");
|
||||
// If directory doesn't exist, create it
|
||||
if p.exists() {
|
||||
return Ok(Some(p));
|
||||
}
|
||||
// directory doesn't exist; create dir recursively
|
||||
match std::fs::create_dir_all(p.as_path()) {
|
||||
Ok(_) => Ok(Some(p)),
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
|
||||
if let Some(dir) = CONF_DIR.as_deref() {
|
||||
init_dir(dir).map(Option::Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// ### get_bookmarks_paths
|
||||
///
|
||||
/// Get termscp cache directory path and initialize it.
|
||||
/// Returns None if it's not possible to initialize it
|
||||
pub fn init_cache_dir() -> Result<Option<PathBuf>, String> {
|
||||
// Get file
|
||||
#[cfg(not(test))]
|
||||
lazy_static! {
|
||||
static ref CACHE_DIR: Option<PathBuf> = dirs::cache_dir();
|
||||
}
|
||||
#[cfg(test)]
|
||||
lazy_static! {
|
||||
static ref CACHE_DIR: Option<PathBuf> = Some(std::env::temp_dir());
|
||||
}
|
||||
|
||||
if let Some(dir) = CACHE_DIR.as_deref() {
|
||||
init_dir(dir).map(Option::Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Init a termscp env dir
|
||||
fn init_dir(p: &Path) -> Result<PathBuf, String> {
|
||||
// Get path of bookmarks
|
||||
let mut p: PathBuf = p.to_path_buf();
|
||||
// Append termscp dir
|
||||
p.push("termscp/");
|
||||
// If directory doesn't exist, create it
|
||||
if p.exists() {
|
||||
return Ok(p);
|
||||
}
|
||||
// directory doesn't exist; create dir recursively
|
||||
match std::fs::create_dir_all(p.as_path()) {
|
||||
Ok(_) => Ok(p),
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get paths for bookmarks client
|
||||
/// Returns: path of bookmarks.toml
|
||||
pub fn get_bookmarks_paths(config_dir: &Path) -> PathBuf {
|
||||
@@ -49,8 +71,6 @@ pub fn get_bookmarks_paths(config_dir: &Path) -> PathBuf {
|
||||
bookmarks_file
|
||||
}
|
||||
|
||||
/// ### get_config_paths
|
||||
///
|
||||
/// Returns paths for config client
|
||||
/// Returns: path of config.toml and path for ssh keys
|
||||
pub fn get_config_paths(config_dir: &Path) -> (PathBuf, PathBuf) {
|
||||
@@ -62,17 +82,13 @@ pub fn get_config_paths(config_dir: &Path) -> (PathBuf, PathBuf) {
|
||||
(bookmarks_file, keys_dir)
|
||||
}
|
||||
|
||||
/// ### get_log_paths
|
||||
///
|
||||
/// Returns the path for the supposed log file
|
||||
pub fn get_log_paths(config_dir: &Path) -> PathBuf {
|
||||
let mut log_file: PathBuf = PathBuf::from(config_dir);
|
||||
pub fn get_log_paths(cache_dir: &Path) -> PathBuf {
|
||||
let mut log_file: PathBuf = PathBuf::from(cache_dir);
|
||||
log_file.push("termscp.log");
|
||||
log_file
|
||||
}
|
||||
|
||||
/// ### get_theme_path
|
||||
///
|
||||
/// Get paths for theme provider
|
||||
/// Returns: path of theme.toml
|
||||
pub fn get_theme_path(config_dir: &Path) -> PathBuf {
|
||||
@@ -101,6 +117,15 @@ mod tests {
|
||||
assert!(std::fs::remove_dir_all(conf_dir.as_path()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn should_get_cache_dir() {
|
||||
// Create and get cache_dir
|
||||
let cache_dir: PathBuf = init_cache_dir().ok().unwrap().unwrap();
|
||||
// Remove dir
|
||||
assert!(std::fs::remove_dir_all(cache_dir.as_path()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_system_environment_get_config_dir_err() {
|
||||
@@ -148,8 +173,8 @@ mod tests {
|
||||
#[serial]
|
||||
fn test_system_environment_get_log_paths() {
|
||||
assert_eq!(
|
||||
get_log_paths(Path::new("/home/omar/.config/termscp/")),
|
||||
PathBuf::from("/home/omar/.config/termscp/termscp.log"),
|
||||
get_log_paths(Path::new("/home/omar/.cache/termscp/")),
|
||||
PathBuf::from("/home/omar/.cache/termscp/termscp.log"),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,32 +2,26 @@
|
||||
//!
|
||||
//! `logging` is the module which initializes the logging system for termscp
|
||||
|
||||
// locals
|
||||
use crate::system::environment::{get_log_paths, init_config_dir};
|
||||
use super::environment::{get_log_paths, init_cache_dir};
|
||||
use crate::utils::file::open_file;
|
||||
// ext
|
||||
pub use simplelog::LevelFilter as LogLevel;
|
||||
use simplelog::{ConfigBuilder, WriteLogger};
|
||||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// ### init
|
||||
///
|
||||
/// Initialize logger
|
||||
pub fn init(level: LogLevel) -> Result<(), String> {
|
||||
// Init config dir
|
||||
let config_dir: PathBuf = match init_config_dir() {
|
||||
// Init cache dir
|
||||
let cache_dir = match init_cache_dir() {
|
||||
Ok(Some(p)) => p,
|
||||
Ok(None) => {
|
||||
return Err(String::from(
|
||||
"This system doesn't seem to support CONFIG_DIR",
|
||||
"This system doesn't seem to support CACHE_DIR",
|
||||
))
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
let log_file_path: PathBuf = get_log_paths(config_dir.as_path());
|
||||
let log_file_path = get_log_paths(cache_dir.as_path());
|
||||
// Open log file
|
||||
let file: File = open_file(log_file_path.as_path(), true, true, false)
|
||||
let file = open_file(log_file_path.as_path(), true, true, false)
|
||||
.map_err(|e| format!("Failed to open file {}: {}", log_file_path.display(), e))?;
|
||||
// Prepare log config
|
||||
let config = ConfigBuilder::new().set_time_format_rfc3339().build();
|
||||
|
||||
@@ -147,8 +147,6 @@ enum InputMask {
|
||||
const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION";
|
||||
const STORE_KEY_RELEASE_NOTES: &str = "AUTH_RELEASE_NOTES";
|
||||
|
||||
/// ### AuthActivity
|
||||
///
|
||||
/// AuthActivity is the data holder for the authentication activity
|
||||
pub struct AuthActivity {
|
||||
app: Application<Id, Msg, NoUserEvent>,
|
||||
|
||||
@@ -8,8 +8,6 @@ use std::time::Instant;
|
||||
|
||||
// -- States and progress
|
||||
|
||||
/// ### TransferStates
|
||||
///
|
||||
/// TransferStates contains the states related to the transfer process
|
||||
pub struct TransferStates {
|
||||
aborted: bool, // Describes whether the transfer process has been aborted
|
||||
@@ -17,8 +15,6 @@ pub struct TransferStates {
|
||||
pub partial: ProgressStates, // Partial transfer states
|
||||
}
|
||||
|
||||
/// ### ProgressStates
|
||||
///
|
||||
/// Progress states describes the states for the progress of a single transfer part
|
||||
pub struct ProgressStates {
|
||||
started: Instant,
|
||||
|
||||
@@ -227,8 +227,6 @@ pub enum ThemeMsg {
|
||||
// -- store
|
||||
const STORE_CONFIG_CHANGED: &str = "SETUP_CONFIG_CHANGED";
|
||||
|
||||
/// ### ViewLayout
|
||||
///
|
||||
/// Current view layout
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum ViewLayout {
|
||||
|
||||
@@ -5,16 +5,12 @@
|
||||
// Ext
|
||||
use magic_crypt::MagicCryptTrait;
|
||||
|
||||
/// ### aes128_b64_crypt
|
||||
///
|
||||
/// Crypt a string using AES128; output is returned as a BASE64 string
|
||||
pub fn aes128_b64_crypt(key: &str, input: &str) -> String {
|
||||
let crypter = new_magic_crypt!(key, 128);
|
||||
crypter.encrypt_str_to_base64(input)
|
||||
}
|
||||
|
||||
/// ### aes128_b64_decrypt
|
||||
///
|
||||
/// Decrypt a string using AES128
|
||||
pub fn aes128_b64_decrypt(key: &str, secret: &str) -> Result<String, magic_crypt::MagicCryptError> {
|
||||
let crypter = new_magic_crypt!(key, 128);
|
||||
|
||||
@@ -7,8 +7,6 @@ use std::fs::OpenOptions;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
/// ### open_file
|
||||
///
|
||||
/// Open file provided as parameter
|
||||
pub fn open_file<P>(filename: P, create: bool, write: bool, append: bool) -> io::Result<File>
|
||||
where
|
||||
|
||||
@@ -10,8 +10,6 @@ use std::time::{Duration, SystemTime};
|
||||
use tuirealm::tui::style::Color;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
/// ### fmt_pex
|
||||
///
|
||||
/// Convert permissions bytes of permissions value into ls notation (e.g. rwx,-wx,--x)
|
||||
pub fn fmt_pex(pex: UnixPexClass) -> String {
|
||||
format!(
|
||||
@@ -31,16 +29,12 @@ pub fn fmt_pex(pex: UnixPexClass) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
/// ### instant_to_str
|
||||
///
|
||||
/// Format a `Instant` into a time string
|
||||
pub fn fmt_time(time: SystemTime, fmt: &str) -> String {
|
||||
let datetime: DateTime<Local> = time.into();
|
||||
format!("{}", datetime.format(fmt))
|
||||
}
|
||||
|
||||
/// ### fmt_millis
|
||||
///
|
||||
/// Format duration as {secs}.{millis}
|
||||
pub fn fmt_millis(duration: Duration) -> String {
|
||||
let seconds: u128 = duration.as_millis() / 1000;
|
||||
@@ -48,16 +42,12 @@ pub fn fmt_millis(duration: Duration) -> String {
|
||||
format!("{}.{:0width$}", seconds, millis, width = 3)
|
||||
}
|
||||
|
||||
/// ### elide_path
|
||||
///
|
||||
/// Elide a path if longer than width
|
||||
/// In this case, the path is formatted to {ANCESTOR[0]}/…/{PARENT[0]}/{BASENAME}
|
||||
pub fn fmt_path_elide(p: &Path, width: usize) -> String {
|
||||
fmt_path_elide_ex(p, width, 0)
|
||||
}
|
||||
|
||||
/// ### fmt_path_elide_ex
|
||||
///
|
||||
/// Elide a path if longer than width
|
||||
/// In this case, the path is formatted to {ANCESTOR[0]}/…/{PARENT[0]}/{BASENAME}
|
||||
/// This function allows to specify an extra length to consider to elide path
|
||||
@@ -90,8 +80,6 @@ pub fn fmt_path_elide_ex(p: &Path, width: usize, extra_len: usize) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### fmt_color
|
||||
///
|
||||
/// Format color
|
||||
pub fn fmt_color(color: &Color) -> String {
|
||||
match color {
|
||||
@@ -258,15 +246,11 @@ pub fn fmt_color(color: &Color) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### shadow_password
|
||||
///
|
||||
/// Return a string with the same length of input string, but each character is replaced by '*'
|
||||
pub fn shadow_password(s: &str) -> String {
|
||||
(0..s.len()).map(|_| '*').collect()
|
||||
}
|
||||
|
||||
/// ### fmt_bytes
|
||||
///
|
||||
/// Format bytes
|
||||
pub fn fmt_bytes(v: u64) -> String {
|
||||
if v >= 1125899906842624 {
|
||||
|
||||
@@ -68,8 +68,6 @@ static BYTESIZE_REGEX: Lazy<Regex> = lazy_regex!(r"(:?([0-9])+)( )*(:?[KMGTP])?B
|
||||
|
||||
// -- remote opts
|
||||
|
||||
/// ### parse_remote_opt
|
||||
///
|
||||
/// Parse remote option string. Returns in case of success a RemoteOptions struct
|
||||
/// For ssh if username is not provided, current user will be used.
|
||||
/// In case of error, message is returned
|
||||
@@ -115,8 +113,6 @@ pub fn parse_remote_opt(s: &str) -> Result<FileTransferParams, String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### parse_remote_opt_protocol
|
||||
///
|
||||
/// Parse protocol from CLI option. In case of success, return the protocol to be used and the remaining arguments
|
||||
fn parse_remote_opt_protocol(
|
||||
s: &str,
|
||||
@@ -147,8 +143,6 @@ fn parse_remote_opt_protocol(
|
||||
}
|
||||
}
|
||||
|
||||
/// ### parse_generic_remote_opt
|
||||
///
|
||||
/// Parse generic remote options
|
||||
fn parse_generic_remote_opt(
|
||||
s: &str,
|
||||
@@ -202,8 +196,6 @@ fn parse_generic_remote_opt(
|
||||
}
|
||||
}
|
||||
|
||||
/// ### parse_s3_remote_opt
|
||||
///
|
||||
/// Parse remote options for s3 protocol
|
||||
fn parse_s3_remote_opt(s: &str) -> Result<FileTransferParams, String> {
|
||||
match REMOTE_S3_OPT_REGEX.captures(s) {
|
||||
@@ -229,8 +221,6 @@ fn parse_s3_remote_opt(s: &str) -> Result<FileTransferParams, String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### parse_semver
|
||||
///
|
||||
/// Parse semver string
|
||||
pub fn parse_semver(haystack: &str) -> Option<String> {
|
||||
match SEMVER_REGEX.captures(haystack) {
|
||||
@@ -239,8 +229,6 @@ pub fn parse_semver(haystack: &str) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### parse_color
|
||||
///
|
||||
/// Parse color from string into a `Color` enum.
|
||||
///
|
||||
/// Color may be in different format:
|
||||
@@ -300,8 +288,6 @@ impl FromStr for ByteUnit {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### parse_bytesize
|
||||
///
|
||||
/// Parse bytes repr (e.g. `24 MB`) into `ByteSize`
|
||||
pub fn parse_bytesize<S: AsRef<str>>(bytes: S) -> Option<ByteSize> {
|
||||
match BYTESIZE_REGEX.captures(bytes.as_ref()) {
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
/// ### absolutize
|
||||
///
|
||||
/// Absolutize target path if relative.
|
||||
/// For example:
|
||||
///
|
||||
@@ -24,8 +22,6 @@ pub fn absolutize(wrkdir: &Path, target: &Path) -> PathBuf {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### diff_paths
|
||||
///
|
||||
/// This function will get the difference from path `path` to `base`. Basically will remove `base` from `path`
|
||||
///
|
||||
/// For example:
|
||||
@@ -127,24 +123,21 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn should_tell_whether_path_is_child_of() {
|
||||
assert_eq!(
|
||||
is_child_of(Path::new("/home/foo/foo.txt"), Path::new("/home"),),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
is_child_of(Path::new("/home/foo/foo.txt"), Path::new("/home/foo/"),),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
is_child_of(
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
is_child_of(Path::new("/home/foo/foo.txt"), Path::new("/tmp"),),
|
||||
false
|
||||
);
|
||||
assert!(is_child_of(
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
Path::new("/home"),
|
||||
));
|
||||
assert!(is_child_of(
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
Path::new("/home/foo/"),
|
||||
));
|
||||
assert!(is_child_of(
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
));
|
||||
assert!(!is_child_of(
|
||||
Path::new("/home/foo/foo.txt"),
|
||||
Path::new("/tmp"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ pub fn create_sample_file_with_content(content: impl std::fmt::Display) -> Named
|
||||
tmpfile
|
||||
}
|
||||
|
||||
/// ### make_file_at
|
||||
///
|
||||
/// Make a file with `name` at specified path
|
||||
pub fn make_file_at(dir: &Path, filename: &str) -> std::io::Result<PathBuf> {
|
||||
let mut p: PathBuf = PathBuf::from(dir);
|
||||
@@ -47,8 +45,6 @@ pub fn make_file_at(dir: &Path, filename: &str) -> std::io::Result<PathBuf> {
|
||||
Ok(p)
|
||||
}
|
||||
|
||||
/// ### make_dir_at
|
||||
///
|
||||
/// Make a directory in `dir`
|
||||
pub fn make_dir_at(dir: &Path, dirname: &str) -> std::io::Result<()> {
|
||||
let mut p: PathBuf = PathBuf::from(dir);
|
||||
@@ -69,8 +65,6 @@ pub fn make_fsentry<P: AsRef<Path>>(path: P, is_dir: bool) -> File {
|
||||
}
|
||||
}
|
||||
|
||||
/// ### create_file_ioers
|
||||
///
|
||||
/// Open a file with two handlers, the first is to read, the second is to write
|
||||
pub fn create_file_ioers(p: &Path) -> (StdFile, StdFile) {
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user