cli: Add `--draft` flag to `rad patch open`
Allows opening patches as drafts.
This commit is contained in:
parent
3b20d45d80
commit
182c9592c0
|
|
@ -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)?;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue