Compare commits
1 Commits
main
...
6eb61d70b9
| Author | SHA1 | Date | |
|---|---|---|---|
| 6eb61d70b9 |
28
CHANGELOG.md
28
CHANGELOG.md
@@ -6,34 +6,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [0.3.5] - 2025-03-04
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- allow clone all
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- *(deps)* update rust crate serde to v1.0.218
|
|
||||||
- *(deps)* update tokio-prost monorepo to v0.13.5
|
|
||||||
- *(deps)* update rust crate termwiz to 0.23.0
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update rust crate uuid to v1.13.0
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update rust crate async-trait to v0.1.86
|
|
||||||
- *(deps)* update rust crate uuid to v1.12.1
|
|
||||||
- *(deps)* update rust crate octocrab to 0.43.0
|
|
||||||
- *(deps)* update rust crate uuid to v1.12.0
|
|
||||||
- *(deps)* update rust crate dirs to v6
|
|
||||||
- *(deps)* update rust crate uuid to v1.11.1
|
|
||||||
|
|
||||||
### Other
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update rust crate clap to v4.5.29
|
|
||||||
- *(deps)* update rust crate clap to v4.5.27
|
|
||||||
- *(deps)* update rust crate clap to v4.5.26
|
|
||||||
- *(deps)* update rust crate tokio to v1.43.0
|
|
||||||
- update example
|
|
||||||
|
|
||||||
## [0.3.4] - 2025-01-08
|
## [0.3.4] - 2025-01-08
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
1440
Cargo.lock
generated
1440
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ members = ["crates/*"]
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.3.5"
|
version = "0.3.4"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
# Git Now
|
# Git Now
|
||||||
|
|
||||||
> https://gitnow.kjuulh.io/
|
|
||||||
|
|
||||||
Git Now is a utility for easily navigating git projects from common upstream providers. Search, Download, and Enter projects as quickly as you can type.
|
Git Now is a utility for easily navigating git projects from common upstream providers. Search, Download, and Enter projects as quickly as you can type.
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gitnow"
|
name = "gitnow"
|
||||||
description = "Git Now is a utility for easily navigating git projects from common upstream providers. Search, Download, and Enter projects as quickly as you can type."
|
description = "Git Now is a utility for easily navigating git projects from common upstream providers. Search, Download, and Enter projects as quickly as you can type."
|
||||||
edition = "2024"
|
edition = "2021"
|
||||||
readme = "../../README.md"
|
readme = "../../README.md"
|
||||||
repository = "https://github.com/kjuulh/gitnow"
|
repository = "https://github.com/kjuulh/gitnow"
|
||||||
homepage = "https://gitnow-client.prod.kjuulh.app"
|
homepage = "https://gitnow-client.prod.kjuulh.app"
|
||||||
@@ -36,7 +36,6 @@ ratatui = { version = "0.29.0", features = ["termwiz"] }
|
|||||||
crossterm = { version = "0.28.0", features = ["event-stream"] }
|
crossterm = { version = "0.28.0", features = ["event-stream"] }
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
termwiz = "0.23.0"
|
termwiz = "0.23.0"
|
||||||
regex = "1.11.1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.4.0"
|
pretty_assertions = "1.4.0"
|
||||||
|
|||||||
@@ -1,83 +1,3 @@
|
|||||||
pub mod root;
|
pub mod root;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
pub mod update;
|
pub mod update;
|
||||||
pub mod clone {
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use futures::future::join_all;
|
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
app::App, cache::CacheApp, custom_command::CustomCommandApp, git_clone::GitCloneApp,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(clap::Parser)]
|
|
||||||
pub struct CloneCommand {
|
|
||||||
#[arg(long = "search")]
|
|
||||||
search: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CloneCommand {
|
|
||||||
pub async fn execute(&mut self, app: &'static App) -> anyhow::Result<()> {
|
|
||||||
let repos = app.cache().get().await?.ok_or(anyhow::anyhow!(
|
|
||||||
"failed to get cache, do a gitnow update first"
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let search = Regex::new(&self.search)?;
|
|
||||||
|
|
||||||
let filtered_repos = repos
|
|
||||||
.iter()
|
|
||||||
.filter(|r| search.is_match(&r.to_rel_path().display().to_string()))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let concurrency_limit = Arc::new(tokio::sync::Semaphore::new(5));
|
|
||||||
let mut handles = Vec::default();
|
|
||||||
for repo in filtered_repos {
|
|
||||||
let config = app.config.clone();
|
|
||||||
let custom_command = app.custom_command();
|
|
||||||
let git_clone = app.git_clone();
|
|
||||||
let repo = repo.clone();
|
|
||||||
let concurrency = Arc::clone(&concurrency_limit);
|
|
||||||
|
|
||||||
let handle = tokio::spawn(async move {
|
|
||||||
let permit = concurrency.acquire().await?;
|
|
||||||
|
|
||||||
let project_path = config.settings.projects.directory.join(repo.to_rel_path());
|
|
||||||
if !project_path.exists() {
|
|
||||||
eprintln!("cloning repository: {}", repo.to_rel_path().display());
|
|
||||||
git_clone.clone_repo(&repo, false).await?;
|
|
||||||
|
|
||||||
custom_command
|
|
||||||
.execute_post_clone_command(&project_path)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(permit);
|
|
||||||
|
|
||||||
Ok::<(), anyhow::Error>(())
|
|
||||||
});
|
|
||||||
|
|
||||||
handles.push(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = join_all(handles).await;
|
|
||||||
|
|
||||||
for res in res {
|
|
||||||
match res {
|
|
||||||
Ok(Ok(())) => {}
|
|
||||||
Ok(Err(e)) => {
|
|
||||||
tracing::error!("failed to clone repo: {}", e);
|
|
||||||
anyhow::bail!(e)
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("failed to clone repo: {}", e);
|
|
||||||
anyhow::bail!(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ use std::time::Duration;
|
|||||||
use crossterm::event::{EventStream, KeyCode};
|
use crossterm::event::{EventStream, KeyCode};
|
||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
TerminalOptions, Viewport, crossterm,
|
crossterm,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widgets::{Block, Padding},
|
widgets::{Block, Padding},
|
||||||
|
TerminalOptions, Viewport,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::components::BatchCommand;
|
use crate::components::BatchCommand;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Dispatch, IntoCommand, Msg, Receiver, create_dispatch,
|
create_dispatch,
|
||||||
spinner::{Spinner, SpinnerState},
|
spinner::{Spinner, SpinnerState},
|
||||||
|
Dispatch, IntoCommand, Msg, Receiver,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct InlineCommand {
|
pub struct InlineCommand {
|
||||||
@@ -118,7 +120,7 @@ impl InlineCommand {
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cmd = self.update_state(msg);
|
let mut cmd = self.update_state(&msg);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let msg = cmd.into_command().execute(dispatch);
|
let msg = cmd.into_command().execute(dispatch);
|
||||||
@@ -126,7 +128,7 @@ impl InlineCommand {
|
|||||||
match msg {
|
match msg {
|
||||||
Some(Msg::Quit) => return Ok(true),
|
Some(Msg::Quit) => return Ok(true),
|
||||||
Some(msg) => {
|
Some(msg) => {
|
||||||
cmd = self.update_state(msg);
|
cmd = self.update_state(&msg);
|
||||||
}
|
}
|
||||||
None => break,
|
None => break,
|
||||||
}
|
}
|
||||||
@@ -161,7 +163,7 @@ impl InlineCommand {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_state(&mut self, msg: Msg) -> impl IntoCommand {
|
fn update_state(&mut self, msg: &Msg) -> impl IntoCommand {
|
||||||
tracing::debug!("handling message: {:?}", msg);
|
tracing::debug!("handling message: {:?}", msg);
|
||||||
|
|
||||||
let mut batch = BatchCommand::default();
|
let mut batch = BatchCommand::default();
|
||||||
@@ -176,7 +178,7 @@ impl InlineCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.with(self.spinner.update(&msg));
|
batch.with(self.spinner.update(msg));
|
||||||
|
|
||||||
batch.into_command()
|
batch.into_command()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ impl CacheDuration {
|
|||||||
hours,
|
hours,
|
||||||
minutes,
|
minutes,
|
||||||
} => Some(
|
} => Some(
|
||||||
std::time::Duration::from_hours(*days * 24)
|
std::time::Duration::from_days(*days)
|
||||||
+ std::time::Duration::from_hours(*hours)
|
+ std::time::Duration::from_hours(*hours)
|
||||||
+ std::time::Duration::from_mins(*minutes),
|
+ std::time::Duration::from_mins(*minutes),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
#![feature(duration_constructors)]
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use commands::{clone::CloneCommand, root::RootCommand, shell::Shell, update::Update};
|
use commands::{root::RootCommand, shell::Shell, update::Update};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use tracing::level_filters::LevelFilter;
|
use tracing::level_filters::LevelFilter;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
@@ -50,7 +52,6 @@ struct Command {
|
|||||||
enum Commands {
|
enum Commands {
|
||||||
Init(Shell),
|
Init(Shell),
|
||||||
Update(Update),
|
Update(Update),
|
||||||
Clone(CloneCommand),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_CONFIG_PATH: &str = ".config/gitnow/gitnow.toml";
|
const DEFAULT_CONFIG_PATH: &str = ".config/gitnow/gitnow.toml";
|
||||||
@@ -88,9 +89,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Commands::Update(mut update) => {
|
Commands::Update(mut update) => {
|
||||||
update.execute(app).await?;
|
update.execute(app).await?;
|
||||||
}
|
}
|
||||||
Commands::Clone(mut clone) => {
|
|
||||||
clone.execute(app).await?;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
RootCommand::new(app)
|
RootCommand::new(app)
|
||||||
|
|||||||
Reference in New Issue
Block a user