add sfdx_auth_url setting

This commit is contained in:
Wim Velzeboer
2026-09-07 10:42:55 +01:00
parent fb5e462564
commit 1d37b13941
4 changed files with 177 additions and 116 deletions
+164 -114
View File
@@ -1,122 +1,124 @@
use crate::logger; use crate::logger;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use clap::{Parser, ValueEnum}; use clap::{CommandFactory, Parser, ValueEnum};
use log::error; use log::{error, info};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
struct Cli { struct Cli {
/// Number of seconds to wait /// Number of seconds to wait
#[arg(short = 'w', long, default_value_t = 20, env = "IMOJEFS_WAIT")] #[arg(short = 'w', long, default_value_t = 20, env = "IMOJEFS_WAIT")]
pub wait: u64, pub wait: u64,
/// The logging level /// The logging level
#[arg(short = 'l', long, value_enum, default_value_t = LogLevel::Info, env = "IMOJEFS_LOG_LEVEL")] #[arg(short = 'l', long, value_enum, default_value_t = LogLevel::Info, env = "IMOJEFS_LOG_LEVEL"
pub log_level: LogLevel, )]
pub log_level: LogLevel,
/// The configuration to use /// The configuration to use
#[arg(short = 'c', long, default_value_t = String::from("imoje"))] #[arg(short = 'c', long, default_value_t = String::from("imoje"))]
config: String, config: String,
#[command(subcommand)] #[command(subcommand)]
command: Option<Commands>, command: Option<Commands>,
} }
#[derive(clap::Subcommand, Debug)] #[derive(clap::Subcommand, Debug)]
enum Commands { enum Commands {
/// Controls testing features /// Controls testing features
FileSync, FileSync,
/// Change Settings /// Change Settings
Set { Set {
#[command(subcommand)] #[command(subcommand)]
command: Option<SettingsCommands>, command: Option<SettingsCommands>,
}, },
} }
#[derive(clap::Subcommand, Debug)] #[derive(clap::Subcommand, Debug)]
enum SettingsCommands { enum SettingsCommands {
/// Set the Salesforce Authentication Url
SfdxAuthUrl { /// Set the Salesforce Authentication Url
/// Salesforce Authentication Url SfdxAuthUrl {
#[arg( /// Salesforce Authentication Url
short = 'x', #[arg(
long, short = 'x',
env = "IMOJEEH_SFDX_AUTH_URL", long,
hide_env_values = true env = "IMOJEFS_SFDX_AUTH_URL",
)] hide_env_values = true
url: String, )]
}, url: String,
},
} }
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
pub struct Args { pub struct Args {
/// AWS Bucket name /// AWS Bucket name
#[arg(short = 'b', long, env = "IMOJEFS_S3_BUCKET")] #[arg(short = 'b', long, env = "IMOJEFS_S3_BUCKET")]
pub s3_bucket: String, pub s3_bucket: String,
/// AWS Access Key Id /// AWS Access Key Id
#[arg(short = 'k', long, env = "IMOJEFS_S3_CLIENT_ID")] #[arg(short = 'k', long, env = "IMOJEFS_S3_CLIENT_ID")]
pub s3_client_id: String, pub s3_client_id: String,
/// AWS Secret Access Key /// AWS Secret Access Key
#[arg( #[arg(
short = 's', short = 's',
long, long,
env = "IMOJEFS_S3_CLIENT_SECRET", env = "IMOJEFS_S3_CLIENT_SECRET",
hide_env_values = true hide_env_values = true
)] )]
pub s3_client_secret: String, pub s3_client_secret: String,
/// AWS Endpoint URL, [default: AWS url] /// AWS Endpoint URL, [default: AWS url]
#[arg(short = 'e', long, env = "IMOJEFS_S3_ENDPOINT")] #[arg(short = 'e', long, env = "IMOJEFS_S3_ENDPOINT")]
pub s3_endpoint: Option<String>, pub s3_endpoint: Option<String>,
/// AWS Region /// AWS Region
#[arg( #[arg(
short = 'r', short = 'r',
long, long,
default_value = "us-east-1", default_value = "us-east-1",
env = "IMOJEFS_S3_REGION" env = "IMOJEFS_S3_REGION"
)] )]
pub s3_region: String, pub s3_region: String,
/// Salesforce Authentication Url /// Salesforce Authentication Url
#[arg( #[arg(
short = 'x', short = 'x',
long, long,
env = "IMOJEFS_SFDX_AUTH_URL", env = "IMOJEFS_SFDX_AUTH_URL",
hide_env_values = true hide_env_values = true
)] )]
pub sfdx_auth_url: String, pub sfdx_auth_url: String,
/// Retry failures after X runs /// Retry failures after X runs
#[arg(long, default_value_t = 180, env = "IMOJEFS_RETRY")] #[arg(long, default_value_t = 180, env = "IMOJEFS_RETRY")]
pub retry: u64, pub retry: u64,
/// A comma separated list of fallback email address, /// A comma separated list of fallback email address,
/// used when Salesforce cannot be reached to deliver log messages /// used when Salesforce cannot be reached to deliver log messages
#[arg(short = 'a', long, env = "IMOJEFS_ADMIN_EMAIL")] #[arg(short = 'a', long, env = "IMOJEFS_ADMIN_EMAIL")]
pub admin_email: Option<String>, pub admin_email: Option<String>,
} }
impl Args { impl Args {
pub(crate) fn s3_bucket(&self) -> &str { pub(crate) fn s3_bucket(&self) -> &str {
&self.s3_bucket &self.s3_bucket
} }
pub(crate) fn s3_client_id(&self) -> &str { pub(crate) fn s3_client_id(&self) -> &str {
&self.s3_client_id &self.s3_client_id
} }
pub(crate) fn s3_client_secret(&self) -> &str { pub(crate) fn s3_client_secret(&self) -> &str {
&self.s3_client_secret &self.s3_client_secret
} }
pub(crate) fn s3_endpoint(&self) -> Option<&str> { pub(crate) fn s3_endpoint(&self) -> Option<&str> {
self.s3_endpoint.as_deref() self.s3_endpoint.as_deref()
} }
pub(crate) fn s3_region(&self) -> &str { pub(crate) fn s3_region(&self) -> &str {
&self.s3_region &self.s3_region
} }
} }
/// Represents the different levels of logging that can be used in an application. /// Represents the different levels of logging that can be used in an application.
@@ -131,39 +133,87 @@ impl Args {
/// as well as `Clone` and `Debug` for efficient copying and debugging purposes. /// as well as `Clone` and `Debug` for efficient copying and debugging purposes.
#[derive(ValueEnum, Clone, Debug)] #[derive(ValueEnum, Clone, Debug)]
pub enum LogLevel { pub enum LogLevel {
Debug, Debug,
Info, Info,
Warning, Warning,
Error, Error,
Trace, Trace,
} }
fn load_configuration_file(config_file: &str) -> Result<()> { fn load_configuration_file(config_file: &str) -> Result<()> {
let app_config = let app_config =
crate::config::load(config_file).context("Failed to load application configuration")?; crate::config::load(config_file).context("Failed to load application configuration")?;
crate::APP_CONFIG crate::APP_CONFIG
.set(app_config) .set(app_config)
.map_err(|_| anyhow::anyhow!("Application configuration has already been initialized"))?; .map_err(|_| anyhow::anyhow!("Application configuration has already been initialized"))?;
Ok(()) Ok(())
} }
fn set_sfdx_auth_url(config_file: &str, url: String) -> Result<()> {
let mut app_config =
crate::config::load(config_file).context("Failed to load application configuration")?;
app_config.sfdx_auth_url = Some(url);
crate::config::save(config_file, &app_config)
.context("Failed to save Salesforce authentication URL")?;
Ok(())
}
pub(crate) fn run() { pub(crate) fn run() {
let cli = Cli::parse(); let cli = Cli::parse();
logger::init(&cli.log_level); match &cli.command {
match load_configuration_file(&cli.config) { Some(command) => match command {
Ok(()) => {} Commands::Set { command } => {
Err(e) => { run_set_command(&cli, command);
error!("Error loading configuration file: {:#}", e); },
std::process::exit(1); Commands::FileSync { .. } => {
} run_file_sync(&cli);
} }
},
match cli.command { None => {
Some(subcommand) => match subcommand { println!("Expected subcommand, none given. Use --help for more information");
Commands::FileSync { .. } => {} std::process::exit(1);
Commands::Set { .. } => {} }
}, }
None => {} }
}
fn run_file_sync(cli: &Cli) {
logger::init(&cli.log_level);
match load_configuration_file(&cli.config) {
Ok(()) => {}
Err(e) => {
error!("Error loading configuration file: {:#}", e);
std::process::exit(1);
}
}
crate::file_sync::run();
}
fn run_set_command(cli: &Cli, commands: &Option<SettingsCommands>) {
match commands {
Some(command) => match command {
SettingsCommands::SfdxAuthUrl { url } => {
match set_sfdx_auth_url(&cli.config, url.clone()) {
Ok(()) => {
println!("Salesforce authentication URL saved successfully");
}
Err(e) => {
error!("Error saving Salesforce authentication URL: {:#}", e);
std::process::exit(1);
}
}
}
},
None => {
println!("Expected subcommand, none given. Use --help for more information");
std::process::exit(1);
}
}
} }
+8 -2
View File
@@ -15,13 +15,13 @@ const NONCE_LEN: usize = 12;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppConfig { pub struct AppConfig {
pub dummy_setting: String, pub sfdx_auth_url: Option<String>,
} }
impl Default for AppConfig { impl Default for AppConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
dummy_setting: "dummy-value".to_string(), sfdx_auth_url: None,
} }
} }
} }
@@ -44,6 +44,12 @@ pub fn load(config_file: &str) -> Result<AppConfig> {
.with_context(|| format!("Unable to decrypt configuration file {}", config_path.display())) .with_context(|| format!("Unable to decrypt configuration file {}", config_path.display()))
} }
pub fn save(config_file: &str, config: &AppConfig) -> Result<()> {
let config_path = config_path(config_file)?;
save_encrypted(&config_path, config)
.with_context(|| format!("Unable to save configuration file {}", config_path.display()))
}
fn config_path(config_file: &str) -> Result<PathBuf> { fn config_path(config_file: &str) -> Result<PathBuf> {
let home_dir = dirs::home_dir().ok_or_else(|| anyhow!("Unable to determine home directory"))?; let home_dir = dirs::home_dir().ok_or_else(|| anyhow!("Unable to determine home directory"))?;
+3
View File
@@ -0,0 +1,3 @@
pub fn run() {
unimplemented!("File sync not yet implemented");
}
+2
View File
@@ -14,6 +14,8 @@ mod logger;
mod salesforce; mod salesforce;
mod terminator; mod terminator;
mod file_sync;
pub static APP_CONFIG: OnceLock<config::AppConfig> = OnceLock::new(); pub static APP_CONFIG: OnceLock<config::AppConfig> = OnceLock::new();