cli: Add `rad patch archive --undo`
Allows archived patches to be reverted to open state.
This commit is contained in:
parent
ea31040ec6
commit
0581c017ae
|
|
@ -57,7 +57,7 @@ Usage
|
||||||
rad patch list [--all|--merged|--open|--archived|--draft|--authored] [--author <did>]... [<option>...]
|
rad patch list [--all|--merged|--open|--archived|--draft|--authored] [--author <did>]... [<option>...]
|
||||||
rad patch show <patch-id> [<option>...]
|
rad patch show <patch-id> [<option>...]
|
||||||
rad patch diff <patch-id> [<option>...]
|
rad patch diff <patch-id> [<option>...]
|
||||||
rad patch archive <patch-id> [<option>...]
|
rad patch archive <patch-id> [--undo] [<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>...]
|
||||||
rad patch review <patch-id> [--accept | --reject] [-m [<string>]] [-d | --delete] [<option>...]
|
rad patch review <patch-id> [--accept | --reject] [-m [<string>]] [-d | --delete] [<option>...]
|
||||||
|
|
@ -109,6 +109,10 @@ Assign options
|
||||||
-d, --delete <did> Delete an assignee from the patch (may be specified multiple times).
|
-d, --delete <did> Delete an assignee from the patch (may be specified multiple times).
|
||||||
Note: --add will take precedence over --delete
|
Note: --add will take precedence over --delete
|
||||||
|
|
||||||
|
Archive options
|
||||||
|
|
||||||
|
--undo Unarchive a patch
|
||||||
|
|
||||||
Label options
|
Label options
|
||||||
|
|
||||||
-a, --add <label> Add a label to the patch (may be specified multiple times).
|
-a, --add <label> Add a label to the patch (may be specified multiple times).
|
||||||
|
|
@ -204,6 +208,7 @@ pub enum Operation {
|
||||||
},
|
},
|
||||||
Archive {
|
Archive {
|
||||||
patch_id: Rev,
|
patch_id: Rev,
|
||||||
|
undo: bool,
|
||||||
},
|
},
|
||||||
Ready {
|
Ready {
|
||||||
patch_id: Rev,
|
patch_id: Rev,
|
||||||
|
|
@ -347,6 +352,11 @@ impl Args for Options {
|
||||||
undo = true;
|
undo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Archive options.
|
||||||
|
Long("undo") if op == Some(OperationName::Archive) => {
|
||||||
|
undo = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Update options.
|
// Update options.
|
||||||
Short('b') | Long("base") if op == Some(OperationName::Update) => {
|
Short('b') | Long("base") if op == Some(OperationName::Update) => {
|
||||||
let val = parser.value()?;
|
let val = parser.value()?;
|
||||||
|
|
@ -591,6 +601,7 @@ impl Args for Options {
|
||||||
},
|
},
|
||||||
OperationName::Archive => Operation::Archive {
|
OperationName::Archive => Operation::Archive {
|
||||||
patch_id: patch_id.ok_or_else(|| anyhow!("a patch id must be provided"))?,
|
patch_id: patch_id.ok_or_else(|| anyhow!("a patch id must be provided"))?,
|
||||||
|
undo,
|
||||||
},
|
},
|
||||||
OperationName::Checkout => Operation::Checkout {
|
OperationName::Checkout => Operation::Checkout {
|
||||||
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"))?,
|
||||||
|
|
@ -726,9 +737,9 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
&workdir,
|
&workdir,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Operation::Archive { ref patch_id } => {
|
Operation::Archive { ref patch_id, undo } => {
|
||||||
let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
|
let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
|
||||||
archive::run(&patch_id, &profile, &repository)?;
|
archive::run(&patch_id, undo, &profile, &repository)?;
|
||||||
}
|
}
|
||||||
Operation::Ready { ref patch_id, undo } => {
|
Operation::Ready { ref patch_id, undo } => {
|
||||||
let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
|
let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,23 @@ use super::*;
|
||||||
use radicle::prelude::*;
|
use radicle::prelude::*;
|
||||||
use radicle::storage::git::Repository;
|
use radicle::storage::git::Repository;
|
||||||
|
|
||||||
pub fn run(patch_id: &PatchId, profile: &Profile, repository: &Repository) -> anyhow::Result<()> {
|
pub fn run(
|
||||||
|
patch_id: &PatchId,
|
||||||
|
undo: bool,
|
||||||
|
profile: &Profile,
|
||||||
|
repository: &Repository,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
let signer = term::signer(profile)?;
|
let signer = term::signer(profile)?;
|
||||||
let mut patches = profile.patches_mut(repository)?;
|
let mut patches = profile.patches_mut(repository)?;
|
||||||
let Ok(mut patch) = patches.get_mut(patch_id) else {
|
let Ok(mut patch) = patches.get_mut(patch_id) else {
|
||||||
anyhow::bail!("Patch `{patch_id}` not found");
|
anyhow::bail!("Patch `{patch_id}` not found");
|
||||||
};
|
};
|
||||||
patch.archive(&signer)?;
|
|
||||||
|
if undo {
|
||||||
|
patch.unarchive(&signer)?;
|
||||||
|
} else {
|
||||||
|
patch.archive(&signer)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2242,11 +2242,25 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Archive a patch.
|
/// Archive a patch.
|
||||||
pub fn archive<G: Signer>(&mut self, signer: &G) -> Result<EntryId, Error> {
|
pub fn archive<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
|
||||||
self.lifecycle(Lifecycle::Archived, signer)
|
self.lifecycle(Lifecycle::Archived, signer)?;
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark a patch as ready to be reviewed. Returns `false` if the patch was not a draft.
|
/// Mark an archived patch as ready to be reviewed again.
|
||||||
|
/// Returns `false` if the patch was not archived.
|
||||||
|
pub fn unarchive<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
|
||||||
|
if !self.is_archived() {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
self.lifecycle(Lifecycle::Open, signer)?;
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark a patch as ready to be reviewed.
|
||||||
|
/// Returns `false` if the patch was not a draft.
|
||||||
pub fn ready<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
|
pub fn ready<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
|
||||||
if !self.is_draft() {
|
if !self.is_draft() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
|
|
@ -2256,7 +2270,8 @@ where
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark an open patch as a draft. Returns `false` if the patch was not open and free of merges.
|
/// Mark an open patch as a draft.
|
||||||
|
/// Returns `false` if the patch was not open and free of merges.
|
||||||
pub fn unready<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
|
pub fn unready<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
|
||||||
if !matches!(self.state(), State::Open { conflicts } if conflicts.is_empty()) {
|
if !matches!(self.state(), State::Open { conflicts } if conflicts.is_empty()) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue