Skip to content

Commit

Permalink
Code cleanups; #20
Browse files Browse the repository at this point in the history
  • Loading branch information
msuchane committed Feb 27, 2024
1 parent 698fba1 commit 87a0ff7
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 27 deletions.
2 changes: 0 additions & 2 deletions src/cmd_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,5 @@ const SOME_FILES: &str = "Specify at least one file to generate or validate.";
/// Get command-line arguments as the `Cli` struct.
#[must_use]
pub fn get_args() -> Cli {
let def = Cli::default();
println!("default args: {:#?}", def);
cli().run()
}
79 changes: 60 additions & 19 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
/*
newdoc: Generate pre-populated documentation modules formatted with AsciiDoc.
Copyright (C) 2024 Marek Suchánek <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

//! # `config.rs`
//!
//! This module defines the global options merged from the command line,
//! the configuration files, and the defaults.
use std::path::PathBuf;

use color_eyre::eyre::{Result, WrapErr};
use directories::ProjectDirs;
use figment::{Figment, providers::{Format, Toml, Serialized}};
use serde::{Serialize, Deserialize};
Expand Down Expand Up @@ -89,39 +113,56 @@ impl Default for Options {
}
}

pub fn merge_configs(cli_options: Options) -> Options {
let proj_dirs = ProjectDirs::from("com", "Red Hat", PKG_NAME)
.expect("Failed to find a home directory.");
/// Try to locale the appropriate per-user configuration file on this platform.
fn home_conf_file() -> Option<PathBuf> {
let proj_dirs = ProjectDirs::from("com", "Red Hat", PKG_NAME)?;
let conf_dir = proj_dirs.config_dir();
let conf_file = conf_dir.join(format!("{PKG_NAME}.toml"));
println!("Configuration file: {}", conf_file.display());

let target_dir = &cli_options.target_dir;

let default_options = Options::default();
Some(conf_file)
}

let mut figment = Figment::from(Serialized::defaults(default_options))
.merge(Toml::file(conf_file));
/// If the target location is in a Git repository, construct the path
/// to a configuration file at the repository's root.
fn git_conf_file(cli_options: &Options) -> Option<PathBuf> {
let target_dir = &cli_options.target_dir;

// Find the earliest ancestor directory that appears to be the root of a Git repo.
let git_root = target_dir.ancestors().find(|dir| {
// The simple heuristic is that the directory is the Git root if it contains
// the `.git/` sub-directory.
let git_dir = dir.join(".git");
git_dir.is_dir()
});
})?;

if let Some(git_root) = git_root {
let git_proj_config = git_root.join(format!(".{PKG_NAME}.toml"));
println!("git project config: {}", git_proj_config.display());
figment = figment.merge(Toml::file(git_proj_config));
let git_proj_config = git_root.join(format!(".{PKG_NAME}.toml"));

Some(git_proj_config)
}

pub fn merge_configs(cli_options: Options) -> Result<Options> {
let default_options = Options::default();
let mut figment = Figment::from(Serialized::defaults(default_options));

if let Some(home_conf_file) = home_conf_file() {
log::info!("Home configuration file: {}", home_conf_file.display());
figment = figment.merge(Toml::file(home_conf_file));
} else {
// If the directory lookup fails because there's no home directory,
// skip the processing of the home configuration file.
log::warn!("Failed to locate a home directory. Skipping home configuration.");
};

if let Some(git_conf_file) = git_conf_file(&cli_options) {
log::info!("Git repo configuration file: {}", git_conf_file.display());
figment = figment.merge(Toml::file(git_conf_file));
}

println!("figment: {:#?}", figment);
log::debug!("Figment configuration: {figment:#?}");

let mut conf_options: Options = figment.extract().unwrap();
let mut conf_options: Options = figment.extract().wrap_err("Failed to load configuration files.")?;

conf_options.update_from_non_default(&cli_options);

println!("complete options: {:#?}", conf_options);

conf_options
Ok(conf_options)
}
5 changes: 1 addition & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use color_eyre::eyre::{bail, Result};

pub mod cmd_line;
pub mod config;
mod logging;
pub mod logging;
mod module;
mod templating;
mod write;
Expand All @@ -53,9 +53,6 @@ const REGEX_ERROR: &str = "Failed to construct a regular expression. Please repo


pub fn run(options: &Options, cli: &Cli) -> Result<()> {
// Initialize the logging system based on the set verbosity
logging::initialize_logger(options.verbosity)?;

log::debug!("Active options:\n{:#?}", &options);

// Report any deprecated options.
Expand Down
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.

use color_eyre::eyre::Result;

use newdoc::{cmd_line, config, Options};
use newdoc::{cmd_line, config, logging, Options};

fn main() -> Result<()> {
// Enable full-featured error logging.
Expand All @@ -27,10 +27,13 @@ fn main() -> Result<()> {
// Parse the command-line options
let cmdline_args = cmd_line::get_args();

// Initialize the logging system based on the set verbosity
logging::initialize_logger(cmdline_args.common_options.verbosity)?;

// Set current options based on the command-line options
let cli_options = Options::new(&cmdline_args);

let options = config::merge_configs(cli_options);
let options = config::merge_configs(cli_options)?;

// Run the main functionality
newdoc::run(&options, &cmdline_args)?;
Expand Down

0 comments on commit 87a0ff7

Please sign in to comment.