feat: implemented a basic configuration file
This commit is contained in:
parent
0931c0daac
commit
f1571d2f93
7 changed files with 139 additions and 20 deletions
19
Cargo.lock
generated
19
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
73
src/config.rs
Normal 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)
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ use anyhow::Result;
|
|||
use clap::Parser;
|
||||
|
||||
mod commands;
|
||||
mod config;
|
||||
mod tags;
|
||||
mod trees;
|
||||
mod versions;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue