diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-12-05 12:13:02 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-12-05 12:13:02 +0000 |
| commit | c6fef5613fc64037e591a6515c025d5ed559915c (patch) | |
| tree | 552ab122c5c0ae4e07c72aecdc35d24eb579620f /src | |
| parent | e00f712fb09d2a55fbfd36696f3725bc44c140f5 (diff) | |
fix: `ngit`validate repo address exists
when nostr address is unknown and user is prompted, validate that
a the entered repo exists (there are events related to it) before
proceeding
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/ngit/sub_commands/list.rs | 2 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/send.rs | 2 | ||||
| -rw-r--r-- | src/lib/repo_ref.rs | 76 |
3 files changed, 53 insertions, 27 deletions
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs index f79e284..b7bfd24 100644 --- a/src/bin/ngit/sub_commands/list.rs +++ b/src/bin/ngit/sub_commands/list.rs | |||
| @@ -33,7 +33,7 @@ pub async fn launch() -> Result<()> { | |||
| 33 | 33 | ||
| 34 | let client = Client::default(); | 34 | let client = Client::default(); |
| 35 | 35 | ||
| 36 | let repo_coordinates = get_repo_coordinates_when_remote_unknown(&git_repo).await?; | 36 | let repo_coordinates = get_repo_coordinates_when_remote_unknown(&git_repo, &client).await?; |
| 37 | 37 | ||
| 38 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; | 38 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; |
| 39 | 39 | ||
diff --git a/src/bin/ngit/sub_commands/send.rs b/src/bin/ngit/sub_commands/send.rs index bc4d18a..e19c38b 100644 --- a/src/bin/ngit/sub_commands/send.rs +++ b/src/bin/ngit/sub_commands/send.rs | |||
| @@ -54,7 +54,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs, no_fetch: bool) -> Re | |||
| 54 | 54 | ||
| 55 | let mut client = Client::default(); | 55 | let mut client = Client::default(); |
| 56 | 56 | ||
| 57 | let repo_coordinates = get_repo_coordinates_when_remote_unknown(&git_repo).await?; | 57 | let repo_coordinates = get_repo_coordinates_when_remote_unknown(&git_repo, &client).await?; |
| 58 | 58 | ||
| 59 | if !no_fetch { | 59 | if !no_fetch { |
| 60 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; | 60 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; |
diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs index 8f8b4ad..89aec17 100644 --- a/src/lib/repo_ref.rs +++ b/src/lib/repo_ref.rs | |||
| @@ -12,9 +12,11 @@ use nostr::{nips::nip01::Coordinate, FromBech32, PublicKey, Tag, TagStandard, To | |||
| 12 | use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; | 12 | use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; |
| 13 | use serde::{Deserialize, Serialize}; | 13 | use serde::{Deserialize, Serialize}; |
| 14 | 14 | ||
| 15 | #[cfg(not(test))] | ||
| 16 | use crate::client::Client; | ||
| 15 | use crate::{ | 17 | use crate::{ |
| 16 | cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms, PromptInputParms}, | 18 | cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms, PromptInputParms}, |
| 17 | client::sign_event, | 19 | client::{consolidate_fetch_reports, sign_event, Connect}, |
| 18 | git::{nostr_url::NostrUrlDecoded, Repo, RepoActions}, | 20 | git::{nostr_url::NostrUrlDecoded, Repo, RepoActions}, |
| 19 | login::user::get_user_details, | 21 | login::user::get_user_details, |
| 20 | }; | 22 | }; |
| @@ -240,11 +242,15 @@ impl RepoRef { | |||
| 240 | } | 242 | } |
| 241 | } | 243 | } |
| 242 | 244 | ||
| 243 | pub async fn get_repo_coordinates_when_remote_unknown(git_repo: &Repo) -> Result<Coordinate> { | 245 | pub async fn get_repo_coordinates_when_remote_unknown( |
| 246 | git_repo: &Repo, | ||
| 247 | #[cfg(test)] client: &crate::client::MockConnect, | ||
| 248 | #[cfg(not(test))] client: &Client, | ||
| 249 | ) -> Result<Coordinate> { | ||
| 244 | if let Ok(c) = try_and_get_repo_coordinates_when_remote_unknown(git_repo).await { | 250 | if let Ok(c) = try_and_get_repo_coordinates_when_remote_unknown(git_repo).await { |
| 245 | Ok(c) | 251 | Ok(c) |
| 246 | } else { | 252 | } else { |
| 247 | get_repo_coordinates_from_user_prompt(git_repo) | 253 | get_repo_coordinate_from_user_prompt(git_repo, client).await |
| 248 | } | 254 | } |
| 249 | } | 255 | } |
| 250 | 256 | ||
| @@ -354,37 +360,57 @@ async fn get_repo_coordinates_from_maintainers_yaml(git_repo: &Repo) -> Result<C | |||
| 354 | }) | 360 | }) |
| 355 | } | 361 | } |
| 356 | 362 | ||
| 357 | fn get_repo_coordinates_from_user_prompt(git_repo: &Repo) -> Result<Coordinate> { | 363 | async fn get_repo_coordinate_from_user_prompt( |
| 364 | git_repo: &Repo, | ||
| 365 | #[cfg(test)] client: &crate::client::MockConnect, | ||
| 366 | #[cfg(not(test))] client: &Client, | ||
| 367 | ) -> Result<Coordinate> { | ||
| 358 | // TODO: present list of events filter by root_commit | 368 | // TODO: present list of events filter by root_commit |
| 359 | // TODO: fallback to search based on identifier | 369 | // TODO: fallback to search based on identifier |
| 360 | let c = ask_for_naddr()?; | ||
| 361 | // PROBLEM: we are saving this before checking whether it actually exists, which | ||
| 362 | // means next time the user won't be prompted and may not know how to | ||
| 363 | // change the selected repo | ||
| 364 | git_repo.save_git_config_item("nostr.repo", &c.to_bech32()?, false)?; | ||
| 365 | // TODO: prompt to add a git remote | ||
| 366 | Ok(c) | ||
| 367 | } | ||
| 368 | |||
| 369 | fn ask_for_naddr() -> Result<Coordinate> { | ||
| 370 | let dim = Style::new().color256(247); | 370 | let dim = Style::new().color256(247); |
| 371 | println!( | 371 | println!( |
| 372 | "{}", | 372 | "{}", |
| 373 | dim.apply_to( | 373 | dim.apply_to( |
| 374 | "hint: https://gitworkshop.dev/repos lists repositories and their nostr addresses" | 374 | "hint: https://gitworkshop.dev/repos lists repositories and their nostr address" |
| 375 | ), | 375 | ), |
| 376 | ); | 376 | ); |
| 377 | 377 | let git_repo_path = git_repo.get_path()?; | |
| 378 | Ok(loop { | 378 | let coordinate = { |
| 379 | let input = Interactor::default() | 379 | loop { |
| 380 | .input(PromptInputParms::default().with_prompt("nostr repository"))?; | 380 | let input = Interactor::default() |
| 381 | if let Ok(c) = Coordinate::parse(&input) { | 381 | .input(PromptInputParms::default().with_prompt("nostr repository"))?; |
| 382 | break c; | 382 | let coordinate = if let Ok(c) = Coordinate::parse(&input) { |
| 383 | } else if let Ok(nostr_url) = NostrUrlDecoded::from_str(&input) { | 383 | c |
| 384 | break nostr_url.coordinate; | 384 | } else if let Ok(nostr_url) = NostrUrlDecoded::from_str(&input) { |
| 385 | nostr_url.coordinate | ||
| 386 | } else { | ||
| 387 | eprintln!("not a valid naddr or git nostr remote URL starting nostr://"); | ||
| 388 | continue; | ||
| 389 | }; | ||
| 390 | let term = console::Term::stderr(); | ||
| 391 | term.write_line("searching for repository...")?; | ||
| 392 | let (relay_reports, progress_reporter) = client | ||
| 393 | .fetch_all( | ||
| 394 | Some(git_repo_path), | ||
| 395 | Some(&coordinate), | ||
| 396 | &HashSet::from_iter(vec![coordinate.public_key]), | ||
| 397 | ) | ||
| 398 | .await?; | ||
| 399 | let relay_errs = relay_reports.iter().any(std::result::Result::is_err); | ||
| 400 | let report = consolidate_fetch_reports(relay_reports); | ||
| 401 | if !relay_errs && !report.to_string().is_empty() { | ||
| 402 | let _ = progress_reporter.clear(); | ||
| 403 | } | ||
| 404 | if report.to_string().is_empty() { | ||
| 405 | eprintln!("couldn't find repository"); | ||
| 406 | continue; | ||
| 407 | } else { | ||
| 408 | eprintln!("repository found"); | ||
| 409 | break coordinate; | ||
| 410 | } | ||
| 385 | } | 411 | } |
| 386 | println!("not a valid naddr or git nostr remote URL starting nostr://"); | 412 | }; |
| 387 | }) | 413 | Ok(coordinate) |
| 388 | } | 414 | } |
| 389 | 415 | ||
| 390 | #[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)] | 416 | #[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)] |