Move launcher working directory to standard location (#31)

* Move launcher working directory to standard location

* Fix settings save, attempt to get better backtraces

* Add environment variable for settings path
This commit is contained in:
Danielle
2022-04-10 13:14:53 -07:00
committed by GitHub
parent a20f6596ce
commit 8935d0e56c
6 changed files with 31 additions and 30 deletions

2
Cargo.lock generated
View File

@@ -3866,9 +3866,11 @@ dependencies = [
"chrono", "chrono",
"const_format", "const_format",
"daedalus", "daedalus",
"dirs 4.0.0",
"fs_extra", "fs_extra",
"futures", "futures",
"json5", "json5",
"lazy_static",
"log", "log",
"once_cell", "once_cell",
"path-clean", "path-clean",

View File

@@ -24,6 +24,7 @@ zip-extensions = "0.6"
sha1 = { version = "0.6.0", features = ["std"]} sha1 = { version = "0.6.0", features = ["std"]}
path-clean = "0.1.0" path-clean = "0.1.0"
fs_extra = "1.2.0" fs_extra = "1.2.0"
dirs = "4.0"
regex = "1.5" regex = "1.5"
@@ -35,6 +36,7 @@ sys-info = "0.9.0"
log = "0.4.14" log = "0.4.14"
const_format = "0.2.22" const_format = "0.2.22"
once_cell = "1.9.0" once_cell = "1.9.0"
lazy_static = "1.4"
[dev-dependencies] [dev-dependencies]
argh = "0.1.6" argh = "0.1.6"

View File

@@ -1,5 +1,3 @@
use std::path::Path;
use crate::{data::DataError, LAUNCHER_WORK_DIR}; use crate::{data::DataError, LAUNCHER_WORK_DIR};
use once_cell::sync; use once_cell::sync;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -19,12 +17,13 @@ pub struct Metadata {
impl Metadata { impl Metadata {
pub async fn init() -> Result<(), DataError> { pub async fn init() -> Result<(), DataError> {
let meta_path = Path::new(LAUNCHER_WORK_DIR).join(META_FILE); let meta_path = LAUNCHER_WORK_DIR.join(META_FILE);
if meta_path.exists() { if meta_path.exists() {
let meta_data = std::fs::read_to_string(meta_path) let meta_data = tokio::fs::read_to_string(meta_path)
.await
.ok() .ok()
.and_then(|x| serde_json::from_str::<Metadata>(&x).ok()); .and_then(|it| serde_json::from_str::<Metadata>(&it).ok());
if let Some(metadata) = meta_data { if let Some(metadata) = meta_data {
METADATA.get_or_init(|| RwLock::new(metadata)); METADATA.get_or_init(|| RwLock::new(metadata));
@@ -37,7 +36,7 @@ impl Metadata {
let new = Self::fetch().await?; let new = Self::fetch().await?;
std::fs::write( std::fs::write(
Path::new(LAUNCHER_WORK_DIR).join(META_FILE), LAUNCHER_WORK_DIR.join(META_FILE),
&serde_json::to_string(&new)?, &serde_json::to_string(&new)?,
)?; )?;

View File

@@ -1,8 +1,5 @@
use super::profiles::*; use super::profiles::*;
use std::{ use std::{collections::HashSet, path::PathBuf};
collections::HashSet,
path::{Path, PathBuf},
};
use crate::{data::DataError, LAUNCHER_WORK_DIR}; use crate::{data::DataError, LAUNCHER_WORK_DIR};
use once_cell::sync; use once_cell::sync;
@@ -12,6 +9,7 @@ use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
const SETTINGS_FILE: &str = "settings.json"; const SETTINGS_FILE: &str = "settings.json";
const ICONS_PATH: &str = "icons"; const ICONS_PATH: &str = "icons";
const METADATA_DIR: &str = "meta"; const METADATA_DIR: &str = "meta";
const SETTINGS_PATH_ENV: &str = "THESEUS_CONFIG_DIR";
static SETTINGS: sync::OnceCell<RwLock<Settings>> = sync::OnceCell::new(); static SETTINGS: sync::OnceCell<RwLock<Settings>> = sync::OnceCell::new();
pub const FORMAT_VERSION: u32 = 1; pub const FORMAT_VERSION: u32 = 1;
@@ -41,8 +39,8 @@ impl Default for Settings {
java_8_path: None, java_8_path: None,
java_17_path: None, java_17_path: None,
hooks: ProfileHooks::default(), hooks: ProfileHooks::default(),
icon_path: Path::new(LAUNCHER_WORK_DIR).join(ICONS_PATH), icon_path: LAUNCHER_WORK_DIR.join(ICONS_PATH),
metadata_dir: Path::new(LAUNCHER_WORK_DIR).join(METADATA_DIR), metadata_dir: LAUNCHER_WORK_DIR.join(METADATA_DIR),
profiles: HashSet::new(), profiles: HashSet::new(),
max_concurrent_downloads: 32, max_concurrent_downloads: 32,
version: FORMAT_VERSION, version: FORMAT_VERSION,
@@ -52,10 +50,12 @@ impl Default for Settings {
impl Settings { impl Settings {
pub async fn init() -> Result<(), DataError> { pub async fn init() -> Result<(), DataError> {
let settings_path = Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE); let settings_path = std::env::var_os(SETTINGS_PATH_ENV)
.map_or(LAUNCHER_WORK_DIR.join(SETTINGS_FILE), PathBuf::from);
if settings_path.exists() { if settings_path.exists() {
let settings_data = std::fs::read_to_string(settings_path) let settings_data = tokio::fs::read_to_string(settings_path)
.await
.map(|x| serde_json::from_str::<Settings>(&x).ok()) .map(|x| serde_json::from_str::<Settings>(&x).ok())
.ok() .ok()
.flatten(); .flatten();
@@ -68,11 +68,8 @@ impl Settings {
if SETTINGS.get().is_none() { if SETTINGS.get().is_none() {
let new = Self::default(); let new = Self::default();
tokio::fs::rename(SETTINGS_FILE, format!("{SETTINGS_FILE}.bak"))
.await?;
tokio::fs::write( tokio::fs::write(
Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE), LAUNCHER_WORK_DIR.join(SETTINGS_FILE),
&serde_json::to_string(&new)?, &serde_json::to_string(&new)?,
) )
.await?; .await?;
@@ -85,7 +82,7 @@ impl Settings {
pub async fn load() -> Result<(), DataError> { pub async fn load() -> Result<(), DataError> {
let new = serde_json::from_str::<Settings>(&std::fs::read_to_string( let new = serde_json::from_str::<Settings>(&std::fs::read_to_string(
Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE), LAUNCHER_WORK_DIR.join(SETTINGS_FILE),
)?)?; )?)?;
let mut write = SETTINGS let mut write = SETTINGS
@@ -103,7 +100,7 @@ impl Settings {
let settings = Self::get().await?; let settings = Self::get().await?;
std::fs::write( std::fs::write(
Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE), LAUNCHER_WORK_DIR.join(SETTINGS_FILE),
&serde_json::to_string_pretty(&*settings)?, &serde_json::to_string_pretty(&*settings)?,
)?; )?;

View File

@@ -5,7 +5,10 @@
#![warn(unused_import_braces, missing_debug_implementations)] #![warn(unused_import_braces, missing_debug_implementations)]
static LAUNCHER_WORK_DIR: &'static str = "./launcher"; // TODO: make non-hardcoded
lazy_static::lazy_static! {
static ref LAUNCHER_WORK_DIR: std::path::PathBuf = dirs::config_dir().expect("Could not find config dir").join("theseus");
}
pub mod data; pub mod data;
pub mod launcher; pub mod launcher;
@@ -25,7 +28,8 @@ pub enum Error {
} }
pub async fn init() -> Result<(), Error> { pub async fn init() -> Result<(), Error> {
std::fs::create_dir_all(LAUNCHER_WORK_DIR) tokio::fs::create_dir_all(LAUNCHER_WORK_DIR.as_path())
.await
.expect("Unable to create launcher root directory!"); .expect("Unable to create launcher root directory!");
use crate::data::*; use crate::data::*;

View File

@@ -1,4 +1,5 @@
use eyre::Result; use eyre::Result;
use futures::TryFutureExt;
use paris::*; use paris::*;
mod subcommands; mod subcommands;
@@ -16,12 +17,8 @@ async fn main() -> Result<()> {
let args = argh::from_env::<Args>(); let args = argh::from_env::<Args>();
theseus::init().await?; theseus::init().await?;
let res = args.dispatch().await; args.dispatch()
if res.is_err() { .inspect_err(|_| error!("An error has occurred!\n"))
error!("An error has occurred!\n"); .and_then(|_| async { Ok(theseus::save().await?) })
} else { .await
theseus::save().await?;
}
res
} }