diff --git a/CHANGELOG.md b/CHANGELOG.md index bf171a8..a2049c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New `patch` subcommands apply,close,draft,merge and reopen to manage the patch status - by Awiteb - View the repo maintainers as `npub` - by Awiteb - New `patch list` commands to list the repo patches - by Awiteb +- New `issue list` commands to list the repo issues - by Awiteb ### Dependencies diff --git a/README.md b/README.md index 1c56982..34daa67 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ details, see the following section. - [X] Repository announcements - [ ] Repository state announcements -- [X] Patches (Send and fetch) -- [X] Issues (Send and view) +- [X] Patches (Send, fetch and list) +- [X] Issues (Send, view and list) - [X] Replies - [X] Issues and patches status - [X] Gossip Model ([NIP-65]) diff --git a/src/cli/commands/issue/list.rs b/src/cli/commands/issue/list.rs new file mode 100644 index 0000000..f360e8c --- /dev/null +++ b/src/cli/commands/issue/list.rs @@ -0,0 +1,46 @@ +// n34 - A CLI to interact with NIP-34 and other stuff related to codes in nostr +// Copyright (C) 2025 Awiteb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use std::num::NonZeroUsize; + +use clap::Args; + +use crate::{ + cli::{CliOptions, common_commands, traits::CommandRunner, types::NaddrOrSet}, + error::N34Result, +}; + +#[derive(Debug, Args)] +pub struct ListArgs { + /// Repository address in `naddr` format (`naddr1...`), NIP-05 format + /// (`4rs.nl/n34` or `_@4rs.nl/n34`), or a set name like `kernel`. + /// + /// If omitted, looks for a `nostr-address` file. + #[arg(value_name = "NADDR-NIP05-OR-SET")] + naddrs: Option>, + /// Maximum number of issues to list + #[arg(long, default_value = "15")] + limit: NonZeroUsize, +} + +impl CommandRunner for ListArgs { + const NEED_SIGNER: bool = false; + + async fn run(self, options: CliOptions) -> N34Result<()> { + common_commands::list_patches_and_issues(options, self.naddrs, false, self.limit.into()) + .await + } +} diff --git a/src/cli/commands/issue/mod.rs b/src/cli/commands/issue/mod.rs index 64a767e..6ec4230 100644 --- a/src/cli/commands/issue/mod.rs +++ b/src/cli/commands/issue/mod.rs @@ -16,6 +16,8 @@ /// `issue close` subcommand mod close; +/// `issue list` subcommand +mod list; /// `issue new` subcommand mod new; /// `issue reopen` subcommand @@ -25,10 +27,13 @@ mod resolve; /// `issue view` subcommand mod view; +use std::fmt; + use clap::Subcommand; use nostr::event::Kind; use self::close::CloseArgs; +use self::list::ListArgs; use self::new::NewArgs; use self::reopen::ReopenArgs; use self::resolve::ResolveArgs; @@ -51,6 +56,8 @@ pub enum IssueSubcommands { Close(CloseArgs), /// Resolves an open issue. Resolve(ResolveArgs), + /// List the repositories issues. + List(ListArgs), } /// Possible states for a Git issue @@ -75,6 +82,15 @@ impl IssueStatus { } } + /// Returns the string representation of the issue status. + pub const fn as_str(&self) -> &'static str { + match self { + Self::Open => "Open", + Self::Resolved => "Resolved", + Self::Closed => "Closed", + } + } + /// Check if the issue is open. #[inline] pub fn is_open(&self) -> bool { @@ -94,6 +110,18 @@ impl IssueStatus { } } +impl From<&IssueStatus> for Kind { + fn from(status: &IssueStatus) -> Self { + status.kind() + } +} + +impl fmt::Display for IssueStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + impl TryFrom for IssueStatus { type Error = N34Error; @@ -109,6 +137,6 @@ impl TryFrom for IssueStatus { impl CommandRunner for IssueSubcommands { async fn run(self, options: CliOptions) -> N34Result<()> { - crate::run_command!(self, options, & New View Reopen Close Resolve) + crate::run_command!(self, options, & New View Reopen Close Resolve List) } }