feat: Added two new flags to output where gman writes logs to and where it expects the config file to live
This commit is contained in:
@@ -177,6 +177,15 @@ $HOME/Library/Application Support/rs.gman/config.yml
|
|||||||
%APPDATA%/Roaming/gman/config.yml
|
%APPDATA%/Roaming/gman/config.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Discover paths (helpful for debugging)
|
||||||
|
|
||||||
|
You can ask `gman` where it writes its log file and where it expects the config file to live:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
gman --show-log-path
|
||||||
|
gman --show-config-path
|
||||||
|
```
|
||||||
|
|
||||||
### Default Configuration
|
### Default Configuration
|
||||||
|
|
||||||
`gman` supports multiple providers. Select one as the default and then list provider configurations.
|
`gman` supports multiple providers. Select one as the default and then list provider configurations.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#[cfg(not(windows))]
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|||||||
+22
-3
@@ -7,7 +7,7 @@ use anyhow::{Context, Result};
|
|||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
use crossterm::execute;
|
use crossterm::execute;
|
||||||
use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};
|
use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};
|
||||||
use gman::config::load_config;
|
use gman::config::{get_config_file_path, load_config};
|
||||||
use heck::ToSnakeCase;
|
use heck::ToSnakeCase;
|
||||||
use std::io::{self, IsTerminal, Read, Write};
|
use std::io::{self, IsTerminal, Read, Write};
|
||||||
use std::panic::PanicHookInfo;
|
use std::panic::PanicHookInfo;
|
||||||
@@ -31,6 +31,7 @@ enum OutputFormat {
|
|||||||
author = crate_authors!(),
|
author = crate_authors!(),
|
||||||
version = crate_version!(),
|
version = crate_version!(),
|
||||||
about = crate_description!(),
|
about = crate_description!(),
|
||||||
|
arg_required_else_help = true,
|
||||||
help_template = "\
|
help_template = "\
|
||||||
{before-help}{name} {version}
|
{before-help}{name} {version}
|
||||||
{author-with-newline}
|
{author-with-newline}
|
||||||
@@ -56,8 +57,16 @@ struct Cli {
|
|||||||
#[arg(long, global = true)]
|
#[arg(long, global = true)]
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
|
|
||||||
|
/// Print the log file path and exit
|
||||||
|
#[arg(long, global = true)]
|
||||||
|
show_log_path: bool,
|
||||||
|
|
||||||
|
/// Print the config file path and exit
|
||||||
|
#[arg(long, global = true)]
|
||||||
|
show_config_path: bool,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Commands,
|
command: Option<Commands>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Clone, Debug)]
|
#[derive(Subcommand, Clone, Debug)]
|
||||||
@@ -115,11 +124,21 @@ fn main() -> Result<()> {
|
|||||||
panic_hook(info);
|
panic_hook(info);
|
||||||
}));
|
}));
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
if cli.show_log_path {
|
||||||
|
println!("{}", utils::get_log_path().display());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if cli.show_config_path {
|
||||||
|
println!("{}", get_config_file_path()?.display());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let config = load_config()?;
|
let config = load_config()?;
|
||||||
let mut provider_config = config.extract_provider_config(cli.provider.clone())?;
|
let mut provider_config = config.extract_provider_config(cli.provider.clone())?;
|
||||||
let secrets_provider = provider_config.extract_provider();
|
let secrets_provider = provider_config.extract_provider();
|
||||||
|
|
||||||
match cli.command {
|
match cli.command.with_context(|| "no command provided")? {
|
||||||
Commands::Add { name } => {
|
Commands::Add { name } => {
|
||||||
let plaintext =
|
let plaintext =
|
||||||
read_all_stdin().with_context(|| "unable to read plaintext from stdin")?;
|
read_all_stdin().with_context(|| "unable to read plaintext from stdin")?;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use log4rs::append::console::ConsoleAppender;
|
|||||||
use log4rs::append::file::FileAppender;
|
use log4rs::append::file::FileAppender;
|
||||||
use log4rs::config::{Appender, Root};
|
use log4rs::config::{Appender, Root};
|
||||||
use log4rs::encode::pattern::PatternEncoder;
|
use log4rs::encode::pattern::PatternEncoder;
|
||||||
use std::fs;
|
use std::{env, fs};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn init_logging_config() -> log4rs::Config {
|
pub fn init_logging_config() -> log4rs::Config {
|
||||||
@@ -11,7 +11,6 @@ pub fn init_logging_config() -> log4rs::Config {
|
|||||||
"{d(%Y-%m-%d %H:%M:%S%.3f)(utc)} <{i}> [{l}] {f}:{L} - {m}{n}",
|
"{d(%Y-%m-%d %H:%M:%S%.3f)(utc)} <{i}> [{l}] {f}:{L} - {m}{n}",
|
||||||
));
|
));
|
||||||
|
|
||||||
// Prefer file logging, but fall back to console if we cannot create/open the file.
|
|
||||||
let file_appender = FileAppender::builder()
|
let file_appender = FileAppender::builder()
|
||||||
.encoder(encoder.clone())
|
.encoder(encoder.clone())
|
||||||
.build(get_log_path());
|
.build(get_log_path());
|
||||||
@@ -44,18 +43,16 @@ pub fn init_logging_config() -> log4rs::Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_log_path() -> PathBuf {
|
pub fn get_log_path() -> PathBuf {
|
||||||
// Use a cache directory on all platforms; fall back to temp dir as a last resort.
|
let base_dir = dirs::cache_dir().unwrap_or_else(env::temp_dir);
|
||||||
let base_dir = dirs::cache_dir().unwrap_or_else(std::env::temp_dir);
|
|
||||||
let log_dir = base_dir.join("gman");
|
let log_dir = base_dir.join("gman");
|
||||||
|
|
||||||
// Best-effort: create the directory; if it fails, write directly into temp dir.
|
|
||||||
let dir = if let Err(e) = fs::create_dir_all(&log_dir) {
|
let dir = if let Err(e) = fs::create_dir_all(&log_dir) {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to create log directory '{}': {}",
|
"Failed to create log directory '{}': {}",
|
||||||
log_dir.display(),
|
log_dir.display(),
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
std::env::temp_dir()
|
env::temp_dir()
|
||||||
} else {
|
} else {
|
||||||
log_dir
|
log_dir
|
||||||
};
|
};
|
||||||
@@ -71,7 +68,6 @@ mod tests {
|
|||||||
fn test_get_log_path() {
|
fn test_get_log_path() {
|
||||||
let log_path = get_log_path();
|
let log_path = get_log_path();
|
||||||
assert!(log_path.ends_with("gman.log"));
|
assert!(log_path.ends_with("gman.log"));
|
||||||
// Parent directory may be cache dir or temp dir; ensure it is a valid path component.
|
|
||||||
assert!(log_path.parent().is_some());
|
assert!(log_path.parent().is_some());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user