Merge pull request #3038 from gitbutlerapp/try-from-part-1

move most `TryFrom`  initialization into main instead of initialization on demand
This commit is contained in:
Josh Junon 2024-03-05 18:08:10 +01:00 committed by GitHub
commit 82f102e106
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 148 additions and 242 deletions

View File

@ -37,24 +37,12 @@ impl TryFrom<&AppHandle> for App {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> std::result::Result<Self, Self::Error> {
if let Some(app) = value.try_state::<App>() {
Ok(app.inner().clone())
} else if let Some(app_data_dir) = value.path_resolver().app_data_dir() {
let projects = projects::Controller::try_from(value)?;
let users = users::Controller::try_from(value)?;
let watchers = watcher::Watchers::try_from(value)?;
let sessions_database = sessions::Database::try_from(value)?;
let app = App::new(app_data_dir, projects, users, watchers, sessions_database);
value.manage(app.clone());
Ok(app)
} else {
Err(anyhow::anyhow!("failed to get app data dir"))
}
Ok(value.state::<Self>().inner().clone())
}
}
impl App {
fn new(
pub fn new(
local_data_dir: path::PathBuf,
projects: projects::Controller,
users: users::Controller,

View File

@ -1,6 +1,6 @@
use std::{collections::HashMap, fs, path, sync};
use std::{collections::HashMap, path, sync};
use anyhow::{Context, Result};
use anyhow::Result;
use futures::future::join_all;
use tauri::{AppHandle, Manager};
use tokio::sync::Semaphore;
@ -24,24 +24,14 @@ impl TryFrom<&AppHandle> for Proxy {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(proxy) = value.try_state::<Proxy>() {
Ok(proxy.inner().clone())
} else if let Some(app_cache_dir) = value.path_resolver().app_cache_dir() {
fs::create_dir_all(&app_cache_dir).context("failed to create cache dir")?;
let cache_dir = app_cache_dir.join("images");
let proxy = Self::new(cache_dir);
value.manage(proxy.clone());
Ok(proxy)
} else {
Err(anyhow::anyhow!("failed to get app cache dir"))
}
Ok(value.state::<Self>().inner().clone())
}
}
const ASSET_SCHEME: &str = "asset";
impl Proxy {
fn new(cache_dir: path::PathBuf) -> Self {
pub fn new(cache_dir: path::PathBuf) -> Self {
Proxy {
cache_dir,
semaphores: sync::Arc::new(tokio::sync::Mutex::new(HashMap::new())),

View File

@ -1,4 +1,4 @@
use std::{fs, path, sync::Arc};
use std::{path, sync::Arc};
use anyhow::{Context, Result};
@ -22,14 +22,7 @@ impl TryFrom<&AppHandle> for Database {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(database) = value.try_state::<Database>() {
Ok(database.inner().clone())
} else if let Some(app_data_dir) = value.path_resolver().app_data_dir() {
fs::create_dir_all(&app_data_dir).context("failed to create local data dir")?;
Self::open(app_data_dir.join("database.sqlite3"))
} else {
Err(anyhow::anyhow!("failed to get app data dir"))
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -43,7 +36,7 @@ impl TryFrom<&path::PathBuf> for Database {
}
impl Database {
fn open<P: AsRef<path::Path>>(path: P) -> Result<Self> {
pub fn open<P: AsRef<path::Path>>(path: P) -> Result<Self> {
let path = path.as_ref();
let manager = SqliteConnectionManager::file(path);
let pool = r2d2::Pool::new(manager)?;

View File

@ -1,11 +1,11 @@
mod controller;
mod database;
mod delta;
mod document;
mod reader;
mod writer;
pub mod commands;
pub mod database;
pub mod operations;
pub use controller::Controller;

View File

@ -15,14 +15,7 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else {
let database = database::Database::try_from(value)?;
let controller = Controller::new(database);
value.manage(controller.clone());
Ok(controller)
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -33,7 +26,7 @@ pub enum ListError {
}
impl Controller {
fn new(database: database::Database) -> Controller {
pub fn new(database: database::Database) -> Controller {
Controller { database }
}

View File

@ -16,18 +16,12 @@ impl TryFrom<&AppHandle> for Database {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(database) = value.try_state::<Database>() {
Ok(database.inner().clone())
} else {
let database = Database::new(database::Database::try_from(value)?);
value.manage(database.clone());
Ok(database)
}
Ok(value.state::<Self>().inner().clone())
}
}
impl Database {
fn new(database: database::Database) -> Database {
pub fn new(database: database::Database) -> Database {
Database { database }
}

View File

@ -80,16 +80,7 @@ impl TryFrom<&AppHandle> for Helper {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(helper) = value.try_state::<Helper>() {
Ok(helper.inner().clone())
} else {
let keys = keys::Controller::try_from(value)?;
let users = users::Controller::try_from(value)?;
let home_dir = env::var_os("HOME").map(path::PathBuf::from);
let helper = Helper::new(keys, users, home_dir);
value.manage(helper.clone());
Ok(helper)
}
Ok(value.state::<Self>().inner().clone())
}
}

View File

@ -1,7 +1,7 @@
pub mod commands;
mod controller;
mod key;
mod storage;
pub mod storage;
pub use controller::*;
pub use key::{PrivateKey, PublicKey, SignError};

View File

@ -12,13 +12,7 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else {
let controller = Controller::new(Storage::try_from(value)?);
value.manage(controller.clone());
Ok(controller)
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -31,7 +25,7 @@ impl TryFrom<&std::path::PathBuf> for Controller {
}
impl Controller {
fn new(storage: Storage) -> Self {
pub fn new(storage: Storage) -> Self {
Self { storage }
}

View File

@ -21,13 +21,7 @@ impl TryFrom<&AppHandle> for Storage {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(storage) = value.try_state::<Storage>() {
Ok(storage.inner().clone())
} else {
let storage = Storage::new(storage::Storage::try_from(value)?);
value.manage(storage.clone());
Ok(storage)
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -40,7 +34,7 @@ impl TryFrom<&std::path::PathBuf> for Storage {
}
impl Storage {
fn new(storage: storage::Storage) -> Storage {
pub fn new(storage: storage::Storage) -> Storage {
Storage { storage }
}

View File

@ -98,48 +98,74 @@ fn main() {
logs::init(&app_handle);
let app_data_dir = app_handle.path_resolver().app_data_dir().expect("missing app data dir");
let app_cache_dir = app_handle.path_resolver().app_cache_dir().expect("missing app cache dir");
let app_log_dir = app_handle.path_resolver().app_log_dir().expect("missing app log dir");
std::fs::create_dir_all(&app_data_dir).expect("failed to create app data dir");
std::fs::create_dir_all(&app_cache_dir).expect("failed to create cache dir");
tracing::info!(version = %app_handle.package_info().version, name = %app_handle.package_info().name, "starting app");
let watchers = watcher::Watchers::try_from(&app_handle)
.expect("failed to initialize watchers");
tauri_app.manage(watchers);
let storage_controller = storage::Storage::new(&app_data_dir);
app_handle.manage(storage_controller.clone());
let proxy =
assets::Proxy::try_from(&app_handle).expect("failed to initialize proxy");
tauri_app.manage(proxy);
let watcher_controller = watcher::Watchers::new(app_handle.clone());
app_handle.manage(watcher_controller.clone());
let database = database::Database::try_from(&app_handle)
.expect("failed to initialize database");
app_handle.manage(database);
let projects_storage_controller = projects::storage::Storage::new(storage_controller.clone());
app_handle.manage(projects_storage_controller.clone());
let storage = storage::Storage::try_from(&app_handle)
.expect("failed to initialize storage");
app_handle.manage(storage);
let users_storage_controller = users::storage::Storage::new(storage_controller.clone());
app_handle.manage(users_storage_controller.clone());
let zipper = zip::Controller::try_from(&app_handle)
.expect("failed to initialize zipc controller ");
tauri_app.manage(zipper);
let users_controller = users::Controller::new(users_storage_controller.clone());
app_handle.manage(users_controller.clone());
let deltas_controller = deltas::Controller::try_from(&app_handle).expect("failed to initialize deltas controller");
let projects_controller = projects::Controller::new(
app_data_dir.clone(),
projects_storage_controller.clone(),
users_controller.clone(),
Some(watcher_controller.clone())
);
app_handle.manage(projects_controller.clone());
app_handle.manage(assets::Proxy::new(app_cache_dir.join("images")));
let database_controller = database::Database::open(app_data_dir.join("database.sqlite3")).expect("failed to open database");
app_handle.manage(database_controller.clone());
let zipper = zip::Zipper::new(&app_cache_dir);
app_handle.manage(zipper.clone());
app_handle.manage(zip::Controller::new(app_data_dir.clone(), app_log_dir.clone(), zipper.clone(), projects_controller.clone()));
let deltas_database_controller = deltas::database::Database::new(database_controller.clone());
app_handle.manage(deltas_database_controller.clone());
let deltas_controller = deltas::Controller::new(deltas_database_controller.clone());
app_handle.manage(deltas_controller);
let sessions_controller = sessions::Controller::try_from(&app_handle)
.expect("failed to initialize sessions controller");
app_handle.manage(sessions_controller);
let keys_storage_controller = keys::storage::Storage::new(storage_controller.clone());
app_handle.manage(keys_storage_controller.clone());
let projects_controller = projects::Controller::try_from(&app_handle)
.expect("failed to initialize projects controller");
app_handle.manage(projects_controller);
let keys_controller = keys::Controller::new(keys_storage_controller.clone());
app_handle.manage(keys_controller.clone());
let vbranch_contoller =
virtual_branches::controller::Controller::try_from(&app_handle)
.expect("failed to initialize virtual branches controller");
app_handle.manage(vbranch_contoller);
let git_credentials_controller = git::credentials::Helper::new(
keys_controller.clone(),
users_controller.clone(),
std::env::var_os("HOME").map(PathBuf::from)
);
app_handle.manage(git_credentials_controller.clone());
let keys_controller = keys::Controller::try_from(&app_handle).expect("failed to initialize keys controller");
app_handle.manage(keys_controller);
let users_controller = users::Controller::try_from(&app_handle).expect("failed to initialize users controller");
app_handle.manage(virtual_branches::controller::Controller::new(
app_data_dir.clone(),
projects_controller.clone(),
users_controller.clone(),
keys_controller.clone(),
git_credentials_controller.clone(),
));
let stores = tauri_app.state::<StoreCollection<Wry>>();
if let Some(path) = app_handle.path_resolver().app_config_dir().map(|path| path.join(PathBuf::from("settings.json"))) {
@ -173,10 +199,23 @@ fn main() {
};
}
app_handle.manage(users_controller);
let sessions_database_controller = sessions::database::Database::new(database_controller.clone());
app_handle.manage(sessions_database_controller.clone());
let app: app::App = app::App::try_from(&tauri_app.app_handle())
.expect("failed to initialize app");
app_handle.manage(sessions::Controller::new(
app_data_dir.clone(),
sessions_database_controller.clone(),
projects_controller.clone(),
users_controller.clone(),
));
let app = app::App::new(
app_data_dir,
projects_controller,
users_controller,
watcher_controller,
sessions_database_controller,
);
app.init().context("failed to init app")?;

View File

@ -1,7 +1,7 @@
pub mod commands;
mod controller;
mod project;
mod storage;
pub mod storage;
pub use controller::*;
pub use project::{AuthKey, CodePushState, FetchResult, Project, ProjectId};

View File

@ -19,18 +19,7 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else if let Some(app_data_dir) = value.path_resolver().app_data_dir() {
Ok(Self {
local_data_dir: app_data_dir,
projects_storage: storage::Storage::try_from(value)?,
users: users::Controller::try_from(value)?,
watchers: Some(watcher::Watchers::try_from(value)?),
})
} else {
Err(anyhow::anyhow!("failed to get app data dir"))
}
Ok(value.state::<Controller>().inner().clone())
}
}
@ -48,6 +37,20 @@ impl TryFrom<&std::path::PathBuf> for Controller {
}
impl Controller {
pub fn new(
local_data_dir: path::PathBuf,
projects_storage: storage::Storage,
users: users::Controller,
watchers: Option<watcher::Watchers>,
) -> Self {
Self {
local_data_dir,
projects_storage,
users,
watchers,
}
}
pub fn add(&self, path: &path::Path) -> Result<Project, AddError> {
let all_projects = self
.projects_storage

View File

@ -17,13 +17,7 @@ impl TryFrom<&AppHandle> for Storage {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(storage) = value.try_state::<Storage>() {
Ok(storage.inner().clone())
} else {
let storage = Storage::new(storage::Storage::try_from(value)?);
value.manage(storage.clone());
Ok(storage)
}
Ok(value.state::<Storage>().inner().clone())
}
}
@ -61,7 +55,7 @@ pub enum Error {
}
impl Storage {
fn new(storage: storage::Storage) -> Storage {
pub fn new(storage: storage::Storage) -> Storage {
Storage { storage }
}

View File

@ -1,11 +1,11 @@
mod controller;
mod database;
mod iterator;
mod reader;
mod session;
mod writer;
pub mod commands;
pub mod database;
#[cfg(test)]
mod tests;

View File

@ -24,18 +24,7 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else if let Some(app_data_dir) = value.path_resolver().app_data_dir() {
Ok(Self {
local_data_dir: app_data_dir,
sessions_database: Database::try_from(value)?,
projects: projects::Controller::try_from(value)?,
users: users::Controller::try_from(value)?,
})
} else {
Err(anyhow::anyhow!("failed to get app data dir"))
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -52,6 +41,20 @@ pub enum ListError {
}
impl Controller {
pub fn new(
local_data_dir: path::PathBuf,
sessions_database: Database,
projects: projects::Controller,
users: users::Controller,
) -> Self {
Self {
local_data_dir,
sessions_database,
projects,
users,
}
}
pub fn list(
&self,
project_id: &ProjectId,

View File

@ -14,18 +14,12 @@ impl TryFrom<&AppHandle> for Database {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(database) = value.try_state::<Database>() {
Ok(database.inner().clone())
} else {
let database = Database::new(database::Database::try_from(value)?);
value.manage(database.clone());
Ok(database)
}
Ok(value.state::<Self>().inner().clone())
}
}
impl Database {
fn new(database: database::Database) -> Database {
pub fn new(database: database::Database) -> Database {
Database { database }
}

View File

@ -24,15 +24,7 @@ impl TryFrom<&AppHandle> for Storage {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(storage) = value.try_state::<Storage>() {
Ok(storage.inner().clone())
} else if let Some(app_data_dir) = value.path_resolver().app_data_dir() {
let storage = Storage::new(app_data_dir);
value.manage(storage.clone());
Ok(storage)
} else {
Err(anyhow::anyhow!("failed to get app data dir"))
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -45,7 +37,7 @@ impl TryFrom<&PathBuf> for Storage {
}
impl Storage {
fn new<P: AsRef<Path>>(local_data_dir: P) -> Storage {
pub fn new<P: AsRef<Path>>(local_data_dir: P) -> Storage {
Storage {
local_data_dir: Arc::new(RwLock::new(local_data_dir.as_ref().to_path_buf())),
}

View File

@ -1,6 +1,6 @@
pub mod commands;
mod controller;
mod storage;
pub mod controller;
pub mod storage;
mod user;
pub use controller::*;

View File

@ -12,13 +12,7 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else {
let controller = Controller::new(Storage::try_from(value)?);
value.manage(controller.clone());
Ok(controller)
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -31,7 +25,7 @@ impl TryFrom<&std::path::PathBuf> for Controller {
}
impl Controller {
fn new(storage: Storage) -> Controller {
pub fn new(storage: Storage) -> Controller {
Controller { storage }
}

View File

@ -22,13 +22,7 @@ impl TryFrom<&AppHandle> for Storage {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(storage) = value.try_state::<Storage>() {
Ok(storage.inner().clone())
} else {
let storage = Storage::new(storage::Storage::try_from(value)?);
value.manage(storage.clone());
Ok(storage)
}
Ok(value.state::<Self>().inner().clone())
}
}
@ -41,7 +35,7 @@ impl TryFrom<&std::path::PathBuf> for Storage {
}
impl Storage {
fn new(storage: storage::Storage) -> Storage {
pub fn new(storage: storage::Storage) -> Storage {
Storage { storage }
}

View File

@ -37,19 +37,7 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else if let Some(app_data_dir) = value.path_resolver().app_data_dir() {
Ok(Self::new(
app_data_dir,
projects::Controller::try_from(value)?,
users::Controller::try_from(value)?,
keys::Controller::try_from(value)?,
git::credentials::Helper::try_from(value)?,
))
} else {
Err(anyhow::anyhow!("failed to get app data dir"))
}
Ok(value.state::<Controller>().inner().clone())
}
}

View File

@ -29,18 +29,12 @@ impl TryFrom<&AppHandle> for Watchers {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(watchers) = value.try_state::<Watchers>() {
Ok(watchers.inner().clone())
} else {
let watchers = Watchers::new(value.clone());
value.manage(watchers.clone());
Ok(watchers)
}
Ok(value.state::<Self>().inner().clone())
}
}
impl Watchers {
fn new(app_handle: AppHandle) -> Self {
pub fn new(app_handle: AppHandle) -> Self {
Self {
app_handle,
watchers: Arc::new(Mutex::new(HashMap::new())),

View File

@ -23,24 +23,14 @@ impl TryFrom<&AppHandle> for Zipper {
type Error = anyhow::Error;
fn try_from(handle: &AppHandle) -> Result<Self> {
if let Some(zipper) = handle.try_state::<Self>() {
Ok(zipper.inner().clone())
} else {
let app_cache_dir = handle
.path_resolver()
.app_cache_dir()
.context("failed to get app cache dir")?;
Self::new(app_cache_dir)
}
Ok(handle.state::<Self>().inner().clone())
}
}
impl Zipper {
fn new<P: AsRef<path::Path>>(cache_dir: P) -> Result<Self, anyhow::Error> {
let cache_dir = cache_dir.as_ref().to_path_buf();
fs::create_dir_all(&cache_dir).context("failed to create cache dir")?;
let cache = cache_dir.join("archives");
Ok(Self { cache })
pub fn new<P: AsRef<path::Path>>(cache_dir: P) -> Self {
let cache = cache_dir.as_ref().to_path_buf().join("archives");
Self { cache }
}
// takes a path to create zip of, returns path of a created archive.
@ -199,7 +189,7 @@ mod tests {
file.write_all(b"test").unwrap();
let zipper_cache = tempdir().unwrap();
let zipper = Zipper::new(zipper_cache.path()).unwrap();
let zipper = Zipper::new(zipper_cache.path());
let zip_file_path = zipper.zip(tmp_dir).unwrap();
assert!(zip_file_path.exists());
}
@ -213,7 +203,7 @@ mod tests {
file.write_all(b"test").unwrap();
let zipper_cache = tempdir().unwrap();
let zipper = Zipper::new(zipper_cache.path()).unwrap();
let zipper = Zipper::new(zipper_cache.path());
zipper.zip(file_path).unwrap_err();
}
@ -226,7 +216,7 @@ mod tests {
file.write_all(b"test").unwrap();
let zipper_cache = tempdir().unwrap();
let zipper = Zipper::new(zipper_cache.path()).unwrap();
let zipper = Zipper::new(zipper_cache.path());
assert_eq!(zipper.zip(&tmp_dir).unwrap(), zipper.zip(&tmp_dir).unwrap());
assert_eq!(WalkDir::new(tmp_dir).into_iter().count(), 1);
}

View File

@ -18,28 +18,12 @@ impl TryFrom<&AppHandle> for Controller {
type Error = anyhow::Error;
fn try_from(value: &AppHandle) -> Result<Self, Self::Error> {
if let Some(controller) = value.try_state::<Controller>() {
Ok(controller.inner().clone())
} else {
let local_data_dir = value
.path_resolver()
.app_data_dir()
.ok_or_else(|| anyhow::anyhow!("failed to get local data dir"))?;
let logs_dir = value
.path_resolver()
.app_log_dir()
.ok_or_else(|| anyhow::anyhow!("failed to get logs dir"))?;
let zipper = Zipper::try_from(value)?;
let projects = projects::Controller::try_from(value)?;
let controller = Controller::new(local_data_dir, logs_dir, zipper, projects);
value.manage(controller.clone());
Ok(controller)
}
Ok(value.state::<Self>().inner().clone())
}
}
impl Controller {
fn new(
pub fn new(
local_data_dir: path::PathBuf,
logs_dir: path::PathBuf,
zipper: Zipper,