From 1d68e80a7fc45e00df2c84f31f738cf5039704d1 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Wed, 17 Dec 2025 16:48:58 +0100 Subject: [PATCH] feature: add optional configuration via `.mono.toml` Signed-off-by: squidfunk --- Cargo.lock | 2 + crates/mono/Cargo.toml | 2 + crates/mono/src/cli.rs | 12 ++++-- .../mono/src/cli/command/version/changelog.rs | 5 ++- crates/mono/src/cli/config.rs | 42 +++++++++++++++++++ crates/mono/src/cli/error.rs | 3 ++ crates/mono/src/main.rs | 20 +++++++-- 7 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 crates/mono/src/cli/config.rs diff --git a/Cargo.lock b/Cargo.lock index d8b8c77..532e68c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -606,8 +606,10 @@ dependencies = [ "mono-project", "mono-repository", "semver", + "serde", "tempfile", "thiserror", + "toml", ] [[package]] diff --git a/crates/mono/Cargo.toml b/crates/mono/Cargo.toml index e52682d..1f42715 100644 --- a/crates/mono/Cargo.toml +++ b/crates/mono/Cargo.toml @@ -46,5 +46,7 @@ clap.workspace = true cliclack.workspace = true console.workspace = true semver.workspace = true +serde.workspace = true tempfile.workspace = true +toml.workspace = true thiserror.workspace = true diff --git a/crates/mono/src/cli.rs b/crates/mono/src/cli.rs index f598dda..7eaa57c 100644 --- a/crates/mono/src/cli.rs +++ b/crates/mono/src/cli.rs @@ -37,9 +37,11 @@ use mono_repository::Repository; use crate::Context; mod command; +mod config; mod error; pub use command::{Command, Commands}; +pub use config::Config; pub use error::Result; // ---------------------------------------------------------------------------- @@ -78,11 +80,15 @@ pub struct Cli { // ---------------------------------------------------------------------------- impl Cli { - pub fn execute(self, repository: Repository, workspace: Workspace) - where + pub fn execute( + self, repository: Repository, workspace: Workspace, config: Config, + ) where T: Manifest, { - match self.command.execute(Context { repository, workspace }) { + match self + .command + .execute(Context { repository, workspace, config }) + { Ok(()) => process::exit(0), Err(err) => { eprintln!("Error: {err}"); diff --git a/crates/mono/src/cli/command/version/changelog.rs b/crates/mono/src/cli/command/version/changelog.rs index d199118..23fbf86 100644 --- a/crates/mono/src/cli/command/version/changelog.rs +++ b/crates/mono/src/cli/command/version/changelog.rs @@ -64,7 +64,10 @@ where // Resolve versions and create changeset, then determine all commits // that are either part of the given version or yet unreleased let versions = context.repository.versions()?; - let mut changeset = Changeset::new(&context.workspace)?; + let mut changeset = Changeset::with_config( + &context.workspace, + &context.config.changeset, + )?; for res in versions.commits(self.version.as_ref())? { changeset.add(res?)?; } diff --git a/crates/mono/src/cli/config.rs b/crates/mono/src/cli/config.rs new file mode 100644 index 0000000..8caf914 --- /dev/null +++ b/crates/mono/src/cli/config.rs @@ -0,0 +1,42 @@ +// Copyright (c) 2025 Zensical and contributors + +// SPDX-License-Identifier: MIT +// Third-party contributions licensed under DCO + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +// ---------------------------------------------------------------------------- + +//! Configuration. + +use serde::Deserialize; + +use mono_changeset as changeset; + +// ---------------------------------------------------------------------------- +// Structs +// ---------------------------------------------------------------------------- + +/// Configuration. +#[derive(Debug, Default, Deserialize)] +pub struct Config { + /// Changeset. + #[serde(default)] + pub changeset: changeset::Config, +} diff --git a/crates/mono/src/cli/error.rs b/crates/mono/src/cli/error.rs index 3460356..6ca625b 100644 --- a/crates/mono/src/cli/error.rs +++ b/crates/mono/src/cli/error.rs @@ -42,6 +42,9 @@ pub enum Error { /// I/O error. #[error(transparent)] Io(#[from] io::Error), + /// TOML error. + #[error(transparent)] + Toml(#[from] toml::de::Error), /// Version error. #[error(transparent)] Version(#[from] semver::Error), diff --git a/crates/mono/src/main.rs b/crates/mono/src/main.rs index 7313855..93ca20c 100644 --- a/crates/mono/src/main.rs +++ b/crates/mono/src/main.rs @@ -26,13 +26,14 @@ //! Command line interface. use clap::Parser; +use std::fs; use mono_project::{Cargo, Manifest, Node, Workspace}; use mono_repository::Repository; mod cli; -use cli::{Cli, Result}; +use cli::{Cli, Config, Result}; // ---------------------------------------------------------------------------- // Structs @@ -48,6 +49,8 @@ where repository: Repository, /// Workspace. workspace: Workspace, + /// Configuration. + config: Config, } // ---------------------------------------------------------------------------- @@ -59,10 +62,21 @@ fn main() -> Result { let cli = Cli::parse(); let repository = Repository::open(&cli.directory)?; let path = repository.path(); + + // Try to load configuraiton, if any + let config_path = path.join(".mono.toml"); + let config = if config_path.exists() { + let contents = fs::read_to_string(&config_path)?; + toml::from_str(&contents)? + } else { + Config::default() + }; + + // Initialize cargo or node workspace if let Ok(workspace) = Workspace::::resolve(path) { - cli.execute(repository, workspace); + cli.execute(repository, workspace, config); } else if let Ok(workspace) = Workspace::::resolve(path) { - cli.execute(repository, workspace); + cli.execute(repository, workspace, config); } // No errors occurred