feat: implemented a basic configuration file

This commit is contained in:
D. Moonfire 2024-03-09 15:57:10 -06:00
parent 0931c0daac
commit f1571d2f93
7 changed files with 139 additions and 20 deletions

19
Cargo.lock generated
View file

@ -425,6 +425,8 @@ dependencies = [
"log",
"semver",
"semver-bump-trait",
"serde",
"serde_json",
"slog",
"slog-stdlog",
"slog-term",
@ -597,6 +599,12 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -638,6 +646,17 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"

View file

@ -12,6 +12,8 @@ glob = "0.3.1"
log = "0.4.20"
semver = "1.0.22"
semver-bump-trait = "0.1.0"
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
slog = "2.7.0"
slog-stdlog = "4.1.1"
slog-term = "2.9.0"

View file

@ -1,6 +1,6 @@
use anyhow::Result;
use clap::{Parser, Subcommand};
use slog::{o, Drain, Level};
use slog::{error, o, Drain, Level};
mod version;
@ -24,7 +24,7 @@ pub enum RootSubcommands {
}
impl RootCommand {
pub async fn run(&self) -> Result<()> {
pub async fn run(&self) -> Result<i32> {
// Adjust the verbosity.
let log_level = match self.verbose {
0 => Level::Warning,
@ -43,10 +43,16 @@ impl RootCommand {
let _log_guard = slog_stdlog::init().unwrap();
// Pass the command in.
match &self.command {
RootSubcommands::Version(cmd) => cmd.run(log).await?,
let result = match &self.command {
RootSubcommands::Version(cmd) => cmd.run(log.clone()).await,
};
Ok(())
match result {
Ok(_) => Ok(0),
Err(err) => {
error!(log, "{}", err);
Err(err)
}
}
}
}

View file

@ -1,43 +1,61 @@
use crate::config::Config;
use crate::trees::get_tree_skip;
use crate::versions::VersionBump;
use anyhow::Result;
use clap::Parser;
use conventional_commit::ConventionalCommit;
use git2::{Oid, Repository};
use git2::Repository;
use semver::Version;
use semver_bump_trait::SemverBump;
use slog::{debug, info, warn};
use slog::{debug, info};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::str::FromStr;
use crate::tags::get_tag_map;
/// Gets the current version based on commits.
#[derive(Debug, Parser)]
pub struct VersionCommand {}
pub struct VersionCommand {
/// The directory to perform the search.
#[clap(short, long)]
directory: Option<String>,
/// The name of the package to use.
#[clap(short, long)]
package: Option<String>,
}
impl VersionCommand {
pub async fn run(&self, log: slog::Logger) -> Result<()> {
// Figure out the path we're searching and which one we found.
let current_dir =
"/home/dmoonfire/src/mfgames/mfgames-cil/src/MfGames.Nitride";
let current_dir = &self.directory.clone();
let current_dir = current_dir.as_ref().unwrap();
info!(log, "searching from {:?}", current_dir);
// Load the repository so we can walk through it.
let repo = Repository::discover(current_dir)?;
let git_dir = &repo.workdir();
let git_dir = git_dir.unwrap();
if let Some(git_dir) = git_dir {
info!(log, "git root at {:?}", git_dir);
} else {
info!(log, "working with a bare repository");
}
info!(log, "git root at {:?}", git_dir);
// Load the configuration file.
let config_file = Config::get_git_config_file(git_dir);
info!(log, "config at {:?}", config_file);
let config = Config::load(&config_file)?;
debug!(log, "config {:?}", config);
// Get the settings.
let package_name = &self.package.clone();
let package_name = package_name.as_ref().unwrap();
let package = config.get_package(package_name)?;
// Load a map of all commits that are pointed to by a tag.
let tag_prefix = "MfGames.Nitride-*";
let tag_map: HashMap<Oid, Version> =
get_tag_map(&log, &repo, &tag_prefix)?;
let tag_prefix = package.tag_prefix;
let tag_map = get_tag_map(&log, &repo, &tag_prefix)?;
// Figure out the head.
let head = repo.head()?;

73
src/config.rs Normal file
View file

@ -0,0 +1,73 @@
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use serde_json;
use std::{
collections::BTreeMap,
fs::File,
io::Read,
path::{Path, PathBuf},
};
/// The top-level configuration for settings. This will typically be stored
/// at the repository root at `./.config/mfgames-conventional-commit.json`.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "$schema")]
pub enum Config {
#[serde(
rename = "https://mfgames.com/mfgames-conventional-commit/schemas/v0.0.json"
)]
Config0(Config0),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Config0 {
/// Settings for specific projects.
pub packages: BTreeMap<String, PackageSettings>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PackageSettings {
/// The prefix of the Git tag to search for.
pub tag_prefix: String,
}
impl Config {
pub fn get_git_config_file(git_dir: &Path) -> PathBuf {
let mut path = PathBuf::from(git_dir);
path.push(".config");
path.push("mfgames-conventional-commit.json");
path
}
pub fn load(path: &PathBuf) -> Result<Config> {
let mut file = File::open(path)?;
let mut data = String::new();
file.read_to_string(&mut data)?;
let config: Config = serde_json::from_str(&data)
.with_context(|| format!("cannot read config from {:?}", &path))?;
Ok(config)
}
pub fn get_package(
&self,
package_name: impl Into<String>,
) -> Result<PackageSettings> {
let package_name = package_name.into();
let Config::Config0(config) = &self;
let config = config.clone();
let packages = config.packages;
let package = packages
.get(&package_name)
.context(format!("cannot find package {}", package_name))?;
let package = package.clone();
Ok(package)
}
}

View file

@ -6,6 +6,7 @@ use anyhow::Result;
use clap::Parser;
mod commands;
mod config;
mod tags;
mod trees;
mod versions;

View file

@ -1,6 +1,6 @@
use anyhow::Result;
use git2::{Commit, DiffOptions, Repository};
use slog::{debug, warn, Logger};
use slog::{debug, Logger};
use crate::versions::VersionBump;