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",
|
"log",
|
||||||
"semver",
|
"semver",
|
||||||
"semver-bump-trait",
|
"semver-bump-trait",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"slog",
|
"slog",
|
||||||
"slog-stdlog",
|
"slog-stdlog",
|
||||||
"slog-term",
|
"slog-term",
|
||||||
|
@ -597,6 +599,12 @@ version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -638,6 +646,17 @@ dependencies = [
|
||||||
"syn",
|
"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]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
|
|
@ -12,6 +12,8 @@ glob = "0.3.1"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
semver = "1.0.22"
|
semver = "1.0.22"
|
||||||
semver-bump-trait = "0.1.0"
|
semver-bump-trait = "0.1.0"
|
||||||
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
|
serde_json = "1.0.114"
|
||||||
slog = "2.7.0"
|
slog = "2.7.0"
|
||||||
slog-stdlog = "4.1.1"
|
slog-stdlog = "4.1.1"
|
||||||
slog-term = "2.9.0"
|
slog-term = "2.9.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use slog::{o, Drain, Level};
|
use slog::{error, o, Drain, Level};
|
||||||
|
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ pub enum RootSubcommands {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootCommand {
|
impl RootCommand {
|
||||||
pub async fn run(&self) -> Result<()> {
|
pub async fn run(&self) -> Result<i32> {
|
||||||
// Adjust the verbosity.
|
// Adjust the verbosity.
|
||||||
let log_level = match self.verbose {
|
let log_level = match self.verbose {
|
||||||
0 => Level::Warning,
|
0 => Level::Warning,
|
||||||
|
@ -43,10 +43,16 @@ impl RootCommand {
|
||||||
let _log_guard = slog_stdlog::init().unwrap();
|
let _log_guard = slog_stdlog::init().unwrap();
|
||||||
|
|
||||||
// Pass the command in.
|
// Pass the command in.
|
||||||
match &self.command {
|
let result = match &self.command {
|
||||||
RootSubcommands::Version(cmd) => cmd.run(log).await?,
|
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::trees::get_tree_skip;
|
||||||
use crate::versions::VersionBump;
|
use crate::versions::VersionBump;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use conventional_commit::ConventionalCommit;
|
use conventional_commit::ConventionalCommit;
|
||||||
use git2::{Oid, Repository};
|
use git2::Repository;
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use semver_bump_trait::SemverBump;
|
use semver_bump_trait::SemverBump;
|
||||||
use slog::{debug, info, warn};
|
use slog::{debug, info};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::tags::get_tag_map;
|
use crate::tags::get_tag_map;
|
||||||
|
|
||||||
/// Gets the current version based on commits.
|
/// Gets the current version based on commits.
|
||||||
#[derive(Debug, Parser)]
|
#[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 {
|
impl VersionCommand {
|
||||||
pub async fn run(&self, log: slog::Logger) -> Result<()> {
|
pub async fn run(&self, log: slog::Logger) -> Result<()> {
|
||||||
// Figure out the path we're searching and which one we found.
|
// Figure out the path we're searching and which one we found.
|
||||||
let current_dir =
|
let current_dir = &self.directory.clone();
|
||||||
"/home/dmoonfire/src/mfgames/mfgames-cil/src/MfGames.Nitride";
|
let current_dir = current_dir.as_ref().unwrap();
|
||||||
info!(log, "searching from {:?}", current_dir);
|
info!(log, "searching from {:?}", current_dir);
|
||||||
|
|
||||||
// Load the repository so we can walk through it.
|
// Load the repository so we can walk through it.
|
||||||
let repo = Repository::discover(current_dir)?;
|
let repo = Repository::discover(current_dir)?;
|
||||||
let git_dir = &repo.workdir();
|
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);
|
info!(log, "git root at {:?}", git_dir);
|
||||||
} else {
|
|
||||||
info!(log, "working with a bare repository");
|
// 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.
|
// Load a map of all commits that are pointed to by a tag.
|
||||||
let tag_prefix = "MfGames.Nitride-*";
|
let tag_prefix = package.tag_prefix;
|
||||||
let tag_map: HashMap<Oid, Version> =
|
let tag_map = get_tag_map(&log, &repo, &tag_prefix)?;
|
||||||
get_tag_map(&log, &repo, &tag_prefix)?;
|
|
||||||
|
|
||||||
// Figure out the head.
|
// Figure out the head.
|
||||||
let head = repo.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;
|
use clap::Parser;
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
|
mod config;
|
||||||
mod tags;
|
mod tags;
|
||||||
mod trees;
|
mod trees;
|
||||||
mod versions;
|
mod versions;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use git2::{Commit, DiffOptions, Repository};
|
use git2::{Commit, DiffOptions, Repository};
|
||||||
use slog::{debug, warn, Logger};
|
use slog::{debug, Logger};
|
||||||
|
|
||||||
use crate::versions::VersionBump;
|
use crate::versions::VersionBump;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue