cli: Add `--draft` flag to `rad patch open`

Allows opening patches as drafts.
This commit is contained in:
Alexis Sellier 2023-04-26 13:47:43 +02:00
parent 3b20d45d80
commit 182c9592c0
No known key found for this signature in database
3 changed files with 104 additions and 26 deletions

View File

@ -40,7 +40,7 @@ Usage
rad patch [<option>...] rad patch [<option>...]
rad patch list [--all|--merged|--open|--archived] [<option>...] rad patch list [--all|--merged|--open|--archived] [<option>...]
rad patch show <patch-id> [<option>...] rad patch show <patch-id> [<option>...]
rad patch open [<option>...] rad patch open [--draft] [<option>...]
rad patch archive <patch-id> [<option>...] rad patch archive <patch-id> [<option>...]
rad patch update <patch-id> [<option>...] rad patch update <patch-id> [<option>...]
rad patch checkout <patch-id> [<option>...] rad patch checkout <patch-id> [<option>...]
@ -50,8 +50,9 @@ Show options
-p, --patch Show the actual patch diff -p, --patch Show the actual patch diff
Create/Update options Open/Update options
--draft Open patch in draft mode
--[no-]announce Announce patch to network (default: false) --[no-]announce Announce patch to network (default: false)
--[no-]push Push patch head to storage (default: true) --[no-]push Push patch head to storage (default: true)
-m, --message [<string>] Provide a comment message to the patch or revision (default: prompt) -m, --message [<string>] Provide a comment message to the patch or revision (default: prompt)
@ -86,6 +87,7 @@ pub enum OperationName {
pub enum Operation { pub enum Operation {
Open { Open {
message: Message, message: Message,
draft: bool,
}, },
Show { Show {
patch_id: Rev, patch_id: Rev,
@ -132,6 +134,7 @@ impl Args for Options {
let mut push = true; let mut push = true;
let mut filter = Some(patch::State::Open); let mut filter = Some(patch::State::Open);
let mut diff = false; let mut diff = false;
let mut draft = false;
while let Some(arg) = parser.next()? { while let Some(arg) = parser.next()? {
match arg { match arg {
@ -165,6 +168,11 @@ impl Args for Options {
push = false; push = false;
} }
// Open options.
Long("draft") if op == Some(OperationName::Open) => {
draft = true;
}
// Show options. // Show options.
Long("patch") | Short('p') if op == Some(OperationName::Show) => { Long("patch") | Short('p') if op == Some(OperationName::Show) => {
diff = true; diff = true;
@ -221,7 +229,7 @@ impl Args for Options {
} }
let op = match op.unwrap_or_default() { let op = match op.unwrap_or_default() {
OperationName::Open => Operation::Open { message }, OperationName::Open => Operation::Open { message, draft },
OperationName::List => Operation::List { filter }, OperationName::List => Operation::List { filter },
OperationName::Show => Operation::Show { OperationName::Show => Operation::Show {
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?, patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
@ -266,8 +274,15 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
} }
match options.op { match options.op {
Operation::Open { ref message } => { Operation::Open { ref message, draft } => {
create::run(&repository, &profile, &workdir, message.clone(), options)?; create::run(
&repository,
&profile,
&workdir,
message.clone(),
draft,
options,
)?;
} }
Operation::List { filter } => { Operation::List { filter } => {
list::run(&repository, &profile, filter)?; list::run(&repository, &profile, filter)?;

View File

@ -84,6 +84,7 @@ pub fn run(
profile: &Profile, profile: &Profile,
workdir: &git::raw::Repository, workdir: &git::raw::Repository,
message: term::patch::Message, message: term::patch::Message,
draft: bool,
options: Options, options: Options,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut patches = patch::Patches::open(storage)?; let mut patches = patch::Patches::open(storage)?;
@ -116,15 +117,27 @@ pub fn run(
let head_oid = branch_oid(&head_branch)?; let head_oid = branch_oid(&head_branch)?;
let base_oid = workdir.merge_base(*target_oid, *head_oid)?; let base_oid = workdir.merge_base(*target_oid, *head_oid)?;
let signer = term::signer(profile)?; let signer = term::signer(profile)?;
let patch = patches.create( let patch = if draft {
title, patches.draft(
&description, title,
patch::MergeTarget::default(), &description,
base_oid, patch::MergeTarget::default(),
head_oid, base_oid,
&[], head_oid,
&signer, &[],
)?; &signer,
)
} else {
patches.create(
title,
&description,
patch::MergeTarget::default(),
base_oid,
head_oid,
&[],
&signer,
)
}?;
term::success!("Patch {} created", term::format::highlight(patch.id)); term::success!("Patch {} created", term::format::highlight(patch.id));
term::blank(); term::blank();

View File

@ -1029,7 +1029,7 @@ impl<'a> Patches<'a> {
Ok(Self { raw }) Ok(Self { raw })
} }
/// Create a patch. /// Open a new patch.
pub fn create<'g, G: Signer>( pub fn create<'g, G: Signer>(
&'g mut self, &'g mut self,
title: impl ToString, title: impl ToString,
@ -1040,18 +1040,39 @@ impl<'a> Patches<'a> {
tags: &[Tag], tags: &[Tag],
signer: &G, signer: &G,
) -> Result<PatchMut<'a, 'g>, Error> { ) -> Result<PatchMut<'a, 'g>, Error> {
let (id, patch, clock) = self._create(
Transaction::initial("Create patch", &mut self.raw, signer, |tx| { title,
tx.revision(String::default(), base, oid)?; description,
tx.edit(title, description, target)?; target,
tx.tag(tags.to_owned(), [])?; base,
oid,
tags,
State::default(),
signer,
)
}
Ok(()) /// Draft a patch. This patch will be created in a [`State::Draft`] state.
})?; pub fn draft<'g, G: Signer>(
// Just a sanity check that our clock is advancing as expected. &'g mut self,
debug_assert_eq!(clock.get(), 1); title: impl ToString,
description: impl ToString,
Ok(PatchMut::new(id, patch, clock, self)) target: MergeTarget,
base: impl Into<git::Oid>,
oid: impl Into<git::Oid>,
tags: &[Tag],
signer: &G,
) -> Result<PatchMut<'a, 'g>, Error> {
self._create(
title,
description,
target,
base,
oid,
tags,
State::Draft,
signer,
)
} }
/// Patches count by state. /// Patches count by state.
@ -1132,6 +1153,35 @@ impl<'a> Patches<'a> {
.proposed()? .proposed()?
.filter(move |(_, p, _)| p.author().id() == who)) .filter(move |(_, p, _)| p.author().id() == who))
} }
/// Create a patch. This is an internal function used by `create` and `draft`.
fn _create<'g, G: Signer>(
&'g mut self,
title: impl ToString,
description: impl ToString,
target: MergeTarget,
base: impl Into<git::Oid>,
oid: impl Into<git::Oid>,
tags: &[Tag],
state: State,
signer: &G,
) -> Result<PatchMut<'a, 'g>, Error> {
let (id, patch, clock) =
Transaction::initial("Create patch", &mut self.raw, signer, |tx| {
tx.revision(String::default(), base, oid)?;
tx.edit(title, description, target)?;
tx.tag(tags.to_owned(), [])?;
if state != State::default() {
tx.lifecycle(state)?;
}
Ok(())
})?;
// Just a sanity check that our clock is advancing as expected.
debug_assert_eq!(clock.get(), 1);
Ok(PatchMut::new(id, patch, clock, self))
}
} }
#[cfg(test)] #[cfg(test)]