Commit Graph

280 Commits

Author SHA1 Message Date
Fintan Halpenny 186d8d30fe cli: Update to 0.18.0 2026-02-19 21:06:43 +01:00
Fintan Halpenny 3a11074600 radicle: Update to 0.21.0 2026-02-19 21:06:43 +01:00
Fintan Halpenny 89478b16fe cargo/git2: Update to 0.20.4
Update to `git2` to 0.20.4` and `radicle-surf` to 0.27.0.

This fixes a low severity vulnerability[^0].

[^0]: https://github.com/advisories/GHSA-j39j-6gw9-jw6h
2026-02-19 20:57:18 +01:00
Lorenz Leutgeb 5fa68ed814
node: Use `gix_packetline`
`gix-packetline` already is in the dependency closure of `radicle-node`.
Use the well-tested and -used reader instead of ours.
2026-02-16 21:42:59 +01:00
Fintan Halpenny 7862e108b6 Update gix-* crates
Fixes [CVE-2026-0810].

The `gix` crates require updating due to the security vulnerability above.
They require updating together in lock-step so both `radicle-fetch`
and `radicle-oid` are affected.

`radicle-oid` handles the non-exhaustive nature of `ObjectId`.

`radicle-fetch` updates to the new API types, however, this comes with
some updates to the `ls_refs` protocol.

A regression is documented in [gitoxide issue 2429].
The regression highlighted that it is the duty of the caller to also
filter the outcome of ls-refs, and `ref-prefix` is simply an
optimisation.

The ls-refs code is refactored to better represent and handle this operation.

[CVE-2026-0810]: https://www.cve.org/CVERecord?id=CVE-2026-0810
[gitoxide issue 2429]: https://github.com/GitoxideLabs/gitoxide/issues/2429
2026-02-16 17:13:39 +00:00
Lorenz Leutgeb a1fa38018e protocol: Depend on `cypheraddr` not `cyphernet`
`radicle-protocol` depends on `cyphernet`, but only uses the module
`cyphernet::addr`, which is a re-export of `cypheraddr`, which is
unnecessary (as `cypheraddr` alone would do), and invites accidentally
pulling in more dependencies via `cyphernet`.

To prevent accidentally depending on further types from `cyphernet`,
change this to more conservativeley depend on `cypheraddr`.
2026-02-16 09:43:38 +00:00
Fintan Halpenny c06b00e330 CVE-2026-25727
Report: <https://www.cve.org/CVERecord?id=CVE-2026-25727>

The `time` crate was a transitivie dependency of `human-panic`.
Updating `human-panic` to 2.0.6 removes the `plist`, and in turn,
`time` dependencies.
2026-02-13 19:08:26 +01:00
Fintan Halpenny 31607cf7ad CVE-2026-25541
Report: <https://www.cve.org/CVERecord?id=CVE-2026-25541>

This vulnerability was introduced via the `bytes` crate.

Update to 1.11.1, as recommended.
2026-02-13 19:07:39 +01:00
Fintan Halpenny 2d0db3c6b2 CVE-2025-58160
Report: <https://www.cve.org/CVERecord?id=CVE-2025-58160>

This vulnerability was introduced via the `test-log` crate.

Updating to `0.2.19` in turn updates `tracing-subscriber` to `0.3.22`
which is in the acceptable upgrade range.
2026-02-13 17:26:50 +00:00
Lorenz Leutgeb 03bbe52417 signals: Add support for Windows 2026-02-13 15:38:02 +00:00
Lorenz Leutgeb ebf7d876b4
node: Control via `uds_windows` not `winpipe`
Recent versions of Windows support Unix Domain Sockets natively, see
<https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/>.

By using that feature instead of Windows named pipes, the difference
for handling communication via the control socket comparing Unix-like
systems and Windows becomes smaller:

 1. No special paths like `\.\pipe\…` have to be handled.
 2. Not two I/O mechanisms are abstracted (named pipe and UDS) but
    just one.
 3. `winpipe` relies on background threads while `uds_windows` does
    not.

Once the feature `windows_unix_domain_sockets` (which is tracked at
https://github.com/rust-lang/rust/issues/150487) stabilizes, it will
likely be possible to just drop the dependency `uds_windows` and use
the implementation in `std::os::windows::net` directly.
2026-02-12 10:18:48 +01:00
Lorenz Leutgeb 90cf37c471
node: On Windows, use job for upload-pack child
Reports of zombie (grand)child processes were received. By associating
the `git upload-pack` process with a job, zombies are prevented.
2026-02-11 16:37:56 +01:00
Lorenz Leutgeb 990edbf055
windows: Introduce new crate
node: Use new windows crate to terminate job
2026-02-11 16:37:56 +01:00
Lorenz Leutgeb 930ec175f1
term, cli: `winsplit` over `shlex` on Windows
Command line parsing differs on Windows vs. POSIX compliant operating
systems (just consider the differences in handling `\` for paths vs. as
a marker for escape sequences). Thus, on Windows use `winsplit` to
split command arguments instead of `shlex` for Unix-like OSes.

`winsplit` is a small crate with no other dependencies.
2026-02-11 10:26:22 +01:00
Lorenz Leutgeb faeee9f370 crypto: Optionally provide JSON Schema
Providing the schema in `radicle-crypto` saves a lot of repetition
in `radicle`, and can be done via an optional dependency.
2026-02-10 09:39:34 +00:00
Fintan Halpenny f0e3ca3403 protocol: Introduce `FetcherState`
This patch introduces the `FetcherState` which encapsulates the logic
and state for keeping track of fetches.

It uses a sans-IO approach, where the state of fetches transition
based on the current state and provided input.

Callers can then decide to perform I/O based on the returned event.
2026-02-05 20:04:28 +01:00
Fintan Halpenny 73827f5362 radicle: Re-export `radicle_core::NodeId` 2026-01-09 14:04:04 +01:00
Fintan Halpenny 7c016f9219 core: Introduce NodeId
A type for node IDs, which are Ed25519 public keys, is added to the
`radicle-core` crate.
2026-01-09 14:03:32 +01:00
Fintan Halpenny d5fea6324c core: Introduce RepoId
Introduce the `radicle-core` crate for housing data types that are at
the core of the Radicle protocol. The initial data type being added is
`RepoId`. To make the crate as lightweight as possible many of
dependencies are optional and gated by feature flags.
The crate is marked as `no_std` even though it unconditionally depends
on `radicle-crypto`, which is *not* `no_std`. This is to invite
refactoring of `radicle-crypto` to `no_std` at a later time.
2026-01-09 14:03:27 +01:00
Lorenz Leutgeb af3f07627b
chore: Update thiserror from 1 to 2
The section on breaking changes in the release notes at

    https://github.com/dtolnay/thiserror/releases/tag/2.0.0

look relatively tame. We gain support for `no_std`.
2026-01-09 10:47:23 +01:00
Fintan Halpenny d98033a1ff localtime: localise the localtime dependency
The `localtime` crate was defined by cloudhead, and is a minimal
repository with a single `lib.rs`.

Instead of using it as an external dependency, copy the code directly
into a new workspace crate `radicle-localtime`.

The default `serde` implementation goes through the `LocalTime`'s
seconds values rather than milliseconds, since this is the more common
format. This allows the removal of the `serde_ext` functions.
The one place milliseconds was used was for the
`radicle::cob::common::Timestamp` type, where the `Serialize` and
`Deserialize` implementations are manually written.

It also adds a `schemars` feature to remove `schemars_ext` functions
in `radicle` as well.
2026-01-08 14:58:41 +01:00
Fintan Halpenny a66d44ebe2 workspace: update git-ref-format-core and radicle-surf
Update the above crates to their latest version, which now use MIT OR Apache-2.0 licensing.

This allows us to remove the exception entries in `deny.toml`.
2025-12-08 16:43:20 +00:00
Fintan Halpenny 93d2ed8c61 cli/completion: Static shell completion for `rad`
Introduce the use of `clap_completion` for generating static completion.
The shells that are supported are the ones that are included in `clap_complete`:
- `bash`,
- `elvish`,
- `zsh`,
- `fish`, and
- `powershell`.

Co-authored-by: Michael Uti <utimichael9@gmail.com>
Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
2025-11-28 20:47:25 +01:00
Fintan Halpenny bc1d9ed495 cli: remove lexopt dependency 2025-11-01 11:20:43 +01:00
Fintan Halpenny b7a7f55e78 gix: CVE-2025-31130
Update the `gix` family of crates to avoid the vulnerability reported in
[CVE-2025-31130].

Since `gix-hash` is used in two places, its version definition was moved to the
top-level `Cargo.toml`. `cargo` warned that `default-features` not being defined
in the top-level could result in a future error, so that was carried along with
it. This did not affect the build of `radicle-fetch`.

[CVE-2025-31130]: https://www.cve.org/CVERecord?id=CVE-2025-31130
2025-10-15 11:34:01 +01:00
Lorenz Leutgeb b7cfcfff75
workspace: A Little Less `git2`
Make `git2` an *optional* dependency of `radicle-cob`, and refactor
`radicle` to depend on crates that in turn do not depend on `git2`
*non-optionally*

The main offending dependency of `radicle-cob` is `radicle-git-ext`
from the `radicle-git` workspace in repository
(rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt) which *non-optionally* depends on
`git2`.

So, to achieve removal of this dependency:

 1. The crate is refactored to depend on the new crates
    `radicle-git-ref-format` `radicle-git-metadata`, and
    `radicle-oid` introduced in the previous commits, instead of
    `radicle-git-ext`.
 2. Some code from the `radicle-git-ext` crate in the `radicle-git`
    workspace in repository (rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt) is
    copied. See `crates/radicle-cob/src/backend/git/commit.rs`.

This cascades to `radicle` and its dependents.

  Firstly, the there is an
`impl Deref<Target=git2::Oid> for radicle_git_ext::Oid`. This made
it very convenient to just deref to obtain the wrapped `git2::Oid`,
so there are many expressions of the shape `*oid` in `radicle` and
its dependents. However `radicle-oid` does not provide
`impl Deref<Target=git2::Oid> for radicle_oid::Oid`, as notably,
`Target` is an associated type, and not a type parameter, so an
implementation of `Deref` would tie the new `Oid` too tightly to a
particular implementation.
Instead, work with `impl From<radicle_oid::Oid> for git2::Oid`
(which can be enabled using the feature flag `radicle-oid/git2`).
This explains the changes from `*oid` to `oid.into()` at every
transition to "`git2` land".

  Secondly, `radicle` and its dependents are refactored to also depend
on `radicle-git-ref-format` and (much less prominently)
`radicle-git-metadata` instead of `radicle-git-ext`
This is to avoid pulling in `git2` via these dependencies.

  Thirdly, as the re-exports in `crates/radicle/src/git.rs` change,
they are at the same time also cleaned up. Notably, the types from
`radicle-git-ref-format` are re-exported under `fmt` only, not "twice".

While overall this obviously is very much a breaking change, these
changes should mostly amount to changing from `Deref` to `Into`, i.e.,
`*oid` → `oid.into()` and rewriting imports for `radicle::git::fmt`.
This is indicated by the mostly mechanical nature of the changes to
`crates/radicle-{cli,node,remote-helper}`.
2025-10-13 16:14:23 +02:00
Lorenz Leutgeb f4a8908727
git-metadata: New crate extract from `radicle-git`
This is just enough to get heartwood going.

Some code from the `radicle-git-ext` crate in the `radicle-git`
workspace in repository (rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt) is
copied.
2025-10-13 16:07:39 +02:00
Lorenz Leutgeb 793f53b5f0
oid: New crate
For further details on the crate see its documentation in
`crates/radicle-oid/src/lib.rs`.

Changes to `crates/radicle{,-crypto}/Cargo.toml` are to preserve the
default features of their dependencies `serde` and `schemars`,
which are disabled to support `radicle-oid` being `no_std`.
2025-10-13 15:00:12 +02:00
Lorenz Leutgeb 3fcf2a86da
git-ref-format: New crate
For further details on the crate see its documentation in
`crates/radicle-git-ref-format/src/lib.rs`.
2025-10-13 13:34:15 +02:00
Lorenz Leutgeb cb7bed5562 node: Remove dependency on amplify 2025-10-10 09:45:05 +01:00
Lorenz Leutgeb 3c3d81a085 node: Use Mio
The dependencies `netservices`, `io-reactor` and `popol` served us well,
however they do not support Windows and are not actively maintained.

This change removes the aforementioned dependencies (and `libc` along
with them). It reuses the integration with `cyphernet` from
`netservices` for Noise and SOCKS.

The new module `reactor` is a rewrite of `io-reactor` on top of Mio.

Note that no tests were changed.
2025-10-10 09:45:05 +01:00
Lorenz Leutgeb b25d80d272
crypto: Depend on `git-ref-format-core` only
The `git-ref-format-core` crate is enough to implement everything
required by `radicle-crypto`, and has a much smaller dependency
footprint than `radicle-git-ext`. Notably, it does not depend on
`git2` and also does not depend on procedural macros.
2025-10-09 17:18:59 +02: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 675a0f81d9
cli: Depend on clap 2025-09-28 18:02:55 +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
Sebastian Martinez 5fea9ac05c node: Add `--log-logger structured` and `--log-format json`
Optionally depend on crate `structured-logger`. Allow enabling it via
`--log-logger structured`. For future compatibility, provide
`--log-format` which currently only supports JSON.

Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
2025-09-23 16:33:50 +02:00
Erik Kundt 8fc37e3316 term: Move to indicatif spinner
This fixes line flodding on narrow terminals and a missing cursor after
cancelation by replacing the custom spinner with an indicatif spinner.
2025-09-15 11:17:35 +02:00
Matthias Beyer 3f489354b6 cli: Add itertools dependency
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2025-09-10 21:23:30 +02:00
Lorenz Leutgeb 2127782b74 term: Remove dependency on `anyhow`
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.
2025-09-04 16:28:20 +03:00
Lorenz Leutgeb 79d928551b node: Remove dependency on `anyhow`
`anyhow` is only used to capture a handful of errors. It also turns out that
usage of `lexopt` was wrong, since it features `parse_with`, which neatly
integrates with `FromStr`. The types, luckily, implement this trait already –
making for cleaner parsing.

For now, the execution errors are all "transparent", which shouldn't be
much of a regression, if at all.
2025-09-04 16:28:20 +03:00
Lorenz Leutgeb ded0d19d59 protocol/wire/test: Define `fn roundtrip` and macro
In many tests we assert that encoding and decoding gives the same
object. Let's call that a "roundrip", and also provide a proc macro to
generate such tests.
2025-08-27 12:48:11 +02:00
Fintan Halpenny bbd1e2cff6 crates: 1.4.0 release
Update crate versions for the 1.4.0 release
2025-08-27 10:30:28 +01:00
Lorenz Leutgeb 19a262d3d6 node: Use winpipe for control socket on Windows
As `std::os::unix` is obviously not available on Windows, resort to the
`winpipe` crate, which implements a very similar API for named pipes.

Apart from simple changes to imports, we need to jump through a few
hoops because the `std::io::{Read, Write}` impls are on `&mut` for
`winpipe`, thus yielding different mutability requirements on Unix vs.
Windows.

We resort to cloning, but as this fallible, swallow the added complexity
of a platform-dependent implementation to not risk panics on Unix.
2025-08-22 15:45:20 +01:00
Lorenz Leutgeb 5229fb8a59 fix: Normalize filesystem paths with `dunce`
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`!
2025-08-22 15:11:43 +01:00
Matthias Beyer 6a1b13bb66 cli: Use human-panic
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2025-08-17 20:53:53 +02:00
Fintan Halpenny d147094812 fix: upgrade radicle-crypto
The upgrade of the `radicle-crypto` crate was missed when upgrading
semver versions.

Unfortunately, since it is at the base of the dependency tree, all
crates that depend on it require an additional upgrade.
2025-08-13 09:20:42 +01:00
Fintan Halpenny 0e48723b41 release: prepare crates
The `radicle` crate required a bump `0.16.1 -> 0.17`.

Due to this, all its dependents are also bumped
- `radicle-cli`: `0.14.0` -> `0.15.0`
- `radicle-fetch`: `0.12.0` -> `0.13.0`
- `radicle-node`: `0.12.0` -> `0.13.0`
- `radicle-remote-helper`: `0.11.0` -> `0.12.0`
- `radicle-schemars`: `0.1.0` -> `0.2.0`

The following also required upgrading:
- `radicle-ssh`: `0.9.0` -> `0.10.0`
- `radicle-systemd`: `0.9.0` -> `0.10.0`
- `radicle-term`: `0.13.0` -> `0.14.0`
2025-08-12 12:13:49 +02:00
Lorenz Leutgeb d7b48b9e29 radicle: Move logging setup calls to binaries 2025-08-07 08:30:59 +01:00
Lorenz Leutgeb c7f3c47f9a systemd: Add module for logging to the journal 2025-08-07 08:30:59 +01:00
Lorenz Leutgeb 5d467418be term: Revert using inquire to spawn editor
This is morally a revert of 70fb0d3fef
while additionally getting to compile
`crates/radicle-term/src/editor.rs` on Windows.

To get the changes that were made on top of the revert, check

  git diff 70fb0d3fef~1 <this commit> -- crates/radicle-term/src/editor.rs

There were reports of the inquire editor being unrealiable.
2025-08-05 15:09:43 +02:00