remote-helper: Create patch drafts via `git push`

This is now possible via the `-o patch.draft` push option.
This commit is contained in:
Alexis Sellier 2023-06-07 15:02:05 +02:00
parent 6bbdc574f0
commit 547fdcc03b
No known key found for this signature in database
3 changed files with 49 additions and 22 deletions

View File

@ -7,9 +7,11 @@ $ git commit -a -m "Nothing to see here.." -q --allow-empty
To open a patch in draft mode, we use the `--draft` option:
```
$ rad patch open --draft -m "Nothing yet" --quiet
c639a0f9895a0fdf2ba2d04533290937cb6fd2f7
``` (stderr)
$ git push -o patch.draft -o patch.message="Nothing yet" rad HEAD:refs/patches
✓ Patch c639a0f9895a0fdf2ba2d04533290937cb6fd2f7 drafted
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
* [new reference] HEAD -> refs/patches
```
We can confirm it's a draft by running `show`:

View File

@ -54,10 +54,12 @@ pub enum Error {
List(#[from] list::Error),
}
#[derive(Debug, Default)]
#[derive(Debug, Default, Clone)]
pub struct Options {
/// Don't sync after push.
no_sync: bool,
/// Open patch in draft mode.
draft: bool,
/// Patch message.
message: cli::patch::Message,
}
@ -108,6 +110,7 @@ pub fn run(profile: radicle::Profile) -> Result<(), Error> {
match *args {
["sync"] => opts.no_sync = false,
["no-sync"] => opts.no_sync = true,
["patch.draft"] => opts.draft = true,
_ => {
let args = args.join(" ");

View File

@ -175,7 +175,7 @@ pub fn run(
let working = git::raw::Repository::open(working)?;
if dst == &*rad::PATCHES_REFNAME {
patch_open(opts.message.clone(), src, &nid, &working, stored, &signer)
patch_open(src, &nid, &working, stored, &signer, opts.clone())
} else {
let dst = git::Qualified::from_refstr(dst)
.ok_or_else(|| Error::InvalidQualifiedRef(dst.clone()))?;
@ -184,7 +184,6 @@ pub fn run(
let oid = git::Oid::from_str(oid)?;
patch_update(
opts.message.clone(),
src,
&dst,
*force,
@ -193,6 +192,7 @@ pub fn run(
&working,
stored,
&signer,
opts.clone(),
)
} else {
push(src, &dst, *force, &nid, &working, stored, &signer)
@ -237,12 +237,12 @@ pub fn run(
/// Open a new patch.
fn patch_open<G: Signer>(
msg: cli::patch::Message,
src: &git::RefStr,
nid: &NodeId,
working: &git::raw::Repository,
stored: &storage::git::Repository,
signer: &G,
opts: Options,
) -> Result<(), Error> {
let reference = working.find_reference(src.as_str())?;
let commit = reference.peel_to_commit()?;
@ -259,26 +259,48 @@ fn patch_open<G: Signer>(
let (_, target) = stored.canonical_head()?;
let base = stored.backend.merge_base(*target, commit.id())?;
let (title, description) =
cli::patch::get_create_message(msg, &stored.backend, &base.into(), &commit.id().into())?;
let (title, description) = cli::patch::get_create_message(
opts.message,
&stored.backend,
&base.into(),
&commit.id().into(),
)?;
let mut patches = patch::Patches::open(stored)?;
let result = match patches.create(
&title,
&description,
patch::MergeTarget::default(),
base,
commit.id(),
&[],
signer,
) {
let patch = if opts.draft {
patches.draft(
&title,
&description,
patch::MergeTarget::default(),
base,
commit.id(),
&[],
signer,
)
} else {
patches.create(
&title,
&description,
patch::MergeTarget::default(),
base,
commit.id(),
&[],
signer,
)
};
let result = match patch {
Ok(patch) => {
let action = if patch.is_draft() {
"drafted"
} else {
"opened"
};
let patch = patch.id;
eprintln!(
"{} Patch {} opened",
"{} Patch {} {action}",
cli::format::positive(""),
cli::format::tertiary(patch)
cli::format::tertiary(patch),
);
// Create long-lived patch head reference, now that we know the Patch ID.
@ -339,7 +361,6 @@ fn patch_open<G: Signer>(
/// Update an existing patch.
#[allow(clippy::too_many_arguments)]
fn patch_update<G: Signer>(
msg: cli::patch::Message,
src: &git::RefStr,
dst: &git::Qualified,
force: bool,
@ -348,6 +369,7 @@ fn patch_update<G: Signer>(
working: &git::raw::Repository,
stored: &storage::git::Repository,
signer: &G,
opts: Options,
) -> Result<(), Error> {
let reference = working.find_reference(src.as_str())?;
let commit = reference.peel_to_commit()?;
@ -366,7 +388,7 @@ fn patch_update<G: Signer>(
return Ok(());
}
let message = cli::patch::get_update_message(
msg,
opts.message,
&stored.backend,
patch.latest().1,
&commit.id().into(),