From 53e673164cd45d7a4ece4507a7e8ffd374b58139 Mon Sep 17 00:00:00 2001 From: Kiril Videlov Date: Mon, 30 Mar 2026 18:10:59 -0700 Subject: [PATCH 1/2] refactor: organize imports and extract config helper --- src/commands/import.rs | 3 ++- src/commands/inspect.rs | 3 ++- src/commands/materialize.rs | 3 ++- src/commands/serialize.rs | 3 ++- src/commands/set.rs | 3 ++- src/commands/show.rs | 3 ++- src/commands/stats.rs | 3 ++- src/commands/watch.rs | 7 ++++--- src/db.rs | 3 ++- src/git_utils.rs | 31 ++++++++++++++----------------- 10 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/commands/import.rs b/src/commands/import.rs index 0a35e57..01e70c1 100644 --- a/src/commands/import.rs +++ b/src/commands/import.rs @@ -1,8 +1,9 @@ +use std::collections::HashSet; + use anyhow::{bail, Context, Result}; use chrono::Utc; use git2::Repository; use serde_json::Value; -use std::collections::HashSet; use crate::db::Db; use crate::git_utils; diff --git a/src/commands/inspect.rs b/src/commands/inspect.rs index 4af7447..3d046ce 100644 --- a/src/commands/inspect.rs +++ b/src/commands/inspect.rs @@ -4,9 +4,10 @@ //! - `gmeta inspect `: list all keys for that target type //! - `gmeta inspect `: fuzzy-match keys/targets on term +use std::collections::BTreeMap; + use anyhow::Result; use chrono::{Duration, Utc}; -use std::collections::BTreeMap; use crate::db::Db; use crate::git_utils; diff --git a/src/commands/materialize.rs b/src/commands/materialize.rs index 39a9f1f..7c1197c 100644 --- a/src/commands/materialize.rs +++ b/src/commands/materialize.rs @@ -1,6 +1,7 @@ +use std::collections::{BTreeMap, BTreeSet}; + use anyhow::Result; use chrono::Utc; -use std::collections::{BTreeMap, BTreeSet}; use crate::db::Db; use crate::git_utils; diff --git a/src/commands/serialize.rs b/src/commands/serialize.rs index 1f9c5a3..f24fe19 100644 --- a/src/commands/serialize.rs +++ b/src/commands/serialize.rs @@ -1,6 +1,7 @@ +use std::collections::{BTreeMap, BTreeSet}; + use anyhow::{bail, Context, Result}; use chrono::Utc; -use std::collections::{BTreeMap, BTreeSet}; use crate::commands::auto_prune::{self, parse_since_to_cutoff_ms}; use crate::db::Db; diff --git a/src/commands/set.rs b/src/commands/set.rs index 66906a9..2a5d2d6 100644 --- a/src/commands/set.rs +++ b/src/commands/set.rs @@ -1,6 +1,7 @@ +use std::fs; + use anyhow::{bail, Context, Result}; use chrono::Utc; -use std::fs; use crate::db::Db; use crate::git_utils; diff --git a/src/commands/show.rs b/src/commands/show.rs index dd31c14..c6e000a 100644 --- a/src/commands/show.rs +++ b/src/commands/show.rs @@ -1,9 +1,10 @@ //! `gmeta show ` — display commit details with any associated metadata. +use std::process::Command; + use anyhow::{Context, Result}; use chrono::{TimeZone, Utc}; use git2::Repository; -use std::process::Command; use crate::db::Db; use crate::git_utils; diff --git a/src/commands/stats.rs b/src/commands/stats.rs index c3b941d..0698ceb 100644 --- a/src/commands/stats.rs +++ b/src/commands/stats.rs @@ -1,6 +1,7 @@ -use anyhow::Result; use std::collections::BTreeMap; +use anyhow::Result; + use crate::db::Db; use crate::git_utils; diff --git a/src/commands/watch.rs b/src/commands/watch.rs index c6b01b4..36e799a 100644 --- a/src/commands/watch.rs +++ b/src/commands/watch.rs @@ -1,6 +1,3 @@ -use anyhow::{bail, Context, Result}; -use chrono::Utc; -use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher}; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::io::{BufRead, BufReader, Seek, SeekFrom}; use std::path::{Path, PathBuf}; @@ -8,6 +5,10 @@ use std::process::Command; use std::sync::mpsc; use std::time::{Duration, Instant}; +use anyhow::{bail, Context, Result}; +use chrono::Utc; +use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher}; + use crate::db::Db; use crate::git_utils; diff --git a/src/db.rs b/src/db.rs index 9b56c3c..3acd822 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,7 +1,8 @@ +use std::path::Path; + use anyhow::{bail, Result}; use git2::Repository; use rusqlite::{params, Connection}; -use std::path::Path; use crate::list_value::{encode_entries, ensure_unique_timestamp, parse_entries, ListEntry}; use crate::types::GIT_REF_THRESHOLD; diff --git a/src/git_utils.rs b/src/git_utils.rs index 45f72bf..894e810 100644 --- a/src/git_utils.rs +++ b/src/git_utils.rs @@ -1,8 +1,9 @@ -use anyhow::{bail, Context, Result}; -use git2::Repository; use std::path::{Path, PathBuf}; use std::process::Command; +use anyhow::{bail, Context, Result}; +use git2::Repository; + /// Discover the Git repository from the current directory (git2). pub fn git2_discover_repo() -> Result { let repo = Repository::discover(".") @@ -305,6 +306,14 @@ pub fn resolve_meta_remote(repo: &Repository, remote: Option<&str>) -> Result String { + let config = repo.config_snapshot(); + config + .string(key) + .map(|s| s.to_string()) + .unwrap_or_else(|| default.to_string()) +} + /// Discover the Git repository from the current directory. pub fn discover_repo() -> Result { let repo = @@ -319,30 +328,18 @@ pub fn db_path(repo: &gix::Repository) -> Result { /// Get the user's email from Git config. pub fn get_email(repo: &gix::Repository) -> Result { - let config = repo.config_snapshot(); - Ok(config - .string("user.email") - .map(|s| s.to_string()) - .unwrap_or_else(|| "unknown".to_string())) + Ok(gix_config_string(repo, "user.email", "unknown")) } /// Get the user's name from Git config. #[allow(dead_code)] pub fn get_name(repo: &gix::Repository) -> Result { - let config = repo.config_snapshot(); - Ok(config - .string("user.name") - .map(|s| s.to_string()) - .unwrap_or_else(|| "unknown".to_string())) + Ok(gix_config_string(repo, "user.name", "unknown")) } /// Get the meta namespace from Git config (defaults to "meta"). pub fn get_namespace(repo: &gix::Repository) -> Result { - let config = repo.config_snapshot(); - Ok(config - .string("meta.namespace") - .map(|s| s.to_string()) - .unwrap_or_else(|| "meta".to_string())) + Ok(gix_config_string(repo, "meta.namespace", "meta")) } /// Get the local ref name for serialization. From 7fd54a420255df411b8ba617974786d65ae5a9a3 Mon Sep 17 00:00:00 2001 From: Kiril Videlov Date: Mon, 30 Mar 2026 18:19:21 -0700 Subject: [PATCH 2/2] refactor: simplify error handling with match guards --- src/commands/get.rs | 40 ++++++++++++++++++++-------------------- src/commands/prune.rs | 28 ++++++++++------------------ src/commands/remote.rs | 12 ++++-------- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/src/commands/get.rs b/src/commands/get.rs index 4707b30..d3e5997 100644 --- a/src/commands/get.rs +++ b/src/commands/get.rs @@ -159,16 +159,16 @@ fn hydrate_promised_entries( if let Some(dir_oid) = git_utils::find_blob_oid_in_tree(repo, &tip_tree, &path)? { // dir_oid is a tree — collect all blob entries in it if let Ok(list_tree) = repo.find_tree(dir_oid) { - let mut oids = Vec::new(); - for entry in list_tree.iter() { - let name = entry.name().unwrap_or(""); - if name == types::TOMBSTONE_ROOT || name.starts_with("__") { - continue; - } - if entry.kind() == Some(git2::ObjectType::Blob) { - oids.push(entry.id()); - } - } + let oids: Vec<_> = list_tree + .iter() + .filter(|e| { + let name = e.name().unwrap_or(""); + !name.starts_with("__") + && name != types::TOMBSTONE_ROOT + && e.kind() == Some(git2::ObjectType::Blob) + }) + .map(|e| e.id()) + .collect(); if !oids.is_empty() { pending.push(PendingEntry { idx, @@ -186,16 +186,16 @@ fn hydrate_promised_entries( let set_path = format!("{}/{}", key_path, types::SET_VALUE_DIR); if let Some(dir_oid) = git_utils::find_blob_oid_in_tree(repo, &tip_tree, &set_path)? { if let Ok(set_tree) = repo.find_tree(dir_oid) { - let mut oids = Vec::new(); - for entry in set_tree.iter() { - let name = entry.name().unwrap_or(""); - if name == types::TOMBSTONE_ROOT || name.starts_with("__") { - continue; - } - if entry.kind() == Some(git2::ObjectType::Blob) { - oids.push(entry.id()); - } - } + let oids: Vec<_> = set_tree + .iter() + .filter(|e| { + let name = e.name().unwrap_or(""); + !name.starts_with("__") + && name != types::TOMBSTONE_ROOT + && e.kind() == Some(git2::ObjectType::Blob) + }) + .map(|e| e.id()) + .collect(); if !oids.is_empty() { pending.push(PendingEntry { idx, diff --git a/src/commands/prune.rs b/src/commands/prune.rs index 59953a3..0fe2949 100644 --- a/src/commands/prune.rs +++ b/src/commands/prune.rs @@ -41,24 +41,16 @@ pub fn run(dry_run: bool) -> Result<()> { // Find the current serialized tree let ref_name = git_utils::git2_local_ref(&repo)?; - let current_commit = match repo.find_reference(&ref_name) { - Ok(r) => match r.peel_to_commit() { - Ok(c) => c, - Err(_) => { - eprintln!( - "No serialized metadata found at {}. Run `gmeta serialize` first.", - ref_name - ); - return Ok(()); - } - }, - Err(_) => { - eprintln!( - "No serialized metadata found at {}. Run `gmeta serialize` first.", - ref_name - ); - return Ok(()); - } + let Some(current_commit) = repo + .find_reference(&ref_name) + .ok() + .and_then(|r| r.peel_to_commit().ok()) + else { + eprintln!( + "No serialized metadata found at {}. Run `gmeta serialize` first.", + ref_name + ); + return Ok(()); }; let tree_oid = current_commit.tree()?.id(); diff --git a/src/commands/remote.rs b/src/commands/remote.rs index b97364f..25e6b57 100644 --- a/src/commands/remote.rs +++ b/src/commands/remote.rs @@ -65,11 +65,8 @@ pub fn run_add(url: &str, name: &str, namespace_override: Option<&str>) -> Resul let url = expand_url(url); // Check if this remote name already exists - let existing = repo.remotes()?; - for existing_name in existing.iter().flatten() { - if existing_name == name { - bail!("remote '{}' already exists", name); - } + if repo.remotes()?.iter().flatten().any(|n| n == name) { + bail!("remote '{}' already exists", name); } // Check the remote for meta refs before configuring @@ -210,9 +207,8 @@ pub fn run_remove(name: &str) -> Result<()> { // Verify this is a meta remote let config = repo.config()?; let meta_key = format!("remote.{}.meta", name); - match config.get_bool(&meta_key) { - Ok(true) => {} - _ => bail!("'{}' is not a metadata remote (no meta = true)", name), + if !matches!(config.get_bool(&meta_key), Ok(true)) { + bail!("'{}' is not a metadata remote (no meta = true)", name); } // Remove the git config section for this remote