Feat: CLI Settings (#2424)
* feat: cli settings * revision: lower msrv * add previous line about hotreload settings just in case * Fix issue with open --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
2ef406982e
commit
9567674a63
13 files changed
+869
-673
No files matched your search
@@ -41,6 +41,9 @@ pub struct DioxusConfig {
|
||||
#[cfg(feature = "cli")]
|
||||
#[serde(default = "default_plugin")]
|
||||
pub plugin: toml::Value,
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
pub cli_settings: Option<crate::CliSettings>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
@@ -116,6 +119,8 @@ impl DioxusConfig {
|
||||
/// Load the dioxus config from a path
|
||||
#[tracing::instrument]
|
||||
pub fn load(bin: Option<PathBuf>) -> Result<Option<DioxusConfig>, CrateConfigError> {
|
||||
use crate::CliSettings;
|
||||
|
||||
let crate_dir = crate::cargo::crate_root();
|
||||
|
||||
let crate_dir = match crate_dir {
|
||||
@@ -157,6 +162,23 @@ impl DioxusConfig {
|
||||
if cfg.bundle.publisher.is_none() {
|
||||
cfg.bundle.publisher = Some(name);
|
||||
}
|
||||
|
||||
// Handle Cli Settings
|
||||
if cfg.cli_settings.is_none() {
|
||||
cfg.cli_settings = Some(CliSettings::default());
|
||||
}
|
||||
|
||||
let cli_settings = cfg.cli_settings.as_mut().unwrap();
|
||||
// If the project-level settings doesn't exist, let's grab it from global.
|
||||
if let Some(global_cli_settings) = crate::CliSettings::from_global() {
|
||||
if cli_settings.always_hot_reload.is_none() {
|
||||
cli_settings.always_hot_reload = global_cli_settings.always_hot_reload;
|
||||
}
|
||||
if cli_settings.always_open_browser.is_none() {
|
||||
cli_settings.always_open_browser = global_cli_settings.always_open_browser;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Some(cfg))
|
||||
}
|
||||
cfg => cfg,
|
||||
@@ -185,7 +207,6 @@ impl Default for DioxusConfig {
|
||||
default_platform: default_platform(),
|
||||
out_dir: out_dir_default(),
|
||||
asset_dir: asset_dir_default(),
|
||||
hot_reload: hot_reload_default(),
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
tools: Default::default(),
|
||||
@@ -223,6 +244,9 @@ impl Default for DioxusConfig {
|
||||
},
|
||||
#[cfg(feature = "cli")]
|
||||
plugin: toml::Value::Table(toml::map::Map::new()),
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
cli_settings: Some(crate::CliSettings::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,9 +265,6 @@ pub struct ApplicationConfig {
|
||||
#[serde(default = "asset_dir_default")]
|
||||
pub asset_dir: PathBuf,
|
||||
|
||||
#[serde(default = "hot_reload_default")]
|
||||
pub hot_reload: bool,
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
#[serde(default)]
|
||||
pub tools: std::collections::HashMap<String, toml::Value>,
|
||||
@@ -260,10 +281,6 @@ fn default_platform() -> Platform {
|
||||
Platform::Web
|
||||
}
|
||||
|
||||
fn hot_reload_default() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn asset_dir_default() -> PathBuf {
|
||||
PathBuf::from("public")
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
mod config;
|
||||
pub use config::*;
|
||||
|
||||
mod bundle;
|
||||
pub use bundle::*;
|
||||
|
||||
mod cargo;
|
||||
pub use cargo::*;
|
||||
#[cfg(feature = "cli")]
|
||||
@@ -13,6 +15,12 @@ mod serve;
|
||||
#[cfg(feature = "cli")]
|
||||
pub use serve::*;
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
mod settings;
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
pub use settings::*;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod __private {
|
||||
use crate::CrateConfig;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
use crate::CrateConfigError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fs,
|
||||
io::{Error, ErrorKind},
|
||||
path::PathBuf,
|
||||
};
|
||||
use tracing::{debug, error, warn};
|
||||
|
||||
const GLOBAL_SETTINGS_FILE_NAME: &str = "dioxus/settings.toml";
|
||||
|
||||
/// Describes cli settings from project or global level.
|
||||
/// The order of priority goes:
|
||||
/// 1. CLI Flags/Arguments
|
||||
/// 2. Project-level Settings
|
||||
/// 3. Global-level settings.
|
||||
///
|
||||
/// This allows users to control the cli settings with ease.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct CliSettings {
|
||||
/// Describes whether hot reload should always be on.
|
||||
pub always_hot_reload: Option<bool>,
|
||||
/// Describes whether the CLI should always open the browser for Web targets.
|
||||
pub always_open_browser: Option<bool>,
|
||||
}
|
||||
|
||||
impl CliSettings {
|
||||
/// Get the current settings structure from global.
|
||||
pub fn from_global() -> Option<Self> {
|
||||
let Some(path) = dirs::data_local_dir() else {
|
||||
warn!("failed to get local data directory, some config keys may be missing");
|
||||
return None;
|
||||
};
|
||||
|
||||
let path = path.join(GLOBAL_SETTINGS_FILE_NAME);
|
||||
let Some(data) = fs::read_to_string(path).ok() else {
|
||||
// We use a debug here because we expect the file to not exist.
|
||||
debug!("failed to read `{}` config file", GLOBAL_SETTINGS_FILE_NAME);
|
||||
return None;
|
||||
};
|
||||
|
||||
let data = toml::from_str::<CliSettings>(&data).ok();
|
||||
if data.is_none() {
|
||||
warn!(
|
||||
"failed to parse `{}` config file",
|
||||
GLOBAL_SETTINGS_FILE_NAME
|
||||
);
|
||||
}
|
||||
|
||||
data
|
||||
}
|
||||
|
||||
/// Save the current structure to the global settings toml.
|
||||
/// This does not save to project-level settings.
|
||||
pub fn save(self) -> Result<Self, CrateConfigError> {
|
||||
let path = Self::get_settings_path().ok_or_else(|| {
|
||||
error!("failed to get settings path");
|
||||
CrateConfigError::Io(Error::new(
|
||||
ErrorKind::NotFound,
|
||||
"failed to get settings path",
|
||||
))
|
||||
})?;
|
||||
|
||||
let data = toml::to_string_pretty(&self).map_err(|e| {
|
||||
error!(?self, "failed to parse config into toml");
|
||||
CrateConfigError::Io(Error::new(ErrorKind::Other, e.to_string()))
|
||||
})?;
|
||||
|
||||
let result = fs::write(path.clone(), data.clone());
|
||||
if let Err(e) = result {
|
||||
error!(?data, ?path, "failed to save global cli settings");
|
||||
return Err(CrateConfigError::Io(e));
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Get the path to the settings toml file.
|
||||
pub fn get_settings_path() -> Option<PathBuf> {
|
||||
let Some(path) = dirs::data_local_dir() else {
|
||||
warn!("failed to get local data directory, some config keys may be missing");
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(path.join(GLOBAL_SETTINGS_FILE_NAME))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user