refactor: remove sync_usage option, enhance SSH connection error messages
This commit is contained in:
+2
-9
@@ -13,7 +13,6 @@ pub enum SettingsField {
|
||||
S3Bucket,
|
||||
S3AccessKey,
|
||||
S3SecretKey,
|
||||
SyncUsage,
|
||||
}
|
||||
|
||||
impl SettingsField {
|
||||
@@ -37,7 +36,6 @@ impl SettingsField {
|
||||
]);
|
||||
}
|
||||
}
|
||||
fields.push(SettingsField::SyncUsage);
|
||||
fields
|
||||
}
|
||||
|
||||
@@ -53,12 +51,11 @@ impl SettingsField {
|
||||
Self::S3Bucket => "Bucket",
|
||||
Self::S3AccessKey => "Access Key",
|
||||
Self::S3SecretKey => "Secret Key",
|
||||
Self::SyncUsage => "Sync Usage",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_toggle(self) -> bool {
|
||||
matches!(self, Self::Backend | Self::SyncUsage)
|
||||
matches!(self, Self::Backend)
|
||||
}
|
||||
|
||||
pub fn is_text(self) -> bool {
|
||||
@@ -78,7 +75,6 @@ pub struct SettingsState {
|
||||
pub s3_bucket: String,
|
||||
pub s3_access_key: String,
|
||||
pub s3_secret_key: String,
|
||||
pub sync_usage: bool,
|
||||
pub active: SettingsField,
|
||||
pub cursor: usize,
|
||||
}
|
||||
@@ -148,7 +144,6 @@ impl Default for SettingsState {
|
||||
s3_bucket: String::new(),
|
||||
s3_access_key: String::new(),
|
||||
s3_secret_key: String::new(),
|
||||
sync_usage: false,
|
||||
active: SettingsField::SyncPassword,
|
||||
cursor: 0,
|
||||
}
|
||||
@@ -225,7 +220,6 @@ impl App {
|
||||
self.config.settings.s3_access_key.clone().unwrap_or_default();
|
||||
self.session.settings.s3_secret_key =
|
||||
self.config.settings.s3_secret_key.clone().unwrap_or_default();
|
||||
self.session.settings.sync_usage = self.config.settings.sync_usage_count;
|
||||
self.session.settings.active = SettingsField::SyncPassword;
|
||||
self.session.settings.cursor = char_len(self.session.settings.active_text());
|
||||
self.session.mode = Mode::Settings;
|
||||
@@ -259,7 +253,6 @@ impl App {
|
||||
} else {
|
||||
Some(s3_sk)
|
||||
};
|
||||
self.config.settings.sync_usage_count = self.session.settings.sync_usage;
|
||||
self.config.save()?;
|
||||
self.session.mode = Mode::Home;
|
||||
Ok(())
|
||||
|
||||
@@ -64,8 +64,6 @@ pub struct Settings {
|
||||
pub s3_bucket: Option<String>,
|
||||
pub s3_access_key: Option<String>,
|
||||
pub s3_secret_key: Option<String>,
|
||||
#[serde(default)]
|
||||
pub sync_usage_count: bool,
|
||||
pub sync_password: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
+33
-2
@@ -1,9 +1,38 @@
|
||||
use crate::config::{ConnectionType, CredentialEntry, SshellConfig};
|
||||
use crate::config::{ConnectionType, CredentialEntry, SshellConfig, find_binary};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
fn require_binary(name: &str) -> Result<()> {
|
||||
if find_binary(name).is_some() {
|
||||
return Ok(());
|
||||
}
|
||||
let hint = match name {
|
||||
"ssh" => "\n\
|
||||
sshell requires `ssh` to connect via SSH.\n\
|
||||
\n\
|
||||
Install it with:\n\
|
||||
macOS: pre-installed (or: xcode-select --install)\n\
|
||||
Debian: sudo apt install openssh-client\n\
|
||||
Arch: sudo pacman -S openssh\n\
|
||||
Fedora: sudo dnf install openssh-clients\n\
|
||||
Windows: Settings → Apps → Optional Features → OpenSSH Client"
|
||||
,
|
||||
"sshpass" => "\n\
|
||||
Password-based SSH login requires `sshpass`.\n\
|
||||
Consider switching to private-key auth instead, or install it:\n\
|
||||
macOS: brew install hudochenkov/sshpass/sshpass\n\
|
||||
Debian: sudo apt install sshpass\n\
|
||||
Arch: sudo pacman -S sshpass\n\
|
||||
Fedora: sudo dnf install sshpass\n\
|
||||
Windows: not available — use private-key auth"
|
||||
,
|
||||
_ => "",
|
||||
};
|
||||
bail!("command not found: `{name}`{hint}");
|
||||
}
|
||||
|
||||
pub fn connect(name: &str, cfg: &SshellConfig) -> Result<()> {
|
||||
let profile = cfg
|
||||
.connections
|
||||
@@ -41,8 +70,10 @@ fn connect_ssh(
|
||||
if auth_ref.is_empty() {
|
||||
bail!("this connection has no credential; edit it and set password or private key");
|
||||
}
|
||||
require_binary("ssh")?;
|
||||
match cfg.credential(auth_ref) {
|
||||
Some(CredentialEntry::Password { value, .. }) => {
|
||||
require_binary("sshpass")?;
|
||||
let args = vec![
|
||||
"ssh".to_string(),
|
||||
"-o".to_string(),
|
||||
@@ -87,7 +118,7 @@ fn run_sshpass(args: &[String], password: &str) -> Result<()> {
|
||||
.args(args)
|
||||
.env("SSHPASS", password)
|
||||
.status()
|
||||
.context("failed to run sshpass — is it installed?")?;
|
||||
.context("failed to run sshpass")?;
|
||||
std::process::exit(status.code().unwrap_or(1));
|
||||
}
|
||||
|
||||
|
||||
+1
-8
@@ -60,9 +60,6 @@ pub(crate) fn build_sync_payload(
|
||||
sync_password: Option<&str>,
|
||||
) -> Result<toml::Value> {
|
||||
let mut payload = cfg.clone();
|
||||
payload.settings.sync_password = None;
|
||||
payload.settings.webdav_password = None;
|
||||
payload.settings.s3_secret_key = None;
|
||||
|
||||
let synced_refs: Vec<String> = payload
|
||||
.connections
|
||||
@@ -90,14 +87,10 @@ pub(crate) fn build_sync_payload(
|
||||
"version".to_string(),
|
||||
toml::Value::Integer(payload.version as i64),
|
||||
);
|
||||
table.insert("settings".to_string(), to_toml_value(&payload.settings)?);
|
||||
|
||||
let mut conns = toml::map::Map::new();
|
||||
for (name, profile) in &mut payload.connections {
|
||||
profile.local_tags.clear();
|
||||
if !payload.settings.sync_usage_count {
|
||||
profile.usage_count = 0;
|
||||
}
|
||||
profile.usage_count = 0;
|
||||
match &mut profile.kind {
|
||||
ConnectionType::Shell {
|
||||
auth_ref,
|
||||
|
||||
+2
-12
@@ -1,7 +1,7 @@
|
||||
use crate::app::{App, FormAction, Mode, SettingsField, SettingsState, char_len};
|
||||
use crate::config::SyncBackend;
|
||||
use crate::ui::component::{FormRow, badge_span};
|
||||
use crate::ui::{ACCENT, GREEN, ORANGE, PURPLE, RED};
|
||||
use crate::ui::{ACCENT, ORANGE, PURPLE};
|
||||
|
||||
use super::{View, handle_form_nav};
|
||||
|
||||
@@ -31,7 +31,7 @@ impl View for SettingsView {
|
||||
let active = settings.active == field;
|
||||
let label = field.label().to_string();
|
||||
|
||||
if i == 2 || matches!(field, SettingsField::SyncUsage) {
|
||||
if i == 2 {
|
||||
rows.push(FormRow::Separator);
|
||||
}
|
||||
|
||||
@@ -42,13 +42,6 @@ impl View for SettingsView {
|
||||
SyncBackend::Webdav => badge_span("WebDAV", ORANGE),
|
||||
SyncBackend::S3 => badge_span("S3", PURPLE),
|
||||
},
|
||||
SettingsField::SyncUsage => {
|
||||
if settings.sync_usage {
|
||||
badge_span("Yes", GREEN)
|
||||
} else {
|
||||
badge_span("No", RED)
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
rows.push(FormRow::Toggle {
|
||||
@@ -131,9 +124,6 @@ fn settings_toggle(settings: &mut SettingsState) {
|
||||
};
|
||||
settings.ensure_active_visible();
|
||||
}
|
||||
SettingsField::SyncUsage => {
|
||||
settings.sync_usage = !settings.sync_usage;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user