Skip to content

Commit

Permalink
feat: working on new clone functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
matzxrr committed Feb 1, 2024
1 parent 539cc64 commit f486744
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 11 deletions.
20 changes: 13 additions & 7 deletions dotme-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

mod dotme_panic;

use std::path::PathBuf;

use clap::{Parser, Subcommand};
use dotme_core::cmd::init;
use dotme_core::cmd;

#[derive(Debug, Parser)]
#[command(name = "dotme")]
Expand All @@ -20,8 +22,11 @@ struct Cli {
enum Commands {
#[command(about = "Setup a new dotfile repo")]
Init,
#[command(about = "Clone and install your dotfiles")]
Clone,
#[command(
about = "Clone and install your dotfiles",
arg_required_else_help = true
)]
Clone { remote: PathBuf },
#[command(about = "Configure your existing repo")]
Config,
#[command(about = "Uninstall your dotfiles and restore previous files")]
Expand All @@ -33,14 +38,15 @@ fn main() {
let args = Cli::parse();
match args.command {
Commands::Init => {
match init::init() {
match cmd::init() {
Ok(()) => println!("Init Complete!"),
Err(err) => println!("{}", err),
};
}
Commands::Clone => {
todo!()
}
Commands::Clone { remote } => match cmd::clone(&remote) {
Ok(()) => println!("Clone Complete!"),
Err(err) => println!("{}", err),
},
Commands::Config => {
todo!()
}
Expand Down
56 changes: 56 additions & 0 deletions dotme-core/src/cmd/clone.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::path::{Path, PathBuf};

use anyhow::Result;
use dialoguer::{theme::ColorfulTheme, Input, Password};
use git2::Cred;

use crate::{
path_utils::{is_ssh_path, parse_into_absolute},
repo::Repo,
};

pub fn clone(remote: &Path) -> Result<()> {
println!("\n\nCloning a repository");

let default_path = String::from("$HOME/.cfg");

let repo_location: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Repo location")
.default(default_path)
.validate_with(|input: &String| {
let path = PathBuf::from(input);
if path.is_dir() {
Err("Directory already exists")
} else {
Ok(())
}
})
.interact_text()?;

let repo_path = PathBuf::from(repo_location);
let absolute_repo_path = parse_into_absolute(&repo_path);
let is_remote_ssh = is_ssh_path(remote);

let cred;
if is_remote_ssh {
let default_ssh_key = String::from("~/.ssh/id_rsa");
let ssh_key = Input::with_theme(&ColorfulTheme::default())
.with_prompt("SSH Key")
.default(default_ssh_key)
.interact_text()?;
let ssh_password = Password::with_theme(&ColorfulTheme::default())
.with_prompt("SSH Password")
.interact();
cred = Cred::ssh_key(
username_from_url.unwrap(),
None,
Path::new(&format!("{}/.ssh/id_rsa", env::var("HOME").unwrap())),
None,
)?;
}

// let _result = Repo::clone(remote, &absolute_repo_path)?;
// println!("Found {}", remote);

Ok(())
}
6 changes: 5 additions & 1 deletion dotme-core/src/cmd/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
pub mod init;
mod clone;
mod init;

pub use clone::clone;
pub use init::init;
5 changes: 4 additions & 1 deletion dotme-core/src/path_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ pub fn base_dirs() -> Result<BaseDirs> {
BaseDirs::new().ok_or(anyhow!("Cannot get base directories",))
}

/// This function does a thing
pub fn parse_into_absolute(path: &Path) -> PathBuf {
path.strip_prefix("$HOME")
.ok()
Expand All @@ -21,3 +20,7 @@ pub fn parse_into_absolute(path: &Path) -> PathBuf {
})
.unwrap_or(path.to_path_buf())
}

pub fn is_ssh_path(path: &Path) -> bool {
!path.starts_with("http")
}
26 changes: 24 additions & 2 deletions dotme-core/src/repo.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::path::Path;
use std::{env, path::Path};

use crate::path_utils::{self};
use anyhow::{anyhow, Result};
use git2::{ErrorCode, Repository};
use git2::{Cred, ErrorCode, FetchOptions, RemoteCallbacks, Repository};

/// A struct that wraps `crate::config::Config` and `git2::Repository`
/// making it easy to load the dotme repo.
Expand Down Expand Up @@ -63,6 +63,28 @@ impl Repo {
config.set_str("status.showuntrackedfiles", "no")?;
Ok(())
}

pub fn clone(url: &str, destination: &Path) -> Result<Repo> {
let mut callbacks = RemoteCallbacks::new();
callbacks.credentials(|_url, username_from_url, _allowed_types| {
Cred::ssh_key(
username_from_url.unwrap(),
None,
Path::new(&format!("{}/.ssh/id_rsa", env::var("HOME").unwrap())),
None,
)
});

let mut fo = FetchOptions::new();
fo.remote_callbacks(callbacks);

let mut builder = git2::build::RepoBuilder::new();
builder.bare(true);
builder.fetch_options(fo);

let repo = builder.clone(url, destination)?;
Ok(Repo { repo })
}
}

#[cfg(test)]
Expand Down

0 comments on commit f486744

Please sign in to comment.