Commit Graph

772 Commits

Author SHA1 Message Date
Lorenz Leutgeb 6259a70327 cargo: Use `workspace.package` table
This removes redundancy from the manifest of many of our crates.

See: <https://doc.rust-lang.org/cargo/reference/workspaces.html#the-package-table>
2025-06-09 14:25:31 +02:00
Lorenz Leutgeb eea6a9bc70 cargo: Clean up dependencies
All dependencies that are dependencies of multiple crates within the
workspace were pulled up to the root `Cargo.toml`. Dependencies that are
dependencies of just one crate within the workspace remain in the
`*/Cargo.toml` of that particular crate.

Generally, this helps us keep an overview of dependencies:
 - If multiple crates depend on a crate, we will see the reference to
   the workspce.
 - Otherwise, we will see a line that specifies the version.

It is up to the maintainers to recognize when a dependency becomes a
dependency of multiple crates in the workspace, at which point it should
be moved to the workspace.

The tool `cargo-autoinherit` can be used to automatically pull *ALL*
dependencies to the workspace. I used this, and in a separate, manual
step, filtered out those dependencies that are dependencies of a single
crate only, moving those back manually.

At the same time, I also unified depending on sibling crates in the
workspace. This is now also done via workspace dependencies.

See:
 - https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace
 - https://github.com/mainmatter/cargo-autoinherit
2025-06-09 13:58:52 +02:00
Lorenz Leutgeb d50df68b74 chore: Remove dependency `once_cell`
Rust 1.80 introduced `std::sync::LazyLock` which achieves the same, so
cut down on dependencies a bit.

See: <https://doc.rust-lang.org/1.80.0/std/sync/struct.LazyLock.html>
2025-06-09 12:06:30 +02:00
Lorenz Leutgeb bac719da21 bootstrap: Migrate radicle.garden → radicle.xyz 2025-06-04 17:13:02 +02:00
Jakob Kirsch 9d4aa59a12 radicle: add .external_template(false) to libgit2 call
Without this, rad clone fails with:
Error: checkout: git: failed to initialize repository with template 'hooks/README.sample': Permission denied; class=Os (2)
2025-06-04 12:15:59 +02:00
Lorenz Leutgeb fcd1acd1dd radicle/schemars: Annotate Commands and results
JSON Schema extraction via `schemars` is provided for configurations.
There are other interfaces that use JSON for (de-)serialization, such as
the communication with `radicle-node` via the control socket.

To ease implementation of tools that want to communicate via the control
socket, we add the respective `schemars` annotations.
2025-06-03 15:10:30 +02:00
Lorenz Leutgeb 05368e84fa cargo: Make schemars a workspace dependency
The `schemars` crate is a dependency of multiple workspace crates in the
same version. Its version number is repeated multiple times in the
respective `*/Cargo.toml` files. This requires more maintenance effort
and risks versions drifting.

As long as all crates depend on the same version, it makes more sense to
have `schemars` as a workspace dependency.

See: <https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table>
2025-06-03 15:10:30 +02:00
Fintan Halpenny e9cf91e1bc cob: bump major version
The addition of the `Namespace` parameter in the traits requires a
major version bump for `radicle-cob`
2025-06-02 11:31:48 +02:00
Fintan Halpenny e6ef767f36 radicle: remove job cob
The Job COB is defined as separate crate: [radicle-job]. So this change removes
its definition and use from the `heartwood` repository.

[radicle-job]: https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z2UcCU1LgMshWvXj6hXSDDrwB8q8M
2025-06-02 10:59:55 +02:00
Fintan Halpenny f4c8ff7a64 chore: prepare crates release
This prepares the crate versions for a new release. The version bumps were
determined by the `cargo-semver-checks` tool.

However, there were some issues with the `radicle-fetch` crate – where when
attempting to check it, it was unable to compile due to the previous version
expecting the kind of `Doc` with a generic parameter. I believe this is due to
the version for `radicle` being specified as simply `0`. This prompted changing
the version specifications to use `major.minor` for all the internal crates.
This, for example, would mean that `radicle-fetch` that relies on `0.15` can use
`>=0.15.0,<0.16.0` – allowing any patch versions but must require a minor
version bump.
2025-05-30 12:58:18 +02:00
Fintan Halpenny d1ba665ebf radicle: introduce sync::announce tests
Test various cases for the `Announcer` to help ensure correct behaviour.
2025-05-30 09:43:12 +02:00
Fintan Halpenny aa7dcd92db radicle: use a struct to help announce success counts
It is easy to mix up the order of a tuple, so a struct is introduced instead to
ensure that the correct counts are used.
2025-05-30 09:42:08 +02:00
Fintan Halpenny 5a0c14cf61 radicle: ensure preferred seeds are announced to
Ensure that the preferred seeds that are not in the synced set are announced to.
2025-05-30 09:40:50 +02:00
Fintan Halpenny c57d43f2f5 radicle: schemars test should be behind feature flag
A `#[cfg(feature = "schemars")]` was missed in the `profile/config.rs` module
since it was part of the test module.
2025-05-30 09:26:31 +02:00
Fintan Halpenny 5b4cbc2cd8 radicle: introduce announcer
Similar to the `Fetcher` sans-IO approach, an `Announcer` sans-IO approach is
introduced. The previous `Handler::announce` was already quite close to using a
sans-IO approach, but using internally held state. This change makes the
business logic more reusable – and testable.

Similarly to the `Fetcher`, the `Announcer` is configured and then driven by
telling it when nodes have been synchronized with. It will continuously check if
it has reached its target, yielding to the caller to decide whether to keep
going. In contrast, it also provides a way to mark the process as timed out,
since announcing relies on waiting for events to come back in a timely manner.
2025-05-26 12:31:03 +02:00
Fintan Halpenny fa9c6cd142 radicle: move PrivateNetwork to `node::sync`
This construction can be used more generally, for example in announcements, so
it is moved one level up.
2025-05-26 12:31:03 +02:00
Johannes Altmanninger 059c804588 radicle: fix build when schemars feature is not enabled
Commit b608a788 (cli: `rad config schema` emits JSON Schema, 2025-04-28)
added a feature flag that enables the "schemars" optional dependency.

Crate radicle-node doesn't use this feature.
Crate radicle fails to compile when the feature is disabled.
This is reproducible with "flake check".
Fix it. 

Note that a "cargo build" of the entire workspace doesn't fail, because the
feature is enabled due to "unification", since "radicle-cli" does use this
feature.  From https://doc.rust-lang.org/cargo/reference/resolver.html#features:

> When building multiple packages in a workspace (such as with --workspace
> or multiple -p flags), the features [of the dependencies] of all of those
> packages are unified. If you have a circumstance where you want to avoid
> that unification for different workspace members, you will need to build
> them via separate cargo invocations.
2025-05-24 22:39:38 +02:00
Fintan Halpenny eec4dd4505 radicle: improve sync fetching
This patch changes separates the business logic of fetching from the process of
fetching itself. It does this through a sans-IO approach, where a `Fetcher`
provides the necessary state to help drive a fetch forward, without performing
any of the IO itself.

What the `Fetcher` cares about is:
- What nodes are going to be attempted to be fetched from
- In what order should they be attempted
- When should the fetching process be considered finished

The `Fetcher` is then used in `radicle-cli` to drive forward the `sync::fetch`
function, allowing it to only care about the IO.
2025-05-23 17:22:48 +01:00
n4ch7 b608a78806 cli: `rad config schema` emits JSON Schema
Leverage `schemars` to generate a JSON Schema from our structs for
configurations and those occurring within them.

The output of `rad config schema` can be used by editors to provide a
smoother editing experience for the configuration file. Discovery
attributes (both keys and values) is greatly improved with the schema
helping in the background.

Refer to:
 - https://json-schema.org
 - https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings
 - https://schemastore.org
2025-05-22 11:00:46 +02:00
Fintan Halpenny 9988b63bb2 cob: abstract namespace identifier
This change is to help separate the fact the namespacing by a `NodeId` is a
Radicle specific concern. The identifier can, in theory, be any kind of path
component, as long it is valid in Git.

The motivation for the change is to help separate the idea of a device's
`NodeId` vs an agent being an author – for future agent repository work.
2025-05-22 09:09:57 +02:00
Fintan Halpenny 1f4fcc5e6a radicle: move to `signature` crate
The motivation of this change is to move away from tying signing to be
specifically for ed25519. The reason being that the protocol will want move
towards two different kinds of signing – the node signing artifacts, and an
author signing artifacts.

This change captures the former, node signing, by introducing a `Device` type
that is the `NodeId` – a PublicKey underneath the hood – and a signing
mechanism. This allows the replacement of the `Signer` trait being used – which
always assumed a `PublicKey`. Instead, the `Device` is constructed with
`NodeId`.

In `radicle-cob`, a signer is expected to implement
`signature::Signer<ExtendedSignature>`, and everywhere in `radicle`,
`radicle-node`, `radicle-cli`, and `radicle-remote-helper` is expected the
signer is expected to implement `signature::Signer<Signature>`.

A `Device` implements both of these but only requires
`signature::Signer<Signature>` to do so – since an `ExtendedSignature` is
essentially `(PublicKey, Signature)`, and the `NodeId` of the `Device` can be
used.
2025-05-22 09:09:57 +02:00
Lars Wirzenius 105b65c2ac workspace: set rust-version (MSRV)
This declares the minimum supported Rust version, independently of the
`rust-toolchain.toml` file, which specifies the Rust version and
toolchain components the crate/workspace should be built with. The
MSRV affects other crates that depend on anything in this workspace,
but the toolchain file does not seem to affect them. This means the
MSRV is useful for those who build or develop dependents.

Signed-off-by: Lars Wirzenius <liw@liw.fi>
2025-05-16 13:49:38 +02:00
Fintan Halpenny f5fa84fac6 test: set name and email for repository fixture
In fresh environments, without a global git config, the `user.name` and
`user.email` will not be set for the fixture repository. This causes issues when
tests are run and attempt to call `git2::Signature::now` – it will fail to read
a user name and email for the commit.

To remedy this, the name and email are set for the repository when initialising
it.
2025-05-09 10:30:44 +01:00
Lorenz Leutgeb f30760d6bb
cob: Add CobAction::produces_identifier and validation
Transactions will now fail/deny when adding multiple actions that
produce an identifier.
2025-04-28 16:19:02 +02:00
Lorenz Leutgeb e4d23fe56a
cli: Introduce `cob [create|update]` 2025-04-28 16:19:02 +02:00
Fintan Halpenny a90aabb1fe node: rate limiter for channel reads
This introduces rate limits for the `ChannelReader` to limit DDoS attacks and
attempts to upload repositories that are larger than a node is will to permit.

The limiter sets the total number of bytes it is will to accept in a single
exchange, defaulting to 500MB. This means that initial fetches will prevent
large repositories, but is plenty for new packfile data to be sent in subsequent
fetch exchanges.

The limit can be configured within the node's config file, under the limits.
2025-04-25 20:27:51 +02:00
Lorenz Leutgeb f13afe491d remote-helper: Print `git range-diff` invocation 2025-04-24 16:51:38 +02:00
Fintan Halpenny ce8ac663f7
radicle: use `git fetch` over libigt2 in checkout
Similarly to pushing using the `file://` protocol and `libgit2`, fetching will
be slow – so instead use `git fetch` directly to perform the `checkout`.
2025-04-23 16:21:51 +02:00
Fintan Halpenny 8fd044833e
radicle: use `git push` to avoid `libgit2` push
In issue #[2836] of `libgit2`, the speed of `libgit2`'s `file://` protocol for
git operations is found to be very slow. This is further corrobarated by `rad
init` taking 13 hours to initialise the hardenedbsd [ports] repository.

There are two areas where the `heartwood` project uses `libgit2` to push using
the file protocol. The first is when via the `trasnport::local` smart transport
registration and the second is the final push to storage in the `git-remote-rad`
binary.

When both these `push` operations are changed to use the `git` binary instead,
the [ports] repository can be initialised in less than 10 minutes (nearly 100x
speed up).

This change is clearly required if `heartwood` wishes to support larger
repositories.

[2836]: https://github.com/libgit2/libgit2/issues/2836
[ports]: https://git.hardenedbsd.org/hardenedbsd/ports
2025-04-17 15:12:12 +02:00
Fintan Halpenny 96637aca7e
chore: update rust-toolchain
Update the rust toolchain version to 1.85.

Note that this is not the latest, however, it is the latest available in nixpgs,
so this version is good enough for now.
2025-04-17 10:39:34 +02:00
Fintan Halpenny 9ef9c5d59a radicle: add Op::load method
Adds an `Op::load` helper method for loading an `Entry`, given its `Oid` and the
`store` it is stored in.

This can be useful for downstream consumers to inspect operations on COBs given
a single `Oid`, without having to load the entire object and/or graph.

It can also be useful when looking at implementing COB stream primitives.
2025-04-11 12:52:09 +02:00
Fintan Halpenny c847a16e14 radicle: return iterator types for db policies
Instead of collecting the results and returning the collection as an
iterator, introduce `FollowPolicies` and `SeedPolicies` types, which
implement `Iterator`.

Note that a call in `service` changed due to the lifetime borrow. It
simply `collect`s into a `Vec` for the time being.
2025-04-11 12:35:55 +02:00
Fintan Halpenny 7de82b5025 radicle: use `Alias` in `follow`
Ensure that the validated `Alias` type is used for inserting into the
policy database.
2025-04-11 12:35:55 +02:00
Fintan Halpenny 6940ac42be radicle: reverse lookup for AliasStore
Provide functionality to lookup the `NodeId`s associated with a given
`Alias`.

The use for this functionality is to allow callers to use aliases as
shorthands for `NodeId`s, but still refer to the exact identifier.

The implementation allows for searching using the `LIKE '%<pattern>%'`
queries in sqlite, so searches do not have to be exact matches.
2025-04-11 12:18:35 +02:00
Fintan Halpenny dd5f739630 radicle: generic Transaction::initial
The use of `Transaction` outside of the `radicle` crate requires that a newtype is used, if the upstream code wants to write methods, such as:

```
pub struct Transaction<R>(store::Transaction<MyCob, R>);

impl Transaction<R> {
  pub fn add_foo(&mut self, foo: Foo) -> Result<(), store::Error> { /* code */ }
  pub fn add_bar(&mut self, bar: Bar) -> Result<(), store::Error> { /* code */ }}
```

This works up until the point that it tries to re-use the
`Transaction::initial` method.

To make this possible, the method needs to know that it can be
converted to the upstream `Transaction` and back to `radicle`
`Transaction`.
2025-04-10 15:37:08 +02:00
Fintan Halpenny c2863c08ab radicle: extend emoji support
Extend the ranges of emojis that are supported, listed
[below](#new-emojis-supported).

To ensure that single `char` emojis are supported, the `emojis` crate
is added as a dev dependency, using it to check that a `Reaction` can
be constructed for the two groups `SmileysAndEmotion` and
`PeopleAndBody`.

### New Emojis Supported

'🩵' 0x1FA75
'🩶' 0x1FA76
'🩷' 0x1FA77
'🫀' 0x1FAC0
'🫁' 0x1FAC1
'🫂' 0x1FAC2
'🫃' 0x1FAC3
'🫄' 0x1FAC4
'🫅' 0x1FAC5
'🫆' 0x1FAC6
'🫠' 0x1FAE0
'🫡' 0x1FAE1
'🫢' 0x1FAE2
'🫣' 0x1FAE3
'🫤' 0x1FAE4
'🫥' 0x1FAE5
'🫦' 0x1FAE6
'🫨' 0x1FAE8
'🫩' 0x1FAE9
'🫰' 0x1FAF0
'🫱' 0x1FAF1
'🫲' 0x1FAF2
'🫳' 0x1FAF3
'🫴' 0x1FAF4
'🫵' 0x1FAF5
'🫶' 0x1FAF6
'🫷' 0x1FAF7
'🫸' 0x1FAF8
2025-04-10 15:18:31 +02:00
Fintan Halpenny 62d000f7cb radicle: fix `parse_ref_*` documentation
The `parse_ref` and `parse_ref_namespaced` documentation used 4 space
indentation for the reference names. Unfortunately, `cargo test` attempts to
interpret this as code.

Use triple-backtick code fencing, with `text` and `no_run`, instead.
2025-01-16 11:08:35 +00:00
Sebastian Martinez 985987468d
radicle: add `list_by_status` method to `cob::issue::Issues`
Provides the same `list_by_status` and `<status>` methods that
`cob::patch::Patches` has to `Issues`
2025-01-14 13:36:14 +01:00
Sebastian Martinez 7c902b6905
radicle: Add `resolves` and `labels` method to `cob::patch::Revision`
To be able to query the `BTreeSet` that shows which comments are
resolved by a specific revision and the `Iterator` of `Label` we require
some methods to obtain them.
2025-01-14 13:34:38 +01:00
Fintan Halpenny 6598243465
radicle: document `parse_ref` and `parse_ref_namespaced`
Provide better documentation for the two methods.

Solves the issue:
```
rad issue show 4603f55d97a0776f37bae2f9d2ba7d455d8a4c83
```

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2025-01-14 13:34:13 +01:00
Leah Neukirchen 41c33901ff
radicle: use rlim_t when working with limits
rlimit values have different types on Linux and FreeBSD, as well as
64-bit and 32-bit platforms, so stick to the type rlim_t provided by the
libc crate.
2025-01-14 13:29:03 +01:00
Lars Wirzenius 4c82bb4c4e
radicle: add some documentation for node::events::Event
Signed-off-by: Lars Wirzenius <liw@liw.fi>
2025-01-14 13:24:11 +01:00
Lars Wirzenius 2929146c49
radicle: clarify RefsAt description
Signed-off-by: Lars Wirzenius <liw@liw.fi>
2025-01-14 13:22:51 +01:00
cloudhead fd892d006f
Update `radicle` to 0.14 2024-11-29 15:25:09 +01:00
cloudhead 3ad84420bd
cli: Implement `rad cob migrate`
Adds the new `migrate` sub-command to migrate the COB database.
Checks for version when opening the COBs database and suggests the
command on out of date version.

Also adds the 2nd migration to the COBs cache, which updates the patch
JSON schema.
2024-11-22 21:27:45 +01:00
cloudhead 2d13591ec2
radicle: Fix flaky test `counts_by_repo` 2024-11-21 16:05:01 +01:00
Sebastian Martinez a7e96131ce
radicle: add notification count grouped by repo
While the total notification count and the notification count by repo
are needed, for most UIs users will want to see the total notification
count grouped by repo.

This new method will provide this without the need of checking all
possible repos to see if they have notifications.
2024-11-21 12:04:32 +01:00
Fintan Halpenny 259adf7dc2
cob: mutable stable time for testing
The `radicle-cob` crate provides a feature flag, `stable-commit-ids` to allow
for `Oid`s to remain stable for testing by always using the same author and
timestamp when creating commits.

This can be an issue when it interplays with COB related tests that are relying
on the ordering for the DAG walk. If the `Oid` values change and get re-ordered
then the test will fail. The DAG for COBs are now ordered via the `Oid` and
`Timestamp`.

In this change, a global timestamp is introduced that is initialised
per thread. The value is read, via `read_timestamp`, and can be
advanced using `with_advanced_timestamp` – while performing an action
that creates a new commit.
2024-11-18 16:11:44 +01:00
Fintan Halpenny 91914d9345
radicle: improve quorum copy
The `no quorum found` error can be opaque and lead to a lot of confusion. It is
better to give more information for this error so that it leads to easier
debugging, since it can be quite a common warning/error.

Instead of a single error, there are two cases provided: `NoCandidates` and
`Diverging`, to capture the two different variants of errors that can occur.

`Display` implementations are provided for both to provide more information.
2024-11-18 12:32:44 +01:00
cloudhead 6c8ee4330e
radicle: Implement migration callback mechanism
Add the ability to have native migrations and progress callback
functions in migration code for the COB cache.
2024-11-14 17:21:33 +01:00