Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Create `rad patch ready` command
Alexis Sellier committed 3 years ago
commit 12a91bd0ae5f5de3a096ab4aaac735fe61e8a6e9
parent f111681dd6fa9f3bf4cba09db33946e7dc6cab55
5 files changed +162 -0
added radicle-cli/examples/rad-patch-draft.md
@@ -0,0 +1,69 @@
+
Let's say we have some changes in a branch:
+

+
```
+
$ git checkout -b cloudhead/draft
+
$ 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
+
3bdbfc4f85b942293ba7adb8e47bf3202a602e8b
+
```
+

+
We can confirm it's a draft by running `show`:
+

+
```
+
$ rad patch show 3bdbfc4f85b942293ba7adb8e47bf3202a602e8b
+
╭─────────────────────────────────────────────────────────────────────────────────────────╮
+
│ Title     Nothing yet                                                                   │
+
│ Patch     3bdbfc4f85b942293ba7adb8e47bf3202a602e8b                                      │
+
│ Author    did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi                      │
+
│ Head      2a465832b5a76abe25be44a3a5d224bbd7741ba7                                      │
+
│ Branches  cloudhead/draft                                                               │
+
│ Commits   ahead 1, behind 0                                                             │
+
│ Status    draft                                                                         │
+
├─────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [   ...    ] │
+
╰─────────────────────────────────────────────────────────────────────────────────────────╯
+
```
+

+
Once the patch is ready for review, we can use the `ready` command:
+

+
```
+
$ rad patch ready 3bdbfc4f85b942293ba7adb8e47bf3202a602e8b
+
```
+

+
```
+
$ rad patch show 3bdbfc4f85b942293ba7adb8e47bf3202a602e8b
+
╭─────────────────────────────────────────────────────────────────────────────────────────╮
+
│ Title     Nothing yet                                                                   │
+
│ Patch     3bdbfc4f85b942293ba7adb8e47bf3202a602e8b                                      │
+
│ Author    did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi                      │
+
│ Head      2a465832b5a76abe25be44a3a5d224bbd7741ba7                                      │
+
│ Branches  cloudhead/draft                                                               │
+
│ Commits   ahead 1, behind 0                                                             │
+
│ Status    open                                                                          │
+
├─────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [   ...    ] │
+
╰─────────────────────────────────────────────────────────────────────────────────────────╯
+
```
+

+
If for whatever reason, it needed to go back into draft mode, we could use
+
the `--undo` flag:
+

+
```
+
$ rad patch ready --undo 3bdbfc4f85b942293ba7adb8e47bf3202a602e8b
+
$ rad patch show 3bdbfc4f85b942293ba7adb8e47bf3202a602e8b
+
╭─────────────────────────────────────────────────────────────────────────────────────────╮
+
│ Title     Nothing yet                                                                   │
+
│ Patch     3bdbfc4f85b942293ba7adb8e47bf3202a602e8b                                      │
+
│ Author    did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi                      │
+
│ Head      2a465832b5a76abe25be44a3a5d224bbd7741ba7                                      │
+
│ Branches  cloudhead/draft                                                               │
+
│ Commits   ahead 1, behind 0                                                             │
+
│ Status    draft                                                                         │
+
├─────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [   ...    ] │
+
╰─────────────────────────────────────────────────────────────────────────────────────────╯
modified radicle-cli/src/commands/patch.rs
@@ -10,6 +10,8 @@ mod create;
mod delete;
#[path = "patch/list.rs"]
mod list;
+
#[path = "patch/ready.rs"]
+
mod ready;
#[path = "patch/show.rs"]
mod show;
#[path = "patch/update.rs"]
@@ -45,6 +47,7 @@ Usage
    rad patch update <patch-id> [<option>...]
    rad patch checkout <patch-id> [<option>...]
    rad patch delete <patch-id> [<option>...]
+
    rad patch ready <patch-id> [--undo] [<option>...]

Show options

@@ -66,6 +69,10 @@ List options
        --merged               Show only merged patches
        --open                 Show only open patches (default)

+
Ready options
+

+
        --undo                 Convert a patch back to a draft
+

Other options

        --help                 Print help
@@ -80,6 +87,7 @@ pub enum OperationName {
    Archive,
    Delete,
    Checkout,
+
    Ready,
    #[default]
    List,
}
@@ -103,6 +111,10 @@ pub enum Operation {
    Archive {
        patch_id: Rev,
    },
+
    Ready {
+
        patch_id: Rev,
+
        undo: bool,
+
    },
    Delete {
        patch_id: Rev,
    },
@@ -138,6 +150,7 @@ impl Args for Options {
        let mut filter = Some(patch::State::Open);
        let mut diff = false;
        let mut draft = false;
+
        let mut undo = false;
        let mut quiet = false;

        while let Some(arg) = parser.next()? {
@@ -187,6 +200,11 @@ impl Args for Options {
                    diff = true;
                }

+
                // Ready options.
+
                Long("undo") if op == Some(OperationName::Ready) => {
+
                    undo = true;
+
                }
+

                // List options.
                Long("all") => {
                    filter = None;
@@ -217,6 +235,7 @@ impl Args for Options {
                    "d" | "delete" => op = Some(OperationName::Delete),
                    "c" | "checkout" => op = Some(OperationName::Checkout),
                    "a" | "archive" => op = Some(OperationName::Archive),
+
                    "y" | "ready" => op = Some(OperationName::Ready),
                    unknown => anyhow::bail!("unknown operation '{}'", unknown),
                },
                Value(val)
@@ -226,6 +245,7 @@ impl Args for Options {
                            Some(OperationName::Update),
                            Some(OperationName::Delete),
                            Some(OperationName::Archive),
+
                            Some(OperationName::Ready),
                            Some(OperationName::Checkout),
                        ]
                        .contains(&op) =>
@@ -262,6 +282,10 @@ impl Args for Options {
            OperationName::Checkout => Operation::Checkout {
                patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
            },
+
            OperationName::Ready => Operation::Ready {
+
                patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
+
                undo,
+
            },
        };

        Ok((
@@ -336,6 +360,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
            let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
            archive::run(&repository, &profile, &patch_id)?;
        }
+
        Operation::Ready { ref patch_id, undo } => {
+
            let patch_id = patch_id.resolve::<PatchId>(&repository.backend)?;
+
            ready::run(&repository, &profile, &patch_id, undo)?;
+
        }
        Operation::Delete { patch_id } => {
            let patch_id = patch_id.resolve(&repository.backend)?;
            delete::run(&repository, &profile, &patch_id)?;
added radicle-cli/src/commands/patch/ready.rs
@@ -0,0 +1,25 @@
+
use super::*;
+

+
use radicle::cob::patch;
+
use radicle::prelude::*;
+
use radicle::storage::git::Repository;
+

+
pub fn run(
+
    repository: &Repository,
+
    profile: &Profile,
+
    patch_id: &PatchId,
+
    undo: bool,
+
) -> anyhow::Result<()> {
+
    let signer = term::signer(profile)?;
+
    let mut patches = patch::Patches::open(repository)?;
+
    let Ok(mut patch) = patches.get_mut(patch_id) else {
+
        anyhow::bail!("Patch `{patch_id}` not found");
+
    };
+

+
    if undo {
+
        patch.unready(&signer)?;
+
    } else {
+
        patch.ready(&signer)?;
+
    }
+
    Ok(())
+
}
modified radicle-cli/tests/commands.rs
@@ -272,6 +272,26 @@ fn rad_patch() {
}

#[test]
+
fn rad_patch_draft() {
+
    let mut environment = Environment::new();
+
    let profile = environment.profile("alice");
+
    let working = tempfile::tempdir().unwrap();
+
    let home = &profile.home;
+

+
    // Setup a test repository.
+
    fixtures::repository(working.path());
+

+
    test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
+
    test(
+
        "examples/rad-patch-draft.md",
+
        working.path(),
+
        Some(home),
+
        [],
+
    )
+
    .unwrap();
+
}
+

+
#[test]
fn rad_rm() {
    let mut environment = Environment::new();
    let profile = environment.profile("alice");
modified radicle/src/cob/patch.rs
@@ -980,6 +980,26 @@ impl<'a, 'g> PatchMut<'a, 'g> {
        self.lifecycle(State::Archived, signer)
    }

+
    /// 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> {
+
        if self.state() != State::Draft {
+
            return Ok(false);
+
        }
+
        self.lifecycle(State::Open, signer)?;
+

+
        Ok(true)
+
    }
+

+
    /// Mark an open patch as a draft. Returns `false` if the patch was not open.
+
    pub fn unready<G: Signer>(&mut self, signer: &G) -> Result<bool, Error> {
+
        if self.state() != State::Open {
+
            return Ok(false);
+
        }
+
        self.lifecycle(State::Draft, signer)?;
+

+
        Ok(true)
+
    }
+

    /// Tag a patch.
    pub fn tag<G: Signer>(
        &mut self,