Commit Graph

2602 Commits

Author SHA1 Message Date
Lorenz Leutgeb 8c1073b9c9 cli/publish: Use clap 2025-10-09 10:52:21 +02:00
Lorenz Leutgeb 7effa7c64c
node: Report sync status for given namespaces
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.
2025-10-09 07:55:11 +02:00
Lorenz Leutgeb 9689de9af0
node: Allow announcing refs for given public keys
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.
2025-10-09 07:55:10 +02:00
Lorenz Leutgeb 4dbb022d22
radicle/node: Create submodule "command"
Purely for better overview, keeping backwards
compatibility with re-exports.
2025-10-08 23:58:41 +02:00
Lorenz Leutgeb 8e7d193202
radicle: Update `CHANGELOG.md` for next iteration 2025-10-08 23:58:41 +02:00
Lorenz Leutgeb 7b8da0e72f cli/fork: Use clap 2025-10-08 23:31:50 +02:00
Lorenz Leutgeb 3992d519c3 cli/clone: Use clap 2025-10-08 15:52:16 +02:00
Lorenz Leutgeb 7c89045ea0 cli/debug: Use clap 2025-10-08 15:30:18 +02:00
Erik Kundt 2e77d5ef4d cli/block: Improve example values for target argument
This visual representation follows the one that `clap` is generating
for defaults and possible values.
2025-10-07 15:01:57 +02:00
Lorenz Leutgeb 6d698bb794 cli/block: Use clap 2025-10-07 14:20:13 +02:00
Fintan Halpenny ed5a68c1d7 node: mark modules as private
In an effort to reduce the change of version numbers, dependents of
`radicle-node` should not need to know about the modules:
- `control`
- `wire`
- `worker`

These are internal to the `radicle-node` running, and none of its dependents
accessed them.

This resulted in removing two unused type aliases.
2025-10-06 18:57:30 +02:00
Fintan Halpenny 59e09078bb radicle: mark `CheckoutError` as `non_exhaustive`
Recently, this error enum was changed. To ensure it does not cause crate version
changes, in the future, mark it as `non_exhaustive`.
2025-10-06 18:57:30 +02:00
Fintan Halpenny 5b260964cb crypto: mark errors as `non_exhaustive`
To improve crate version churn, mark the error types as `non_exhaustive`.
This removes the need to change the version number of the crate when adding a
new variant.

Note that these errors are never matched on, so no other code is changed in
dependent crates.
2025-10-06 18:57:30 +02:00
Lorenz Leutgeb 30908dcf48 radicle/git/canonical: Actually use qualified refs
Some tests actually do not use qualified patterns. The removed lines
*should* not compile because the `qualified_pattern!` proc macro
*should* validate the string literals at compile time, but it contains
a bug and actually does not assert well-formedness of qualified
refspec patterns. Rectify.
2025-10-06 17:31:12 +01:00
Fintan Halpenny ee041d8d06 crates: bump for release
- `radicle-term`: 0.15.0 -> 0.16.0
- `radicle-node`: 0.15.0 -> 0.16.0
- `radicle-fetch`: 0.15.0 -> 0.16.0
- `radicle-crypto`: 0.13.0 -> 0.14.0
- `radicle-cli`: 0.16.0 -> 0.17.0
- `radicle`: 0.19.0 -> 0.20.0
- `radicle-cob`: 0.16.0 -> 0.17.0
- `radicle-remote-helper`: 0.13.0 -> 0.14.0
- `radicle-protocol`: 0.3.0 -> 0.4.0
- `radicle-systemd`: 0.10.0 -> 0.11.0
2025-10-06 16:36:30 +01:00
Lorenz Leutgeb 2149770a4b
storage: Rewrite temporary repositories for clones
On Windows, all attempts to clone repositories failed with

    Fetch failed for rad:… from z6Mk…: Access is denied. (os error 5)

The reason is that, other than Unix-like systems, it forbids that
directories that are in use are moved.

To improve the situation, take back control over what is moved and
removed exactly by implementing `cleanup` instead of relying
on `impl Drop for tempfile::TempDir`.

A new type `TempRepository` is introduced to capture a repository that can be
used temporarily, and either cleaned up on failure, or moved on success.
This `TempRepository` can be constructed using `Storage::temporary_repository` –
renamed from `Storage::lock_repository` since it is only creating a temporary
resource and not locking it.

In the future (once Rust 1.89 is a little less cutting edge and more
widely available), we may opt for actual locking via
`std::fs::File::lock`.
2025-10-06 11:52:42 +02:00
Lorenz Leutgeb 31a7d3bd3f
fetch: add `Handle::into_inner`
Adds an `into_inner` method to deconstruct the `Handle` back into the underlying
repository type.
2025-10-06 11:52:42 +02:00
Fintan Halpenny e40fe86ff8 fetch: use `AsRef<Repository>`
Allow the fetch interface to accept anything that implements
`AsRef<Repository>`. This allows flexibility in the types that the `Handle` can
accept.

This change is motivated by wanting to introduce a type that is a temporary
repository that wraps a `Repository`.
2025-10-06 11:52:42 +02:00
Fintan Halpenny a163f4e939 fetch: refactor repository access
The interface of the `Handle` has two methods: `Handle::repository` and
`Handle::repository_mut`. However, the calling logic would always access the
`Handle::repo` field.

This is cleaned up by making this field private, and using the
`Handle::repository` method instead. There were no calls to `repository_mut`,
and so the method was removed.
2025-10-06 11:52:42 +02:00
Lorenz Leutgeb 5caa7b302a remote-helper: Check base when matching revisions
It is impossible to preserve the head of a revision and only change
the base of same revision via push.

Strenghthen the precondition for skipping updates to also consider the
base commit.
2025-10-03 11:30:22 +01:00
Lorenz Leutgeb 9bb136105c remote-helper: Only update patch after evaluating base
Without quorum for the default branch, the remote helper would report
an error, suggesting that the patch was not updated, while,
inconsistently, actually updating the ref in storage without creating
a new revision.

    $ git push …
    To rad://z…5/z…z
    …
     ! [remote rejected]       612… -> patches/a77… (…)
    error: failed to push some refs to 'rad://z…5/z…z'
    …
    $ git ls-remote rad://z…5/z…z
    612…        refs/heads/patches/a77…

This is very confusing.

Fix this by using a temporary reference name that is different from the
reference name that the patch would use, implementing cleanup via
`Drop`.

While at it, also move the logic into `patch_base` and share it
between `patch_open` and `patch_update`. Computation of the canonical
head via `stored.canonical_head` is moved to a branch that is only
taken if the user did not specify a base explicitly. This allows to
update patches even when there is no quorum for the default branch.
2025-10-03 11:30:22 +01:00
Lorenz Leutgeb 5cd016b587 radicle-systemd: Guard `mod listen` for Unix
This crate does not build on Windows, because there is a Unix-only `use`
in `mod listen`. To get the crate to build, guard the module
appropriately.
2025-10-02 15:46:56 +01:00
Lorenz Leutgeb 0095fdc585 flake: Keep `crates/**/*.txt` files for build
Fix builds broken due to `include_str!` failing to read a text file.
2025-10-02 15:45:22 +01:00
Lorenz Leutgeb 9954a79490
flake: Add binary cache configuration
Advertise our own binary cache a bit more.
2025-10-02 13:04:28 +02:00
Lorenz Leutgeb 9c8ab7fa62
fetch: Rewrite `git::repository::direct`
This function (and the helpers `ancestry` and `find_and_peel`) are
eagerly peeling to commits, leading to updates of tags that target the
same commit to be missed.

For example, there could be tag two tag objects with *different* OIDs
A and B, from *different* authors, using *different* tag names, signed
with *different* secret keys, and both pointing to *the same* commit C.

The implementation would consider A and B to be the same, just becuase
A and B both peel to C, skipping the update.

This is counterintuitive, and when combined with canonical references
can be quite confusing.

Change this to only reason about an ancestry if the two objects in
question really both are commits directly. Otherwise, treat cases where
no structure can be used as ancestry similarly to non-fast-forward
updates.
2025-10-02 12:31:38 +02:00
Lorenz Leutgeb d9ce078d56 protocol: Decrease log-level for logging ping/pong
When logging writes, use a lower more verbose level for ping and pong,
as these messages are quite noisy.
2025-10-02 10:47:29 +01:00
Lorenz Leutgeb 474b97950b
node/log: Define syslog identifier
The argument passed to `fn logger` would only be used as a fallback.
Make it required to pass an identifier, as this is a good practice.
2025-10-01 16:46:46 +02:00
Lorenz Leutgeb ee49e28766 cli/unfollow: Use clap 2025-10-01 14:36:39 +02:00
Lorenz Leutgeb 6fb1ebec45 cli/clean: Use clap 2025-10-01 14:12:22 +02:00
Lorenz Leutgeb 753b7aef93 cli/path: Use clap 2025-10-01 13:04:28 +02:00
Fintan Halpenny 4787b53b1e CHANGELOG: Radicle 1.5.0 2025-09-30 19:13:31 +02:00
Fintan Halpenny 8bc578bfa8 build/release: missed updating the symlink 2025-09-30 19:10:54 +02:00
Lorenz Leutgeb 01f9f3fcd4 cli/unseed: Use clap 2025-09-30 15:13:09 +02:00
Lorenz Leutgeb 80bc95269b
cli/stats: Use clap 2025-09-29 16:44:18 +02:00
Lorenz Leutgeb f1c7c98607
cli/issue: Move definition of "about" to args 2025-09-28 19:47:50 +02:00
Christopher Fredén c7bff28452 cli/issue: Use clap
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>
2025-09-28 18:02:55 +02:00
Lorenz Leutgeb 675a0f81d9
cli: Depend on clap 2025-09-28 18:02:55 +02:00
Lorenz Leutgeb 5a958b5ebd
cli/test: Output of `rad --help`
With migration subcommands to `clap` planned one-by-one,
prepare this to catch regressions.
2025-09-28 18:02:19 +02:00
Lorenz Leutgeb 22720e718b node: Make location of secret key configurable
With this change, the location of the secret SSH key can be configured
through `${RAD_HOME}/config.json` so that the node key does not have to
be placed under `${RAD_HOME}/keys` anymore.

Further, there is now an option to override `config.json` directly when
executing `radicle-node` via the command line argument
`--secret`.

The primary motivation is more flexible deployments, for example
leveraging external secret management solutions, like
<https://systemd.io/CREDENTIALS/>.

The secret key is fingerprinted by taking the fingerprint of the public
key corresponding to the secret key. This allows to detect when the
secret key changes.
2025-09-26 13:03:57 +01:00
Lorenz Leutgeb 5887edf93b
crypto/ssh/keystore: Explicit paths
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.
2025-09-26 13:21:38 +02:00
Lorenz Leutgeb 9e1d6b1feb radicle: Detect current repository using `jj`
When using Jujutsu and a non-colocated Git repository, the detection
using `git2` directly fails (just as `git` in a shell would fail)
because there is no `.git` directory found by traversing up the
filesystem hierarchy.

Add an invocation of `jj git root` as a fallback.
2025-09-26 12:03:01 +01:00
Lorenz Leutgeb abc963f2f2 radicle-cli/tests: Add `rad_jj_patch` 2025-09-26 12:03:01 +01:00
Lorenz Leutgeb 731688d3f2 flake: Install Jujutsu for testing 2025-09-26 12:03:01 +01:00
Lorenz Leutgeb fd5043d572 radicle-cli-test: Prepare testing with `jj`
Most of this is taken from Jujutsu's own testing setup, see:
98d884827e/cli/tests/common/test_environment.rs (L106-L150)

Not all features are preserved, but this is good enough.
2025-09-26 12:03:01 +01:00
Lorenz Leutgeb 53522288c1 radicle-cli/tests: `fn program_reports_version`
Introduce this `fn` to check whether a program is available.
2025-09-26 12:03:01 +01:00
Lorenz Leutgeb fafb3493dc
cli: Detect key mismatch
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.
2025-09-26 00:33:59 +02:00
Fintan Halpenny ed8b086045 node: Log Panics
Register a panic handler that logs a backtrace via the `backtrace`
crate, instead of setting `RUST_BACKTRACE`.

Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xy>
2025-09-24 10:51:34 +01:00
Defelo 0441b048f9
cli: Don't add newlines for empty descriptions in editor 2025-09-23 19:52:54 +02:00
Defelo ae01a42434
radicle: Allow to clear issue descriptions and comments
Previously it was possible to create an issue with an empty description
(i.e. an empty "root" comment), and also to change it later to a
non-empty string, however it was not possible to clear it again.
2025-09-23 19:52:54 +02:00
Defelo ec22c94321
cli/issue: Show previous title in `rad issue edit` editor 2025-09-23 19:52:53 +02:00