Compare commits

..

1 Commits

Author SHA1 Message Date
cuddle-please
c725af45db chore(release): 0.2.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2024-09-22 13:12:41 +00:00
5 changed files with 5 additions and 141 deletions

View File

@ -9,7 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.2.1] - 2024-09-22 ## [0.2.1] - 2024-09-22
### Added ### Added
- implement git clone
- include vhs demo - include vhs demo
- add interactive search - add interactive search
- implement naive fuzzy matcher - implement naive fuzzy matcher

View File

@ -4,7 +4,6 @@ use crate::{
app::App, app::App,
cache::CacheApp, cache::CacheApp,
fuzzy_matcher::{FuzzyMatcher, FuzzyMatcherApp}, fuzzy_matcher::{FuzzyMatcher, FuzzyMatcherApp},
git_clone::GitCloneApp,
git_provider::Repository, git_provider::Repository,
interactive::InteractiveApp, interactive::InteractiveApp,
projects_list::ProjectsListApp, projects_list::ProjectsListApp,
@ -24,7 +23,6 @@ impl RootCommand {
&mut self, &mut self,
search: Option<impl Into<String>>, search: Option<impl Into<String>>,
cache: bool, cache: bool,
clone: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
tracing::debug!("executing"); tracing::debug!("executing");
@ -43,8 +41,7 @@ impl RootCommand {
} else { } else {
self.app.projects_list().get_projects().await? self.app.projects_list().get_projects().await?
}; };
match search {
let repo = match search {
Some(needle) => { Some(needle) => {
let matched_repos = self let matched_repos = self
.app .app
@ -54,9 +51,7 @@ impl RootCommand {
let repo = matched_repos let repo = matched_repos
.first() .first()
.ok_or(anyhow::anyhow!("failed to find repository"))?; .ok_or(anyhow::anyhow!("failed to find repository"))?;
tracing::debug!("selected repo: {}", repo.to_rel_path().display()); tracing::info!("selected repo: {}", repo.to_rel_path().display());
repo.to_owned()
} }
None => { None => {
let repo = self let repo = self
@ -65,14 +60,8 @@ impl RootCommand {
.interactive_search(&repositories)? .interactive_search(&repositories)?
.ok_or(anyhow::anyhow!("failed to find a repository"))?; .ok_or(anyhow::anyhow!("failed to find a repository"))?;
tracing::debug!("selected repo: {}", repo.to_rel_path().display()); tracing::info!("selected repo: {}", repo.to_rel_path().display());
repo
} }
};
if clone {
self.app.git_clone().clone_repo(&repo).await?;
} }
Ok(()) Ok(())

View File

@ -14,49 +14,10 @@ pub struct Config {
#[derive(Debug, Default, Serialize, Deserialize, PartialEq)] #[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct Settings { pub struct Settings {
#[serde(default)]
pub projects: Projects,
#[serde(default)] #[serde(default)]
pub cache: Cache, pub cache: Cache,
} }
#[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct Projects {
pub directory: ProjectLocation,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ProjectLocation(PathBuf);
impl From<PathBuf> for ProjectLocation {
fn from(value: PathBuf) -> Self {
Self(value)
}
}
impl From<ProjectLocation> for PathBuf {
fn from(value: ProjectLocation) -> Self {
value.0
}
}
impl Default for ProjectLocation {
fn default() -> Self {
let home = dirs::home_dir().unwrap_or_default();
Self(home.join("git"))
}
}
impl std::ops::Deref for ProjectLocation {
type Target = PathBuf;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Debug, Default, Serialize, Deserialize, PartialEq)] #[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct Cache { pub struct Cache {
#[serde(default)] #[serde(default)]
@ -270,9 +231,6 @@ mod test {
#[test] #[test]
fn test_can_parse_config() -> anyhow::Result<()> { fn test_can_parse_config() -> anyhow::Result<()> {
let content = r#" let content = r#"
[settings]
projects = { directory = "git" }
[settings.cache] [settings.cache]
location = ".cache/gitnow" location = ".cache/gitnow"
duration = { days = 2 } duration = { days = 2 }
@ -358,9 +316,6 @@ mod test {
hours: 0, hours: 0,
minutes: 0 minutes: 0
} }
},
projects: Projects {
directory: PathBuf::from("git").into()
} }
} }
}, },
@ -385,8 +340,7 @@ mod test {
gitea: vec![] gitea: vec![]
}, },
settings: Settings { settings: Settings {
cache: Cache::default(), cache: Cache::default()
projects: Projects::default()
} }
}, },
config config

View File

@ -1,74 +0,0 @@
use crate::{app::App, git_provider::Repository};
pub struct GitClone {
app: &'static App,
}
impl GitClone {
pub fn new(app: &'static App) -> Self {
Self { app }
}
pub async fn clone_repo(&self, repository: &Repository) -> anyhow::Result<()> {
let project_path = self
.app
.config
.settings
.projects
.directory
.join(repository.to_rel_path());
if project_path.exists() {
tracing::info!(
"project: {} already exists, skipping clone",
repository.to_rel_path().display()
);
return Ok(());
}
tracing::info!(
"cloning: {} into {}",
repository.ssh_url.as_str(),
&project_path.display().to_string(),
);
let mut cmd = tokio::process::Command::new("git");
cmd.args([
"clone",
repository.ssh_url.as_str(),
&project_path.display().to_string(),
]);
let output = cmd.output().await?;
match output.status.success() {
true => tracing::debug!(
"cloned {} into {}",
repository.ssh_url.as_str(),
&project_path.display().to_string(),
),
false => {
let stdout = std::str::from_utf8(&output.stdout).unwrap_or_default();
let stderr = std::str::from_utf8(&output.stderr).unwrap_or_default();
tracing::error!(
"failed to clone {} into {}, with output: {}, err: {}",
repository.ssh_url.as_str(),
&project_path.display().to_string(),
stdout,
stderr
)
}
}
Ok(())
}
}
pub trait GitCloneApp {
fn git_clone(&self) -> GitClone;
}
impl GitCloneApp for &'static App {
fn git_clone(&self) -> GitClone {
GitClone::new(self)
}
}

View File

@ -13,7 +13,6 @@ mod cache_codec;
mod commands; mod commands;
mod config; mod config;
mod fuzzy_matcher; mod fuzzy_matcher;
mod git_clone;
mod git_provider; mod git_provider;
mod interactive; mod interactive;
mod projects_list; mod projects_list;
@ -29,9 +28,6 @@ struct Command {
#[arg(long = "no-cache", default_value = "false")] #[arg(long = "no-cache", default_value = "false")]
no_cache: bool, no_cache: bool,
#[arg(long = "no-clone", default_value = "false")]
no_clone: bool,
} }
#[derive(Subcommand)] #[derive(Subcommand)]
@ -64,7 +60,7 @@ async fn main() -> anyhow::Result<()> {
Some(_) => todo!(), Some(_) => todo!(),
None => { None => {
RootCommand::new(app) RootCommand::new(app)
.execute(cli.search.as_ref(), !cli.no_cache, !cli.no_clone) .execute(cli.search.as_ref(), !cli.no_cache)
.await?; .await?;
} }
} }