Skip to content

Commit

Permalink
feat: support apply user config
Browse files Browse the repository at this point in the history
  • Loading branch information
luhc228 committed Jun 15, 2024
1 parent 493c658 commit e50e6f7
Show file tree
Hide file tree
Showing 8 changed files with 549 additions and 33 deletions.
487 changes: 487 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ clap = { version = "4.5.4", features = ["derive"] }
console = "0.15.8"
dialoguer = "0.11.0"
dirs = "5.0.1"
git2 = { version = "0.19.0", features = [] }
regex = "1.10.5"
rust-ini = "0.21.0"
serde = {version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
7 changes: 1 addition & 6 deletions src/process/clone_repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ fn get_repo_local_path(git_url: &GitUrl, global_config: &GlobalConfig) -> Result
}

fn call_git_clone_command(url: &str, repo_path: &Path) -> Result<()> {
run_piped_command(vec![
"git".to_string(),
"clone".to_string(),
url.to_string(),
repo_path.to_string_lossy().to_string(),
])?;
run_piped_command(vec!["git", "clone", url, repo_path.to_str().unwrap()])?;
Ok(())
}
8 changes: 1 addition & 7 deletions src/process/git_user_config/add.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{GitUserConfig, GlobalConfig};
use anyhow::{Ok, Result};
use console::style;
use dialoguer::Input;
use regex::Regex;

Expand Down Expand Up @@ -46,12 +45,7 @@ pub fn add() -> Result<()> {

GitUserConfig::new(&config_id, &name, &email).add()?;

println!(
"Git user config {}({}<{}>) added successfully!",
style(&config_id).bold(),
style(&name).bold(),
style(&email).bold()
);
println!("Git user config added successfully!",);

Ok(())
}
27 changes: 24 additions & 3 deletions src/process/git_user_config/apply.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
use anyhow::Result;
use crate::{run_piped_command, GitUserConfig};
use anyhow::{Ok, Result};
use git2::Repository;
use std::{env, path::Path};

/// apply git config to current directory
pub fn apply(_config_id: String) -> Result<()> {
Ok(())
pub fn apply(config_id: String) -> Result<()> {
// check if it is a git repository
if !is_git_repo(env::current_dir()?) {
return Err(anyhow::anyhow!("The current directory is not a git repository"));
}

let git_user_configs = GitUserConfig::get_all()?;
let git_user_config = git_user_configs.iter().find(|c| c.config_id == config_id);
match git_user_config {
Some(git_user_config) => {
run_piped_command(vec!["git", "config", "user.name", git_user_config.name.as_str()])?;
run_piped_command(vec!["git", "config", "user.email", git_user_config.email.as_str()])?;
Ok(())
}
None => Err(anyhow::anyhow!("Config id: {} is not found", config_id)),
}
}

fn is_git_repo<P: AsRef<Path>>(path: P) -> bool {
Repository::open(path).is_ok()
}
9 changes: 8 additions & 1 deletion src/utils/get_git_user_config_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@ pub fn get_git_user_config_id(raw_config_id: Option<String>) -> anyhow::Result<S
})
.collect::<Vec<String>>();

if items.is_empty() {
return Err(anyhow::anyhow!(
"No git user config found. Please add one by running `gitez user-config add`"
));
}

let selection = Select::new()
.with_prompt("Chose the user config you want to remove")
.with_prompt("choose the user config you want to remove")
.items(&items)
.default(0)
.interact()?;
let selected_config_id = &git_user_configs[selection].config_id;

Expand Down
34 changes: 22 additions & 12 deletions src/utils/global_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::path::PathBuf;

use crate::GitUserConfig;

const CONFIG_NAME: &str = ".gitez.json";
pub const DIR: &str = ".gitez";
const CONFIG_FILENAME: &str = "config.json";

#[derive(Debug, Serialize, Deserialize)]
pub struct GlobalConfig {
Expand All @@ -16,34 +17,43 @@ pub struct GlobalConfig {
impl GlobalConfig {
pub fn init() -> Result<()> {
let config_path = GlobalConfig::config_path();
Self::init_dir()?;
if !config_path.exists() {
fs::write(config_path, "{ git_user_configs: [] }")
.map_err(|err| anyhow::anyhow!("Unable to create {}. Reason: {}", CONFIG_NAME, err))?;
fs::write(&config_path, "{ \"git_user_configs\": [] }")
.map_err(|err| anyhow::anyhow!("Unable to create {}. Reason: {}", config_path.display(), err))?;
}
Ok(())
}
fn init_dir() -> Result<()> {
let config_path = GlobalConfig::config_path();
let dir = config_path.parent().unwrap();
if !dir.exists() {
fs::create_dir(dir).map_err(|err| anyhow::anyhow!("Unable to create {}. Reason: {}", dir.display(), err))?;
}
Ok(())
}
pub fn config_path() -> PathBuf {
match dirs::home_dir() {
// The path is ~/.gitez.json
Some(home_dir) => home_dir.join(CONFIG_NAME),
None => PathBuf::from(CONFIG_NAME),
// The path is ~/.gitez/config.json
Some(home_dir) => home_dir.join(DIR).join(CONFIG_FILENAME),
None => PathBuf::from(DIR).join(CONFIG_FILENAME),
}
}
pub fn new() -> Result<Self> {
let config_path = GlobalConfig::config_path();
let config_str = fs::read_to_string(config_path)
.map_err(|err| anyhow::anyhow!("Unable to create {}. Reason: {}", CONFIG_NAME, err))?;
let config_str = fs::read_to_string(&config_path)
.map_err(|err| anyhow::anyhow!("Unable to create {}. Reason: {}", config_path.display(), err))?;
let config = serde_json::from_str::<GlobalConfig>(&config_str)
.map_err(|err| anyhow::anyhow!("Unable to parse {}. Reason: {}", CONFIG_NAME, err))?;
.map_err(|err| anyhow::anyhow!("Unable to parse {}. Reason: {}", config_path.display(), err))?;
Ok(config)
}

pub fn save(&self) -> Result<()> {
let config_path = GlobalConfig::config_path();
let config_str = serde_json::to_string_pretty(&self)
.map_err(|err| anyhow::anyhow!("Unable to serialize {}. Reason: {}", CONFIG_NAME, err))?;
fs::write(config_path, config_str)
.map_err(|err| anyhow::anyhow!("Unable to write {}. Reason: {}", CONFIG_NAME, err))?;
.map_err(|err| anyhow::anyhow!("Unable to serialize {}. Reason: {}", config_path.display(), err))?;
fs::write(&config_path, config_str)
.map_err(|err| anyhow::anyhow!("Unable to write {}. Reason: {}", config_path.display(), err))?;
Ok(())
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/utils/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ fn get_shell_name() -> String {
}
}

fn get_shell_args(args: Vec<String>) -> Vec<String> {
fn get_shell_args(args: Vec<&str>) -> Vec<String> {
// windows
if cfg!(windows) {
vec!["/c".to_string(), args.join(" ")]
["/c", &args.join(" ")].iter().map(|s| s.to_string()).collect()
} else {
// linux / macOS
vec!["-c".to_string(), args.join(" ")]
["-c", &args.join(" ")].iter().map(|s| s.to_string()).collect()
}
}

pub fn run_piped_command(args: Vec<String>) -> Result<()> {
pub fn run_piped_command(args: Vec<&str>) -> Result<()> {
let shell_name = get_shell_name();
let shell_args = get_shell_args(args);

Expand Down

0 comments on commit e50e6f7

Please sign in to comment.