radicle-cli: use Did across CLI
The CLI commands and output use PublicKey, ActorId, and NodeId for peer identifiers. Instead Did should be standardised for use in CLI arguments and outputs. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
b57a4606f6
commit
5477a3615f
|
|
@ -7,7 +7,7 @@ $ rad auth
|
|||
Initializing your 🌱 profile and identity
|
||||
|
||||
ok Creating your 🌱 Ed25519 keypair...
|
||||
ok Profile z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi created.
|
||||
ok Profile did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi created.
|
||||
|
||||
Your radicle Node ID is z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi. This identifies your device.
|
||||
|
||||
|
|
@ -18,7 +18,8 @@ You can get the above information at all times using the `self` command:
|
|||
|
||||
```
|
||||
$ rad self
|
||||
ID z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
ID did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
Node ID z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
Key (hash) SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA
|
||||
Key (full) AAAAC3NzaC1lZDI1NTE5AAAAIHahWSBEpuT1ESZbynOmBNkLBSnR32Ar4woZqSV2YNH1
|
||||
Storage (git) [..]/storage
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ We want to add a new maintainer to the project to help out with the
|
|||
work.
|
||||
|
||||
```
|
||||
$ rad delegate add z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
$ rad delegate add did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
Added delegate 'did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG'
|
||||
ok Update successful!
|
||||
```
|
||||
|
|
@ -33,7 +33,7 @@ And finally, we no longer want to be part of the project so we pass on
|
|||
the torch and remove ourselves from the delegate set.
|
||||
|
||||
```
|
||||
$ rad delegate remove z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
$ rad delegate remove did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --to rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
Removed delegate 'did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi'
|
||||
ok Update successful!
|
||||
```
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ First off, we will create two proposals -- we can imagine two
|
|||
delegates creating proposals concurrently.
|
||||
|
||||
```
|
||||
$ rad id edit --title "Add Alice" --description "Add Alice as a delegate" --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
|
||||
$ rad id edit --title "Add Alice" --description "Add Alice as a delegate" --delegates did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
|
||||
ok Identity proposal '57332790a2eabc0b2fd8c7ff48c3579d5812d405' created 🌱
|
||||
title: Add Alice
|
||||
description: Add Alice as a delegate
|
||||
|
|
@ -47,7 +47,7 @@ Quorum Reached
|
|||
```
|
||||
|
||||
```
|
||||
$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --no-confirm
|
||||
$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --no-confirm
|
||||
ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' created 🌱
|
||||
title: Add Bob
|
||||
description: Add Bob as a delegate
|
||||
|
|
@ -294,7 +294,7 @@ Quorum Reached
|
|||
We can now update the proposal to have both keys in the delegates set:
|
||||
|
||||
```
|
||||
$ rad id update c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4 --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
|
||||
$ rad id update c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4 --delegates did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
|
||||
ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' updated 🌱
|
||||
ok Revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/6'
|
||||
title: Add Bob
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ delegate` command. For cases where `threshold > 1`, it is necessary to
|
|||
gather a quorum of signatures to update the Radicle identity. To do
|
||||
this, we use the `rad id` command.
|
||||
|
||||
Let's add Bob as a delegate using their key
|
||||
`z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn`.
|
||||
Let's add Bob as a delegate using their DID
|
||||
`did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn`.
|
||||
|
||||
```
|
||||
$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
|
||||
$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
|
||||
ok Identity proposal '06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39' created 🌱
|
||||
title: Add Bob
|
||||
description: Add Bob as a delegate
|
||||
|
|
|
|||
|
|
@ -22,20 +22,20 @@ others to work on. This is to ensure work is not duplicated.
|
|||
Let's assign ourselves to this one.
|
||||
|
||||
```
|
||||
$ rad assign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
$ rad assign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
```
|
||||
|
||||
It will now show in the list of issues assigned to us.
|
||||
|
||||
```
|
||||
$ rad issue list --assigned
|
||||
2b4650e3c66d568132034de0d02871a2fbf9c5b5 "flux capacitor underpowered" z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
2b4650e3c66d568132034de0d02871a2fbf9c5b5 "flux capacitor underpowered" did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
```
|
||||
|
||||
Note: this can always be undone with the `unassign` subcommand.
|
||||
|
||||
```
|
||||
$ rad unassign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
$ rad unassign 2b4650e3c66d568132034de0d02871a2fbf9c5b5 did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
```
|
||||
|
||||
Great, now we have communicated to the world about our car's defect.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::ffi::OsString;
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use radicle::prelude::Did;
|
||||
|
||||
use crate::terminal as term;
|
||||
use crate::terminal::args;
|
||||
|
|
@ -16,7 +17,7 @@ pub const HELP: args::Help = args::Help {
|
|||
usage: r#"
|
||||
Usage
|
||||
|
||||
rad assign <issue> <peer>
|
||||
rad assign <issue> <did>
|
||||
|
||||
Options
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ Options
|
|||
#[derive(Debug)]
|
||||
pub struct Options {
|
||||
pub id: issue::IssueId,
|
||||
pub peer: cob::ActorId,
|
||||
pub peer: Did,
|
||||
}
|
||||
|
||||
impl args::Args for Options {
|
||||
|
|
@ -36,7 +37,7 @@ impl args::Args for Options {
|
|||
|
||||
let mut parser = lexopt::Parser::from_args(args);
|
||||
let mut id: Option<issue::IssueId> = None;
|
||||
let mut peer: Option<cob::ActorId> = None;
|
||||
let mut peer: Option<Did> = None;
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
|
|
@ -52,12 +53,7 @@ impl args::Args for Options {
|
|||
|
||||
id = Some(val);
|
||||
} else if peer.is_none() {
|
||||
let val = val.to_string_lossy();
|
||||
let Ok(val) = cob::ActorId::from_str(&val) else {
|
||||
return Err(anyhow!("invalid peer ID '{}'", val));
|
||||
};
|
||||
|
||||
peer = Some(val);
|
||||
peer = Some(term::args::did(val)?);
|
||||
} else {
|
||||
return Err(anyhow!(arg.unexpected()));
|
||||
}
|
||||
|
|
@ -90,7 +86,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
cob::store::Error::NotFound(_, _) => anyhow!("issue not found '{}'", options.id),
|
||||
_ => err.into(),
|
||||
})?;
|
||||
issue.assign(vec![options.peer], &signer)?;
|
||||
issue.assign(vec![*options.peer], &signer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ pub fn init(options: Options) -> anyhow::Result<()> {
|
|||
|
||||
term::success!(
|
||||
"Profile {} created.",
|
||||
term::format::highlight(profile.id().to_string())
|
||||
term::format::highlight(profile.did().to_string())
|
||||
);
|
||||
|
||||
term::blank();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::str::FromStr;
|
|||
use anyhow::{anyhow, Context as _};
|
||||
|
||||
use radicle::identity::Id;
|
||||
use radicle_crypto::PublicKey;
|
||||
use radicle::prelude::Did;
|
||||
|
||||
use crate::terminal as term;
|
||||
use crate::terminal::args::{Args, Error, Help};
|
||||
|
|
@ -23,7 +23,7 @@ pub const HELP: Help = Help {
|
|||
usage: r#"
|
||||
Usage
|
||||
|
||||
rad delegate (add|remove) <public key> [--to <id>]
|
||||
rad delegate (add|remove) <did> [--to <id>]
|
||||
rad delegate list [<id>]
|
||||
|
||||
The `add` and `remove` commands are limited to managing delegates
|
||||
|
|
@ -47,8 +47,8 @@ pub enum OperationName {
|
|||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum Operation {
|
||||
Add { id: Option<Id>, key: PublicKey },
|
||||
Remove { id: Option<Id>, key: PublicKey },
|
||||
Add { id: Option<Id>, did: Did },
|
||||
Remove { id: Option<Id>, did: Did },
|
||||
List { id: Option<Id> },
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ impl Args for Options {
|
|||
let mut parser = lexopt::Parser::from_args(args);
|
||||
let mut id: Option<Id> = None;
|
||||
let mut op: Option<OperationName> = None;
|
||||
let mut key: Option<PublicKey> = None;
|
||||
let mut did: Option<Did> = None;
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
|
|
@ -81,27 +81,21 @@ impl Args for Options {
|
|||
|
||||
unknown => anyhow::bail!("unknown operation '{}'", unknown),
|
||||
},
|
||||
Value(val) if op.is_some() => {
|
||||
let val = val.to_string_lossy();
|
||||
|
||||
match op {
|
||||
Some(OperationName::Add) | Some(OperationName::Remove) => {
|
||||
if let Ok(val) = PublicKey::from_str(&val) {
|
||||
key = Some(val);
|
||||
} else {
|
||||
return Err(anyhow!("invalid Public Key '{}'", val));
|
||||
}
|
||||
}
|
||||
Some(OperationName::List) => {
|
||||
if let Ok(val) = Id::from_str(&val) {
|
||||
id = Some(val);
|
||||
} else {
|
||||
return Err(anyhow!("invalid Project ID '{}'", val));
|
||||
}
|
||||
}
|
||||
None => continue,
|
||||
Value(val) if op.is_some() => match op {
|
||||
Some(OperationName::Add) | Some(OperationName::Remove) => {
|
||||
did = Some(term::args::did(&val)?);
|
||||
}
|
||||
}
|
||||
Some(OperationName::List) => {
|
||||
// TODO: create args::project_id function
|
||||
let val = val.to_string_lossy();
|
||||
if let Ok(val) = Id::from_str(&val) {
|
||||
id = Some(val);
|
||||
} else {
|
||||
return Err(anyhow!("invalid Project ID '{}'", val));
|
||||
}
|
||||
}
|
||||
None => continue,
|
||||
},
|
||||
_ => return Err(anyhow!(arg.unexpected())),
|
||||
}
|
||||
}
|
||||
|
|
@ -110,11 +104,11 @@ impl Args for Options {
|
|||
OperationName::List => Operation::List { id },
|
||||
OperationName::Add => Operation::Add {
|
||||
id,
|
||||
key: key.ok_or_else(|| anyhow!("a delegate key must be provided"))?,
|
||||
did: did.ok_or_else(|| anyhow!("a delegate DID must be provided"))?,
|
||||
},
|
||||
OperationName::Remove => Operation::Remove {
|
||||
id,
|
||||
key: key.ok_or_else(|| anyhow!("a delegate key must be provided"))?,
|
||||
did: did.ok_or_else(|| anyhow!("a delegate DID must be provided"))?,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -127,8 +121,8 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let storage = &profile.storage;
|
||||
|
||||
match options.op {
|
||||
Operation::Add { id, key } => add::run(&profile, storage, get_id(id)?, key)?,
|
||||
Operation::Remove { id, key } => remove::run(&profile, storage, get_id(id)?, &key)?,
|
||||
Operation::Add { id, did } => add::run(&profile, storage, get_id(id)?, *did)?,
|
||||
Operation::Remove { id, did } => remove::run(&profile, storage, get_id(id)?, &did)?,
|
||||
Operation::List { id } => list::run(&profile, storage, get_id(id)?)?,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use anyhow::{anyhow, Context as _};
|
|||
use radicle::cob::identity::{self, Proposal, ProposalId, Proposals, Revision, RevisionId};
|
||||
use radicle::git::Oid;
|
||||
use radicle::identity::Identity;
|
||||
use radicle::prelude::Doc;
|
||||
use radicle::prelude::{Did, Doc};
|
||||
use radicle::storage::ReadStorage as _;
|
||||
use radicle_crypto::{PublicKey, Verified};
|
||||
use radicle_crypto::Verified;
|
||||
|
||||
use crate::terminal::args::{Args, Error, Help};
|
||||
use crate::terminal::{self as term, Interactive};
|
||||
|
|
@ -19,7 +19,7 @@ pub const HELP: Help = Help {
|
|||
Usage
|
||||
|
||||
rad id (update|edit) [--title|-t] [--description|-d]
|
||||
[--delegates <key>] [--threshold <num>]
|
||||
[--delegates <did>] [--threshold <num>]
|
||||
[--no-confirm]
|
||||
rad id list
|
||||
rad id (show|rebase) <id> [--rev <revision id>]
|
||||
|
|
@ -61,7 +61,7 @@ pub enum Operation {
|
|||
Edit {
|
||||
title: Option<String>,
|
||||
description: Option<String>,
|
||||
delegates: Vec<PublicKey>,
|
||||
delegates: Vec<Did>,
|
||||
threshold: Option<usize>,
|
||||
},
|
||||
Update {
|
||||
|
|
@ -69,7 +69,7 @@ pub enum Operation {
|
|||
rev: Option<RevisionId>,
|
||||
title: Option<String>,
|
||||
description: Option<String>,
|
||||
delegates: Vec<PublicKey>,
|
||||
delegates: Vec<Did>,
|
||||
threshold: Option<usize>,
|
||||
},
|
||||
Rebase {
|
||||
|
|
@ -121,7 +121,7 @@ impl Args for Options {
|
|||
let mut rev: Option<RevisionId> = None;
|
||||
let mut title: Option<String> = None;
|
||||
let mut description: Option<String> = None;
|
||||
let mut delegates: Vec<PublicKey> = Vec::new();
|
||||
let mut delegates: Vec<Did> = Vec::new();
|
||||
let mut threshold: Option<usize> = None;
|
||||
let mut interactive = Interactive::Yes;
|
||||
let mut show_revisions = false;
|
||||
|
|
@ -161,11 +161,8 @@ impl Args for Options {
|
|||
);
|
||||
}
|
||||
Long("delegates") => {
|
||||
let val = String::from(parser.value()?.to_string_lossy());
|
||||
delegates.push(
|
||||
PublicKey::from_str(&val)
|
||||
.map_err(|_| anyhow!("invalid Public Key '{}'", val))?,
|
||||
)
|
||||
let did = term::args::did(&parser.value()?)?;
|
||||
delegates.push(did);
|
||||
}
|
||||
Long("threshold") => {
|
||||
threshold = Some(parser.value()?.to_string_lossy().parse()?);
|
||||
|
|
@ -277,9 +274,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let proposed = {
|
||||
let mut proposed = previous.doc.clone();
|
||||
proposed.threshold = threshold.unwrap_or(proposed.threshold);
|
||||
proposed
|
||||
.delegates
|
||||
.extend(delegates.into_iter().map(|k| k.into()));
|
||||
proposed.delegates.extend(delegates);
|
||||
proposed
|
||||
};
|
||||
|
||||
|
|
@ -320,9 +315,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let proposed = {
|
||||
let mut proposed = revision.proposed.clone();
|
||||
proposed.threshold = threshold.unwrap_or(revision.proposed.threshold);
|
||||
proposed
|
||||
.delegates
|
||||
.extend(delegates.into_iter().map(|k| k.into()));
|
||||
proposed.delegates.extend(delegates);
|
||||
proposed
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::ffi::OsString;
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{anyhow, Context as _};
|
||||
use radicle::prelude::Did;
|
||||
|
||||
use crate::terminal as term;
|
||||
use crate::terminal::args::{Args, Error, Help};
|
||||
|
|
@ -22,7 +23,7 @@ Usage
|
|||
|
||||
rad issue
|
||||
rad issue delete <id>
|
||||
rad issue list [--assigned <key>]
|
||||
rad issue list [--assigned <did>]
|
||||
rad issue open [--title <title>] [--description <text>]
|
||||
rad issue react <id> [--emoji <char>]
|
||||
rad issue show <id>
|
||||
|
|
@ -38,7 +39,7 @@ Options
|
|||
pub struct Metadata {
|
||||
title: String,
|
||||
labels: Vec<Tag>,
|
||||
assignees: Vec<cob::ActorId>,
|
||||
assignees: Vec<Did>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, Eq)]
|
||||
|
|
@ -57,7 +58,7 @@ pub enum OperationName {
|
|||
pub enum Assigned {
|
||||
#[default]
|
||||
Me,
|
||||
Peer(cob::ActorId),
|
||||
Peer(Did),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
|
@ -135,10 +136,7 @@ impl Args for Options {
|
|||
}
|
||||
Long("assigned") | Short('a') if assigned.is_none() => {
|
||||
if let Ok(val) = parser.value() {
|
||||
let val = val.to_string_lossy();
|
||||
let Ok(peer) = cob::ActorId::from_str(&val) else {
|
||||
return Err(anyhow!("invalid peer ID '{}'", val));
|
||||
};
|
||||
let peer = term::args::did(&val)?;
|
||||
assigned = Some(Assigned::Peer(peer));
|
||||
} else {
|
||||
assigned = Some(Assigned::Me);
|
||||
|
|
@ -265,7 +263,11 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
&meta.title,
|
||||
description.trim(),
|
||||
meta.labels.as_slice(),
|
||||
meta.assignees.as_slice(),
|
||||
meta.assignees
|
||||
.into_iter()
|
||||
.map(cob::ActorId::from)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
&signer,
|
||||
)?;
|
||||
}
|
||||
|
|
@ -273,7 +275,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
Operation::List { assigned } => {
|
||||
let assignee = match assigned {
|
||||
Some(Assigned::Me) => Some(*profile.id()),
|
||||
Some(Assigned::Peer(id)) => Some(id),
|
||||
Some(Assigned::Peer(id)) => Some(id.into()),
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
|
@ -282,7 +284,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let (id, issue, _) = result?;
|
||||
let assigned: Vec<_> = issue.assigned().collect();
|
||||
|
||||
if Some(true) == assignee.map(|a| !assigned.contains(&&a)) {
|
||||
if Some(true) == assignee.map(|a| !assigned.contains(&Did::from(a))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,8 +77,11 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
fn all(profile: &Profile) -> anyhow::Result<()> {
|
||||
let mut table = term::Table::default();
|
||||
|
||||
let did = profile.did();
|
||||
table.push(["ID", &term::format::tertiary(did)]);
|
||||
|
||||
let node_id = profile.id();
|
||||
table.push(["ID", &term::format::tertiary(node_id)]);
|
||||
table.push(["Node ID", &term::format::tertiary(node_id)]);
|
||||
|
||||
let ssh_short = ssh::fmt::fingerprint(node_id);
|
||||
table.push(["Key (hash)", &term::format::tertiary(ssh_short)]);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::ffi::OsString;
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use radicle::prelude::Did;
|
||||
|
||||
use crate::terminal as term;
|
||||
use crate::terminal::args::{Args, Error, Help};
|
||||
|
|
@ -27,7 +28,7 @@ Options
|
|||
#[derive(Debug)]
|
||||
pub struct Options {
|
||||
pub id: issue::IssueId,
|
||||
pub peer: cob::ActorId,
|
||||
pub peer: Did,
|
||||
}
|
||||
|
||||
impl Args for Options {
|
||||
|
|
@ -36,7 +37,7 @@ impl Args for Options {
|
|||
|
||||
let mut parser = lexopt::Parser::from_args(args);
|
||||
let mut id: Option<issue::IssueId> = None;
|
||||
let mut peer: Option<cob::ActorId> = None;
|
||||
let mut peer: Option<Did> = None;
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
|
|
@ -52,12 +53,7 @@ impl Args for Options {
|
|||
|
||||
id = Some(val);
|
||||
} else if peer.is_none() {
|
||||
let val = val.to_string_lossy();
|
||||
let Ok(val) = cob::ActorId::from_str(&val) else {
|
||||
return Err(anyhow!("invalid peer ID '{}'", val));
|
||||
};
|
||||
|
||||
peer = Some(val);
|
||||
peer = Some(term::args::did(val)?);
|
||||
} else {
|
||||
return Err(anyhow!(arg.unexpected()));
|
||||
}
|
||||
|
|
@ -90,7 +86,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
cob::store::Error::NotFound(_, _) => anyhow!("issue '{}' not found", options.id),
|
||||
_ => err.into(),
|
||||
})?;
|
||||
issue.unassign(vec![options.peer], &signer)?;
|
||||
issue.unassign(vec![*options.peer], &signer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub fn finish(unparsed: Vec<OsString>) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn did(val: OsString) -> anyhow::Result<Did> {
|
||||
pub fn did(val: &OsString) -> anyhow::Result<Did> {
|
||||
let val = val.to_string_lossy();
|
||||
let Ok(peer) = Did::from_str(&val) else {
|
||||
if crypto::PublicKey::from_str(&val).is_ok() {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use crate::cob::thread;
|
|||
use crate::cob::thread::{CommentId, Thread};
|
||||
use crate::cob::{store, ActorId, ObjectId, OpId, TypeName};
|
||||
use crate::crypto::{PublicKey, Signer};
|
||||
use crate::prelude::Did;
|
||||
use crate::storage::git as storage;
|
||||
|
||||
/// Issue operation.
|
||||
|
|
@ -152,8 +153,8 @@ impl store::FromHistory for Issue {
|
|||
}
|
||||
|
||||
impl Issue {
|
||||
pub fn assigned(&self) -> impl Iterator<Item = &ActorId> {
|
||||
self.assignees.iter()
|
||||
pub fn assigned(&self) -> impl Iterator<Item = Did> + '_ {
|
||||
self.assignees.iter().map(Did::from)
|
||||
}
|
||||
|
||||
pub fn title(&self) -> &str {
|
||||
|
|
@ -516,21 +517,21 @@ mod test {
|
|||
|
||||
let id = issue.id;
|
||||
let issue = issues.get(&id).unwrap().unwrap();
|
||||
let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>();
|
||||
let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(1, assignees.len());
|
||||
assert!(assignees.contains(&assignee));
|
||||
assert!(assignees.contains(&Did::from(assignee)));
|
||||
|
||||
let mut issue = issues.get_mut(&id).unwrap();
|
||||
issue.assign([assignee_two], &signer).unwrap();
|
||||
|
||||
let id = issue.id;
|
||||
let issue = issues.get(&id).unwrap().unwrap();
|
||||
let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>();
|
||||
let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(2, assignees.len());
|
||||
assert!(assignees.contains(&assignee));
|
||||
assert!(assignees.contains(&assignee_two));
|
||||
assert!(assignees.contains(&Did::from(assignee)));
|
||||
assert!(assignees.contains(&Did::from(assignee_two)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -556,11 +557,11 @@ mod test {
|
|||
|
||||
let id = issue.id;
|
||||
let issue = issues.get(&id).unwrap().unwrap();
|
||||
let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>();
|
||||
let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(2, assignees.len());
|
||||
assert!(assignees.contains(&assignee));
|
||||
assert!(assignees.contains(&assignee_two));
|
||||
assert!(assignees.contains(&Did::from(assignee)));
|
||||
assert!(assignees.contains(&Did::from(assignee_two)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -641,10 +642,10 @@ mod test {
|
|||
|
||||
let id = issue.id;
|
||||
let issue = issues.get(&id).unwrap().unwrap();
|
||||
let assignees: Vec<_> = issue.assigned().cloned().collect::<Vec<_>>();
|
||||
let assignees: Vec<_> = issue.assigned().collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(1, assignees.len());
|
||||
assert!(assignees.contains(&assignee_two));
|
||||
assert!(assignees.contains(&Did::from(assignee_two)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use crate::crypto::ssh::agent::Agent;
|
|||
use crate::crypto::ssh::{keystore, Keystore, Passphrase};
|
||||
use crate::crypto::{PublicKey, Signer};
|
||||
use crate::node;
|
||||
use crate::prelude::Did;
|
||||
use crate::storage::git::transport;
|
||||
use crate::storage::git::Storage;
|
||||
|
||||
|
|
@ -103,6 +104,10 @@ impl Profile {
|
|||
&self.public_key
|
||||
}
|
||||
|
||||
pub fn did(&self) -> Did {
|
||||
Did::from(self.public_key)
|
||||
}
|
||||
|
||||
pub fn signer(&self) -> Result<Box<dyn Signer>, Error> {
|
||||
if let Some(passphrase) = env::read_passphrase() {
|
||||
let signer = keystore::MemorySigner::load(&self.keystore, passphrase)?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue