From ed1bfaf161733f20e17db1413921d51c0ca3932d Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Mon, 18 Aug 2025 13:25:36 +0000
Subject: [PATCH] fix(issue)!: make subject mandatory and optional content
BREAKING CHANGE: When the editor contains only one line, it is now
treated as the subject instead of being used as the issue content.
Signed-off-by: Awiteb
---
CHANGELOG.md | 14 +++++++
src/cli/commands/issue/new.rs | 72 +++++++++++++++--------------------
src/nostr_utils/utils.rs | 29 ++++++++++++++
3 files changed, 73 insertions(+), 42 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 85a06ae..89be98e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## Unreleased
+
+### Added
+
+- New command `repo state` - by Awiteb
+
+### Breaking Change
+
+- Make subject mandatory and optional content - by Awiteb
+
+### Fixed
+
+- Check the nip07 signer in `CliOptions::ensure_signer` - by Awiteb
+
## [0.4.0] - 2025-08-08
### Added
diff --git a/src/cli/commands/issue/new.rs b/src/cli/commands/issue/new.rs
index fcffd37..7ae61e8 100644
--- a/src/cli/commands/issue/new.rs
+++ b/src/cli/commands/issue/new.rs
@@ -37,14 +37,9 @@ use crate::{
/// Arguments for the `issue new` command
#[derive(Args, Debug)]
#[clap(
- group(
- ArgGroup::new("issue-content")
- .args(["content", "editor"])
- .required(true)
- ),
group(
ArgGroup::new("issue-subject")
- .args(["editor", "subject"])
+ .required(true)
)
)]
pub struct NewArgs {
@@ -56,14 +51,14 @@ pub struct NewArgs {
naddrs: Option>,
/// Markdown content for the issue. Cannot be used together with the
/// `--editor` flag.
- #[arg(short, long)]
+ #[arg(short, long, group = "issue-content")]
content: Option,
/// Opens the user's default editor to write issue content. The first line
/// will be used as the issue subject.
- #[arg(short, long)]
+ #[arg(short, long, group = "issue-subject", group = "issue-content")]
editor: bool,
/// The issue subject. Cannot be used together with the `--editor` flag.
- #[arg(long)]
+ #[arg(long, group = "issue-subject")]
subject: Option,
/// Labels for the issue. Can be specified as arguments (-l bug) or hashtags
/// in content (#bug).
@@ -71,29 +66,6 @@ pub struct NewArgs {
label: Vec,
}
-impl NewArgs {
- /// Returns the subject and the content of the issue. (subject, content)
- pub fn issue_content(&self) -> N34Result<(Option, String)> {
- if let Some(content) = self.content.as_ref() {
- if let Some(subject) = self.subject.as_ref() {
- return Ok((Some(subject.trim().to_owned()), content.trim().to_owned()));
- }
- return Ok((None, content.trim().to_owned()));
- }
- // If the `self.content` is `None` then the `self.editor` is `true`
- let file_content = utils::read_editor(None, ".md")?;
- if file_content.contains('\n') {
- Ok(file_content
- .split_once('\n')
- .map(|(s, c)| (Some(s.trim().to_owned()), c.trim().to_owned()))
- .expect("There is a new line"))
- } else {
- tracing::info!("File content contains only issue body without a subject line");
- Ok((None, file_content))
- }
- }
-}
-
impl CommandRunner for NewArgs {
async fn run(self, options: CliOptions) -> N34Result<()> {
let naddrs = utils::check_empty_naddrs(utils::naddrs_or_file(
@@ -113,16 +85,30 @@ impl CommandRunner for NewArgs {
.add_relays(&utils::add_read_relays(relays_list.as_ref()))
.await;
- let (subject, content) = self.issue_content()?;
- let content_details = client.parse_content(&content).await;
+ let (subject, content) = utils::subject_and_body(self.subject, self.content, ".md")?;
- let event =
- EventBuilder::new_git_issue(coordinates.as_slice(), content, subject, self.label)?
- .dedup_tags()
- .pow(options.pow.unwrap_or_default())
- .tags(maintainers.iter().map(|p| Tag::public_key(*p)))
- .tags(content_details.clone().into_tags())
- .build(user_pubk);
+ let content_details = if let Some(content) = &content {
+ Some(client.parse_content(content).await)
+ } else {
+ None
+ };
+
+ let event = EventBuilder::new_git_issue(
+ coordinates.as_slice(),
+ content.unwrap_or_default(),
+ Some(subject),
+ self.label,
+ )?
+ .dedup_tags()
+ .pow(options.pow.unwrap_or_default())
+ .tags(maintainers.iter().map(|p| Tag::public_key(*p)))
+ .tags(
+ content_details
+ .clone()
+ .map(|c| c.into_tags())
+ .unwrap_or_default(),
+ )
+ .build(user_pubk);
let event_id = event.id.expect("There is an id");
let write_relays = [
@@ -135,7 +121,9 @@ impl CommandRunner for NewArgs {
.extract_relays(),
// Include read relays for each maintainer (if found)
client.read_relays_from_users(&maintainers).await,
- content_details.write_relays.clone().into_iter().collect(),
+ content_details
+ .map(|c| c.write_relays.into_iter().collect())
+ .unwrap_or_default(),
]
.concat();
diff --git a/src/nostr_utils/utils.rs b/src/nostr_utils/utils.rs
index d9fca30..701879e 100644
--- a/src/nostr_utils/utils.rs
+++ b/src/nostr_utils/utils.rs
@@ -309,3 +309,32 @@ pub fn check_empty_naddrs(naddrs: Vec) -> N34Result,
+ body: Option,
+ file_suffix: &str,
+) -> N34Result<(String, Option)> {
+ if let Some(subject) = subject {
+ return Ok((subject, body));
+ }
+
+ // There is no subject, so we need to get it from the editor
+ let file_content = read_editor(None, file_suffix)?;
+ // if there is a subject and body
+ if file_content.contains('\n') {
+ Ok(file_content
+ .split_once("\n")
+ .map(|(subject, body)| (subject.trim().to_owned(), Some(body.trim().to_owned())))
+ .expect("There is a newline"))
+ } else {
+ tracing::info!("File content contains only the subject");
+ Ok((file_content.trim().to_owned(), None))
+ }
+}