Commit Graph

80 Commits

Author SHA1 Message Date
Lorenz Leutgeb 3f81e83d36 radicle/crefs: Support Symbolic References
Canonical references can not be used to model symbolic references.

Relax this restriction by adding another member to the payload, named
"symbolic". Its key-value/name-target pairs then translate directly to
canonical symbolic references.

Care is taken to not allow circular references, and that there always
is a rule that could generate the target of a symbolic reference
(or a chain of symbolic references). Still, a symbolic reference may
dangle (for example when its target reference cannot be computed
because of divergence), but at least it can be prevented that a
symref *always* dangles, because there is no rule that would produce
its target.

Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
2026-05-06 20:51:04 +02:00
Josh Soref 5dae2a8b58 treewide: Spelling
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2026-04-30 15:50:29 -04:00
Fintan Halpenny b4707e5502 cli: Amend jj tests
Update the output of `rad_jj_colocated_patch` so that it passes with the current version of `jj` being used:
```
jj --version
jj 0.35.0
```

Mark `rad_jj_bare` as `ignore` since it currently cannot determine the
RID from the `rad` remote.
2026-04-29 13:51:11 +02:00
Lorenz Leutgeb aa177b0400
treewide: radicle.{xyz → dev,network}
We have moved to radicle.dev, so adjust the domain name in various
places.

Not changed:
 - COB type names
 - systemd secret identifiers
2026-04-27 18:34:30 +02:00
Lorenz Leutgeb 06ff36ebc4
cli: Update warning for new bootstrap node names 2026-04-27 18:20:25 +02:00
Richard Levitte 354805aeb3 cli/test: Fix failures related to remote HEAD
Two tests assumed that `refs/remotes/rad/HEAD` would automatically be
crated.  It turns out, however, that this only the case if executed
with Git 2.48.0 or newer. Git versions older than 2.48.0 do not touch
'refs/remotes/<remote>/HEAD'.

Git 2.48.0 and newer will update `refs/remotes/<remote>/HEAD` by
default. This can be disabled by setting
`remote.<remote>.followRemoteHEAD` to "never". Thus, with these
versions, setting that configuration to "never" emulates the behaviour
of older versions.

Therefore, to ensure that test results are consistent across Git
versions before and after 2.48.0, the fixture of test repositories
now include setting 'remote.rad.followRemoteHEAD = never'.

The affected tests are adjusted accordingly.

This change can possibly be reverted once Radicle requires usage of Git
2.48.0 or newer.

Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
2026-04-21 23:15:34 +02:00
Lorenz Leutgeb 4f647b2a10 Spell "Radicle" with a captial R
In documentation and output, spell the name of the project with a
captial "R".
2026-04-17 17:15:31 +01:00
Lorenz Leutgeb ac3eba09a1 I2P Support
Co-authored-by: ps
2026-04-15 12:01:50 +01:00
Lorenz Leutgeb 22b2871f64 radicle: Add Version to User Agent
The main motivation behind this change is to get just a little
telemetry information from nodes on the network, namely the version
of Radicle they are running.

This is achieved by rewriting `impl Default for UserAgent` which now
uses the version information provided by the build script also used
in other crates.

Also, a new configuration option `node.userAgent` is added, which
allows users to override the user agent if they so please, or set
the value `null`, which will in turn send the user agent
`/radicle/`, which is not really helpful, and the default prior to
this commit.

Creations of `UserAgent` in the whole workspace is cleaned up. In
order to do that `UserAgent::test` is introduced.
2026-04-02 16:26:46 +01:00
Lorenz Leutgeb 96f573b767 cargo: Update dependencies with `cargo update` 2026-04-02 14:46:41 +01:00
Richard Levitte 91590a3287 cli/patch: Show Commit Ranges of Revisions
Each revision now shows a `{base}..{head}` range instead of just the
head.  This is meant to clarify when a patch is rebased, and to be
helpful when one might want to observe changes using 'git range-diff'.
2026-04-02 14:08:44 +01:00
Lorenz Leutgeb 10a82958ca
node: Explicit default for `AddressConfig`
The intent to drop outgoing connections is modeled as `Option::None`
which is brittle and easy to miss.

Extend `enum AddressConfig` with a variant that is more explicit.
2026-03-31 16:24:22 +02:00
Lorenz Leutgeb 5d583338c8 radicle/sigrefs/git: Use stable `RAD_LOCAL_TIME`
For stable commits, use the same timestamp as the CLI tests do.
This preserves that commits that are created in the Signed References
module appears as "now" in the output.
2026-03-25 08:07:49 +00:00
Lorenz Leutgeb e245e3115b fetch: Configure Minimum Feature Level
Add a configuration knob `node.fetch.signedReferences.featureLevel.minimum` to
allow node operators to enforce more strict verification when fetching
Signed References.
2026-03-24 14:40:42 +00:00
Lorenz Leutgeb 47063057a8 radicle/sigrefs: Automatically Migrate
In order to allow automatic migration to the feature level 'parent',
introduce a way to force writing signed references, even if the
user-controlled refs are unchanged.

To detect the special case of a Signed References history with a single
and root commit (which would otherwise be detected as feature level
'parent', even though the `refs/rad/sigrefs-parent` ref cannot be
written), keep information about the parent commit in `SignedRefs`.

The output of `rad inspect --sigrefs` is changed to match the more
strict interpretation of the feature level for histories with a single
and root commit.
2026-03-24 14:40:42 +00:00
Lorenz Leutgeb 7fb032da9b cli/inspect: Show feature level of sigrefs
In order for users to be able to inspect the feature level of Signed
References in a repository, have `rad inspect --sigrefs` attempt to
load Signed References, and, if successful, print the feature level.
2026-03-24 14:40:42 +00:00
Fintan Halpenny d40fa9a347 radicle/sigrefs: Switch to new implementation 2026-03-17 21:31:42 +01:00
Matthias Beyer 99d9242122 Use humantime to parse timeouts
In issue

    29c6c6fc8171287faa0079798ba2d6e3e7fd86f3

was noted that it would be nice to use value parsers for the timeouts in
the CLI.

This patch implements this.

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Co-Authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
2026-03-17 11:39:09 +00:00
Defelo 52e5581228 cli: Don't override existing seeding scope in `rad seed` 2026-03-17 10:31:29 +00:00
Defelo 281f92e9ff cli/tests: Add test for `rad clone --scope` 2026-03-17 10:31:29 +00:00
Matthias Beyer ff85c74eaa cli: Add blank line after issue reply header
This patch adds a blank line to seperate the issue reply header from the
issue reply payload.

This makes visually parsing the output easier.

Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2026-03-12 13:30:09 +00:00
Yorgos Saslis f4aee203ab radicle: Make SQLite pragmas configurable
Expose choosing particular SQLite pragmas via configuration.
2026-03-09 09:20:42 +00:00
Fintan Halpenny 7c92360842 radicle: fix to schemars of DefaultSeedingPolicy
Use `flatten` to remove the extraneous `Scope2` that shows up in the
JSON schema of the Radicle `Config`.
2026-03-05 15:32:44 +01:00
Fintan Halpenny 6291cae592 cli: add `rad config schema` to the `rad-config` test
Adds the `rad config schema` to the `rad-config` test so that changes
to the schema will result in errors, forcing the implementor to ensure
the changes are correct.
2026-03-05 15:32:44 +01:00
Adrian Duke 832598ceb7 cli: Warn user about implicit seeding policy
To prepare for future changes, warn users if their config file currently
does not explicitly specify a default seeding policy.

Because there are now potentially multiple warnings generated that all
relate to the configuration file, group these together and adjust the
wording to be more uniform.
2026-02-16 21:39:11 +01:00
Adrian Duke 0684d1ccdf cli: Changed the default scope from all to followed for clone and seed
The previous implementation used 'all' as the default for scope, this
could lead to surprising behaviour where a user would fetch all
references for cloned and seeded repositories. Instead have a progressive,
safe by default value - where it fetches only 'followed' references. Later
a user can decide to set the scope to 'all'. NOTE: the default policy
scope was not changed from 'all' and is intended to be changed at a
later date.
2026-02-16 21:39:11 +01:00
Adrian Duke dd13eed1d0 cli: Do not print scope in block table
Previous implementation used the default scope when a scope wasn't
present. Scope is not present when the policy is block, because block
doesn't have a scope. Instead use an empty string when printing the
block policy.
2026-02-16 21:39:11 +01:00
Lorenz Leutgeb 9055a2043c cli-test: Add placeholder for executable extension
Help text generated by `clap` contains the full file name (including
extension) of the binary. On Unix-like systems, binaries commonly do not
have any file extension. On Windows, ".exe" is common.

To allow testing such output, introduce a new marker "[EXE]" that is 
substituted accordingly. The idea and syntax is taken from
https://docs.rs/trycmd/1.0.0/trycmd/#toml
2026-02-16 08:39:55 +00:00
Fintan Halpenny c33c26fa78 cli: fix casing for warning of preferred_seeds
While the field name will `preferred_seeds` in Rust, the casing for
the JSON file is `preferredSeeds`.
2026-01-28 10:17:36 +00:00
Lorenz Leutgeb e63c30976e cli/fork: Deprecate
This command is confusing in name and function. Rather than creating
a hard fork of a repository, with a new identity, it pushes the
default branch to the local user's namespace.

Deprecate it and add some help text.
2026-01-23 15:04:16 +00:00
Adrian Duke b937a93892 radicle-cli: more helpful error for non-delegate updates
When a non-delegate attempts to update the identity document, their
action will be rejected.

Provide a better error, along with a hint, to the non-delegate.
2026-01-22 10:38:28 +00:00
Fintan Halpenny 3168107df9 fetch: surface underlying I/O error
The message that is returned by `gix-transport` for I/O errors can be
unhelpful, since it does not provide the reason for what happened.

Instead, surface the error so that it provides more detail for logging.
2026-01-05 18:29:52 +01:00
Fintan Halpenny 0c70e17123 remote-helper: inform the user of an empty patch
The previous message is included in the error:

     ! [remote rejected] master -> refs/patches (patch commits are already included in the base branch)
     
To make it clearer to the user, also print a warning to tell them that the
commit was in the base branch – including the commit SHA:

    warn: attempted to create a patch using the commit f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354, but this commit is already included in the base branch
2025-11-28 20:19:47 +01:00
Defelo 0ec084fc23 remote-helper: Support push --force-with-lease
Previously, the remote helper would not support the `--force-with-lease` option.
This change introduces this support and ensures that it works as intended.

Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
2025-11-25 10:48:30 +00:00
Yaroslav Halchenko 32d77641ab chore: Fix spelling errors with codespell 2025-11-01 12:11:02 +01:00
Fintan Halpenny 23332fa318 cli/main: migrate main to use clap
Now that all commands can be parsed by clap, remove any custom parsing and
directly use `CliArgs::parse`.

The `Diff` command was removed, since only one `external_command` can be
declared for a subcommand. The handling of `rad diff` is now done via the
`External` variant. If the subcommand name is `diff` then this is executed,
otherwise delegate to the possible `rad-{exe}` command.

Also of note, the `rad inspect` command has an alias `rad .`. This changes the
behaviour of `rad . --help`. Before, it would print the help of the `rad`
command. Now, it prints the help of `rad inspect`.

Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
2025-11-01 11:20:43 +01:00
Fintan Halpenny 38ca038a0d cli: fix test regression in 27a85987c3
A test failure was caused in commit
27a85987c3, which expected `STRING`
instead of `ALIAS`.

This change fixes that discrepancy.
2025-10-17 16:57:29 +01:00
Lorenz Leutgeb 72cf3d1919 cli/diff: Use clap
The implementation of the *deprecated* command is removed, it now
directly invokes `git diff`.
2025-10-15 10:30:34 +02:00
Richard Levitte 384c506489 cli/auth: use Clap 2025-10-14 12:55:33 +01:00
Erik Kundt dfd35480be cli/watch: Use clap 2025-10-14 12:49:16 +02:00
Lorenz Leutgeb f7af918190 cli/test: Fix `rad_patch_delete` for macOS
It looks like macOS does not like this command:

    ln: -f: No such file or directory

Since `LICENSE` and `MIT` are both just empty here, we don't need to
link anything.
2025-10-13 10:18:10 +01:00
Lorenz Leutgeb 7d6d2e51d8 cli/test: Clean up testing environment
This is a small cleanup to path generation during testing.
 1. Separate `rad_home` and `unix_home` to avoid confusion.
 2. Remove now unnecessary `trait HasHome`.
 3. Move setting `$USER` to the environment.
 4. Make paths shorter overall, to fix macOS tests.
2025-10-13 08:56:23 +01:00
Lorenz Leutgeb 8c1073b9c9 cli/publish: Use clap 2025-10-09 10:52:21 +02:00
Lorenz Leutgeb 7c89045ea0 cli/debug: Use clap 2025-10-08 15:30:18 +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 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 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 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