style: 格式化代码并优化导入顺序
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{Result, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -80,25 +80,25 @@ impl GitProfile {
|
||||
if self.user_name.is_empty() {
|
||||
bail!("User name cannot be empty");
|
||||
}
|
||||
|
||||
|
||||
if self.user_email.is_empty() {
|
||||
bail!("User email cannot be empty");
|
||||
}
|
||||
|
||||
|
||||
crate::utils::validators::validate_email(&self.user_email)?;
|
||||
|
||||
|
||||
if let Some(ref ssh) = self.ssh {
|
||||
ssh.validate()?;
|
||||
}
|
||||
|
||||
|
||||
if let Some(ref gpg) = self.gpg {
|
||||
gpg.validate()?;
|
||||
}
|
||||
|
||||
|
||||
for token in self.tokens.values() {
|
||||
token.validate()?;
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -119,7 +119,8 @@ impl GitProfile {
|
||||
|
||||
/// Get signing key (from GPG config or direct)
|
||||
pub fn signing_key(&self) -> Option<&str> {
|
||||
self.signing_key.as_deref()
|
||||
self.signing_key
|
||||
.as_deref()
|
||||
.or_else(|| self.gpg.as_ref().map(|g| g.key_id.as_str()))
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ impl GitProfile {
|
||||
pub fn record_usage(&mut self, repo_path: Option<String>) {
|
||||
self.usage.last_used = Some(chrono::Utc::now().to_rfc3339());
|
||||
self.usage.total_uses += 1;
|
||||
|
||||
|
||||
if let Some(repo) = repo_path {
|
||||
let count = self.usage.repo_usage.entry(repo).or_insert(0);
|
||||
*count += 1;
|
||||
@@ -157,91 +158,95 @@ impl GitProfile {
|
||||
/// Apply this profile to a git repository (local config)
|
||||
pub fn apply_to_repo(&self, repo: &git2::Repository) -> Result<()> {
|
||||
let mut config = repo.config()?;
|
||||
|
||||
|
||||
config.set_str("user.name", &self.user_name)?;
|
||||
config.set_str("user.email", &self.user_email)?;
|
||||
|
||||
|
||||
if let Some(key) = self.signing_key() {
|
||||
config.set_str("user.signingkey", key)?;
|
||||
|
||||
|
||||
if self.settings.auto_sign_commits {
|
||||
config.set_bool("commit.gpgsign", true)?;
|
||||
}
|
||||
|
||||
|
||||
if self.settings.auto_sign_tags {
|
||||
config.set_bool("tag.gpgsign", true)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if let Some(ref ssh) = self.ssh
|
||||
&& let Some(ref key_path) = ssh.private_key_path {
|
||||
let path_str = key_path.display().to_string();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
config.set_str("core.sshCommand",
|
||||
&format!("ssh -i \"{}\"", path_str.replace('\\', "/")))?;
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
config.set_str("core.sshCommand",
|
||||
&format!("ssh -i '{}'", path_str))?;
|
||||
}
|
||||
&& let Some(ref key_path) = ssh.private_key_path
|
||||
{
|
||||
let path_str = key_path.display().to_string();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
config.set_str(
|
||||
"core.sshCommand",
|
||||
&format!("ssh -i \"{}\"", path_str.replace('\\', "/")),
|
||||
)?;
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
config.set_str("core.sshCommand", &format!("ssh -i '{}'", path_str))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Apply this profile globally
|
||||
pub fn apply_global(&self) -> Result<()> {
|
||||
let mut config = git2::Config::open_default()?;
|
||||
|
||||
|
||||
config.set_str("user.name", &self.user_name)?;
|
||||
config.set_str("user.email", &self.user_email)?;
|
||||
|
||||
|
||||
if let Some(key) = self.signing_key() {
|
||||
config.set_str("user.signingkey", key)?;
|
||||
|
||||
|
||||
if self.settings.auto_sign_commits {
|
||||
config.set_bool("commit.gpgsign", true)?;
|
||||
}
|
||||
|
||||
|
||||
if self.settings.auto_sign_tags {
|
||||
config.set_bool("tag.gpgsign", true)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if let Some(ref ssh) = self.ssh
|
||||
&& let Some(ref key_path) = ssh.private_key_path {
|
||||
let path_str = key_path.display().to_string();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
config.set_str("core.sshCommand",
|
||||
&format!("ssh -i \"{}\"", path_str.replace('\\', "/")))?;
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
config.set_str("core.sshCommand",
|
||||
&format!("ssh -i '{}'", path_str))?;
|
||||
}
|
||||
&& let Some(ref key_path) = ssh.private_key_path
|
||||
{
|
||||
let path_str = key_path.display().to_string();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
config.set_str(
|
||||
"core.sshCommand",
|
||||
&format!("ssh -i \"{}\"", path_str.replace('\\', "/")),
|
||||
)?;
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
config.set_str("core.sshCommand", &format!("ssh -i '{}'", path_str))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compare with current git configuration
|
||||
pub fn compare_with_git_config(&self, repo: &git2::Repository) -> Result<ProfileComparison> {
|
||||
let config = repo.config()?;
|
||||
|
||||
|
||||
let git_user_name = config.get_string("user.name").ok();
|
||||
let git_user_email = config.get_string("user.email").ok();
|
||||
let git_signing_key = config.get_string("user.signingkey").ok();
|
||||
|
||||
|
||||
let mut comparison = ProfileComparison {
|
||||
profile_name: self.name.clone(),
|
||||
matches: true,
|
||||
differences: vec![],
|
||||
};
|
||||
|
||||
|
||||
if git_user_name.as_deref() != Some(&self.user_name) {
|
||||
comparison.matches = false;
|
||||
comparison.differences.push(ConfigDifference {
|
||||
@@ -250,7 +255,7 @@ impl GitProfile {
|
||||
git_value: git_user_name.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if git_user_email.as_deref() != Some(&self.user_email) {
|
||||
comparison.matches = false;
|
||||
comparison.differences.push(ConfigDifference {
|
||||
@@ -259,24 +264,24 @@ impl GitProfile {
|
||||
git_value: git_user_email.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if let Some(profile_key) = self.signing_key()
|
||||
&& git_signing_key.as_deref() != Some(profile_key) {
|
||||
comparison.matches = false;
|
||||
comparison.differences.push(ConfigDifference {
|
||||
key: "user.signingkey".to_string(),
|
||||
profile_value: profile_key.to_string(),
|
||||
git_value: git_signing_key.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
&& git_signing_key.as_deref() != Some(profile_key)
|
||||
{
|
||||
comparison.matches = false;
|
||||
comparison.differences.push(ConfigDifference {
|
||||
key: "user.signingkey".to_string(),
|
||||
profile_value: profile_key.to_string(),
|
||||
git_value: git_signing_key.unwrap_or_else(|| "<not set>".to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(comparison)
|
||||
}
|
||||
}
|
||||
|
||||
/// Profile settings
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Default)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct ProfileSettings {
|
||||
/// Automatically sign commits
|
||||
#[serde(default)]
|
||||
@@ -303,7 +308,6 @@ pub struct ProfileSettings {
|
||||
pub commit_template: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
/// SSH configuration
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SshConfig {
|
||||
@@ -334,15 +338,17 @@ impl SshConfig {
|
||||
/// Validate SSH configuration
|
||||
pub fn validate(&self) -> Result<()> {
|
||||
if let Some(ref path) = self.private_key_path
|
||||
&& !path.exists() {
|
||||
bail!("SSH private key does not exist: {:?}", path);
|
||||
}
|
||||
|
||||
&& !path.exists()
|
||||
{
|
||||
bail!("SSH private key does not exist: {:?}", path);
|
||||
}
|
||||
|
||||
if let Some(ref path) = self.public_key_path
|
||||
&& !path.exists() {
|
||||
bail!("SSH public key does not exist: {:?}", path);
|
||||
}
|
||||
|
||||
&& !path.exists()
|
||||
{
|
||||
bail!("SSH public key does not exist: {:?}", path);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -487,7 +493,6 @@ pub enum TokenType {
|
||||
App,
|
||||
}
|
||||
|
||||
|
||||
impl std::fmt::Display for TokenType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@@ -617,9 +622,15 @@ impl GitProfileBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<GitProfile> {
|
||||
let name = self.name.ok_or_else(|| anyhow::anyhow!("Name is required"))?;
|
||||
let user_name = self.user_name.ok_or_else(|| anyhow::anyhow!("User name is required"))?;
|
||||
let user_email = self.user_email.ok_or_else(|| anyhow::anyhow!("User email is required"))?;
|
||||
let name = self
|
||||
.name
|
||||
.ok_or_else(|| anyhow::anyhow!("Name is required"))?;
|
||||
let user_name = self
|
||||
.user_name
|
||||
.ok_or_else(|| anyhow::anyhow!("User name is required"))?;
|
||||
let user_email = self
|
||||
.user_email
|
||||
.ok_or_else(|| anyhow::anyhow!("User email is required"))?;
|
||||
|
||||
Ok(GitProfile {
|
||||
name,
|
||||
@@ -665,7 +676,7 @@ mod tests {
|
||||
"".to_string(),
|
||||
"invalid-email".to_string(),
|
||||
);
|
||||
|
||||
|
||||
assert!(profile.validate().is_err());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user