The "seeds" command does only take a repository ID, and
carries the implicit assumption that the namespace with the same public
key as the Node ID of the receiving `radicle-node` process should be
used as reference for determining whether other nodes are in sync,
but no other namespace.
In the spirit of separating user and node identity, relax this, so that
the command also carries the public keys relative to which the sync
status should be computed. This allows to inspect sync status for
arbitrary namespaces via command.
For now, this feature is not exposed to the CLI, but `rad sync status`
always passes the public key of the active profile.
The "announce references" command does only take a repository ID, and
carries the implicit assumption that the namespace with the same public
key as the Node ID of the receiving `radicle-node` process should be
announced, but no other namespace.
In the spirit of separating user and node identity, relax this, so that
the command also carries the public keys for which the announcement
should be made. This allows to announce arbitrary namespaces out of
storage via command.
For now, this feature is not exposed to the CLI, but rather:
- `rad sync` always announce for the public key of the active profile.
- `git-remote-rad` ditto, as it calls the same codepath.
A rewrite of the argument parsing portions of the `rad issue` subcommand
using `clap` instead of `lexopt`.
From a user's perspective, the look-and-feel of `rad issue` does not
change much. Although, the most prominent change is to rely on
`clap`'a default error template which looks a bit different from what we
use usually (`error: ...` vs. `✗ Error: ...`).
Leaving the above restriction aside, subcommand mis-usage is
reported more verbosely.
Also configure `clap` to use colored output for errors and help pages.
In help output, headers are colored with `Magenta` to match the overall
CLI styling.
Specify a type that captures the different actions that can be take
when using the `comment` command: `Comment`, `Reply`, and `Edit`.
Move the functions that run the corresponding actions into a `comment`
module.
To preserve the "default command" behaviour being `rad issue list`,
e.g., `rad issue --solved` behaving like `rad issue list --solved`,
introduce a new type `EmptyArgs`to also parse arguments without a
subcommand. In case no subcommand was parsed, construct `Command::List`
with from `EmptyArgs`.
Co-authored-by: Matthias Beyer <mail@beyermatthias.de>
Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
Co-authored-by: Erik Kundt <erik@zirkular.io>
Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
The implementation of `Keystore` requires a particular layout and naming
of keys. This is a rather strong limitation. Lift it and allow
specifying an arbitrary path for the secret and public key.
As it is possible to derive the public key from the secret key, make
the public key in `Keystore` optional. Also allow constructing
`MemorySigner` can now be initialized without a public key, by
deriving it.
When run with a secret and public key that do not cryptographically
match, `fn radicle_cli::terminal::io::signer` would prompt the user
for a password to unlock the secret key, and then carry on with a
mismatching key pair.
Fix this by verifying that the keys match in `MemorySigner::load`
and only swallow errors initializing the signer in cases where
prompting for a password makes sense. It does not make sense in the
case of mismatched keys.
The output of this command is confusing. It is not clear which of the
hashes printed is that of the revision and which one is the respective
head commit.
Further, the hash is omitted on the initial revision, adding confusion.
Further, the terminology of "revised" vs. "updated" is confusing.
This rewrites `timeline.rs` to drop the distinction between various
revisions (in wording, the small icon is still different) and cleans up
the output.
Attention is paid to alignment of the output. Now all verbs of updates
("accepted", "rejected", "reviewed", "merged") are aligned, and authors
("… by …") are also aligned.
The rewrite itself is not for better code quality or readability.
Note that all the code in this file only accessed via one `fn` by one
callsite in the implementation of `rad patch`.
The `--setup-signing` flag is a no-op when combined with `--existing`
and errors on bare repositories.
Make it effective in combination with `--existing` and also rewrite it
to support bare repositories, gracefully falling back to just avoid
writing to `.gitsigners`.
`radicle::run` interprets the `Output` returned by the `git`
process. However, depending on the application we have different
requirements for interpreting the output, e.g., how to handle errors.
Make `radicle::run` not interpret `Output`, but move this
logic to the respective binary crates (`radicle-remote-helper` and
`radicle-cli`).
The `verbosity` option is ignored, which makes it more difficult to
obtain debugging information if the "internal" push, i.e., the
`git push` invocation by `git-remote-rad` fails.
Provide two types for verbosity, and wire them up.
Rewrite module declarations that use the `#[path="…"]` annotation
to the more idomatic `pub mod …` + `pub use …` forms.
For the "self" module, that is not possible because `self` is an
identifier in Rust, and also `r#self` is not admissable as a raw
identifier, so stick to `rad_self`.
Files in submodules were patched as appropriate.
To get to a point of separating the users' identity from the node, then the `rad
self` command should not display information related to the node so prominently.
The relation between `rad` and `radicle-node` is really similar to that between
`rad` and SSH Agent. They communicate via socket. So, when this connection is
successful, it is printed, but not more.
There may be some re-learning for users here, but it is worth the improvement.
Note that the information being removed here is available via `rad node status`
(see previous commit).
If we ever want to disentangle the users' identity from the node, then
the `rad node` commands must learn to print the information related to
the node, so here we go.
As a library crate, it is bad to return such generic errors.
To get there, errors from `inquire` are downcasted.
This allowed to clean up the public interface of `radicle-term`, so that
it does also not leak the `inquire::InquireError` in its public API.
I was greeted by `rad patch redact` with
called `Result::unwrap()` on an `Err` value:
Error { code: None, message: Some("failed to convert") }
stack backtrace:
[…]
3: core::result::Result<T,E>::unwrap
at …/rust-1.88.0/lib/rustlib/src/rust/library/core/src/result.rs:1137:23
4: sqlite::cursor::Row::read
at …/index.crates.io-1949cf8c6b5b557f/sqlite-0.32.0/src/cursor.rs:136:9
5: radicle::cob::patch::cache::query::find_by_revision
at ./crates/radicle/src/cob/patch/cache.rs:624:65
6: <… as radicle::cob::patch::cache::Patches>::find_by_revision
at ./crates/radicle/src/cob/patch/cache.rs:553:9
7: radicle_cli::commands::rad_patch::redact::run
at ./crates/radicle-cli/src/commands/patch/redact.rs:23:9
8: radicle_cli::commands::rad_patch::run
at ./crates/radicle-cli/src/commands/patch.rs:1026:13
[…]
It turns out that `sqlite::cursor::Row::read` is the panicky version of
`sqlite::cursor::Row::try_read` (which returns a `Result`).
While it is somewhat rare that SQLite reads fail, it is not unheard of.
In `radicle-cli` it might not be critical, but also `radicle-protocol`
and `radicle-fetch` are affected, and they could potentially panic a
`radicle-node` process.
Use `try_read` instead, and propagate down the error handling.
Microsoft Windows has Universal Naming Convention (UNC) paths, see
<https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths>
The Rust standard library normalizes paths to this form when calling
`std::fs::canonicalize`, see
<https://doc.rust-lang.org/std/fs/fn.canonicalize.html>
However, some programs, do not parse these paths correctly, including
our ally `git`:
$ git clone \\?\C:\Users\lorenz\tmp
Cloning into 'tmp'...
ssh: Could not resolve hostname \\\\?\\c: No such host is known.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
The `dunce` crate solves the problem of having to deal with
normalization and avoiding weird UNC paths for us. Note that on
non-Windows platforms, it *behaves exactly like*
`std::fs::canonicalize`!