smarter config loading giving more diagnostics to the user about whats going wrong (#589)

This commit is contained in:
Stephan Dilly 2021-03-14 00:25:30 +01:00 committed by GitHub
parent 52bf018515
commit 7d4b79606c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 46 deletions

View file

@ -23,7 +23,7 @@ use crossbeam_channel::Sender;
use crossterm::event::{Event, KeyEvent};
use std::{
cell::{Cell, RefCell},
path::{Path, PathBuf},
path::Path,
rc::Rc,
};
use tui::{
@ -74,11 +74,12 @@ impl App {
pub fn new(
sender: &Sender<AsyncNotification>,
input: Input,
theme_path: PathBuf,
theme: Theme,
key_config: KeyConfig,
) -> Self {
let queue = Queue::default();
let theme = Rc::new(Theme::init(theme_path));
let key_config = Rc::new(KeyConfig::init());
let theme = Rc::new(theme);
let key_config = Rc::new(key_config);
Self {
input,

View file

@ -5,12 +5,12 @@ use crate::get_app_config_path;
use anyhow::Result;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ron::{
de::from_bytes,
self,
ser::{to_string_pretty, PrettyConfig},
};
use serde::{Deserialize, Serialize};
use std::{
fs::File,
fs::{self, File},
io::{Read, Write},
path::PathBuf,
rc::Rc,
@ -127,15 +127,14 @@ impl Default for KeyConfig {
}
impl KeyConfig {
fn save(&self) -> Result<()> {
let config_file = Self::get_config_file()?;
let mut file = File::create(config_file)?;
fn save(&self, file: PathBuf) -> Result<()> {
let mut file = File::create(file)?;
let data = to_string_pretty(self, PrettyConfig::default())?;
file.write_all(data.as_bytes())?;
Ok(())
}
fn get_config_file() -> Result<PathBuf> {
pub fn get_config_file() -> Result<PathBuf> {
let app_home = get_app_config_path()?;
Ok(app_home.join("key_config.ron"))
}
@ -144,31 +143,31 @@ impl KeyConfig {
let mut f = File::open(config_file)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
Ok(from_bytes(&buffer)?)
Ok(ron::de::from_bytes(&buffer)?)
}
fn init_internal() -> Result<Self> {
let file = Self::get_config_file()?;
pub fn init(file: PathBuf) -> Result<Self> {
if file.exists() {
Ok(Self::read_file(file)?)
} else {
let def = Self::default();
if def.save().is_err() {
log::warn!(
"failed to store default key config to disk."
)
}
Ok(def)
}
}
match Self::read_file(file.clone()) {
Err(e) => {
let config_path = file.clone();
let config_path_old =
format!("{}.old", file.to_string_lossy());
fs::rename(
config_path.clone(),
config_path_old.clone(),
)?;
pub fn init() -> Self {
match Self::init_internal() {
Ok(v) => v,
Err(e) => {
log::error!("failed loading key binding: {}", e);
Self::default()
Self::default().save(file)?;
Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
e,config_path_old,config_path.to_string_lossy()))
}
Ok(res) => Ok(res),
}
} else {
Self::default().save(file)?;
Ok(Self::default())
}
}

View file

@ -43,6 +43,7 @@ use crossterm::{
ExecutableCommand,
};
use input::{Input, InputEvent, InputState};
use keys::KeyConfig;
use profiler::Profiler;
use scopeguard::defer;
use scopetime::scope_time;
@ -61,6 +62,7 @@ use tui::{
backend::{Backend, CrosstermBackend},
Terminal,
};
use ui::style::Theme;
static TICK_INTERVAL: Duration = Duration::from_secs(5);
static SPINNER_INTERVAL: Duration = Duration::from_millis(80);
@ -88,6 +90,13 @@ fn main() -> Result<()> {
return Ok(());
}
let key_config = KeyConfig::init(KeyConfig::get_config_file()?)
.map_err(|e| eprintln!("KeyConfig loading error: {}", e))
.unwrap_or_default();
let theme = Theme::init(cliargs.theme)
.map_err(|e| eprintln!("Theme loading error: {}", e))
.unwrap_or_default();
setup_terminal()?;
defer! {
shutdown_terminal().expect("shutdown failed");
@ -105,7 +114,7 @@ fn main() -> Result<()> {
let ticker = tick(TICK_INTERVAL);
let spinner_ticker = tick(SPINNER_INTERVAL);
let mut app = App::new(&tx_git, input, cliargs.theme);
let mut app = App::new(&tx_git, input, theme, key_config);
let mut spinner = Spinner::default();
let mut first_update = true;

View file

@ -9,7 +9,7 @@ use ron::{
};
use serde::{Deserialize, Serialize};
use std::{
fs::File,
fs::{self, File},
io::{Read, Write},
path::PathBuf,
rc::Rc,
@ -250,21 +250,29 @@ impl Theme {
Ok(from_bytes(&buffer)?)
}
fn init_internal(theme: PathBuf) -> Result<Self> {
if theme.exists() {
Ok(Self::read_file(theme)?)
} else {
// This will only be called when theme.ron doesn't already exists
let def = Self::default();
if def.save(theme).is_err() {
log::warn!("failed to store default theme to disk.")
}
Ok(def)
}
}
pub fn init(file: PathBuf) -> Result<Self> {
if file.exists() {
match Self::read_file(file.clone()) {
Err(e) => {
let config_path = file.clone();
let config_path_old =
format!("{}.old", file.to_string_lossy());
fs::rename(
config_path.clone(),
config_path_old.clone(),
)?;
pub fn init(theme_path: PathBuf) -> Self {
Self::init_internal(theme_path).unwrap_or_default()
Self::default().save(file)?;
Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
e,config_path_old,config_path.to_string_lossy()))
}
Ok(res) => Ok(res),
}
} else {
Self::default().save(file)?;
Ok(Self::default())
}
}
}