Commit Graph

2368 Commits

Author SHA1 Message Date
Fintan Halpenny ce2d3eb071 radicle: Announcer test synced with unknown node
Adds a test case to show that the Announcer is allowed to mark an "unknown" node
as synced.

There may be a case where gossip reached a node that the current node was not
aware of. This should be allowed and should count towards the final replication
factor.
2025-08-13 11:09:49 +02:00
Fintan Halpenny ca7231e652 radicle: Announcer test adapting the replication target
The replication target should be constrained to the number of nodes to sync
with, if the original value exceeds that number.
2025-08-13 11:09:49 +02:00
Fintan Halpenny 685c84e598 radicle: Announcer with replication factor of 0
Ensures that the Announcer will still announce to preferred seeds when the
replication factor is 0.
2025-08-13 11:09:49 +02:00
Fintan Halpenny 4307eb35b5 radicle: Announcer test AlreadySynced for preferred seeds 2025-08-13 11:09:49 +02:00
Fintan Halpenny 376a5566c2 radicle: Announcer test preferred seeds only 2025-08-13 11:09:49 +02:00
Fintan Halpenny 84f11f5e31 radicle: Announcer ensures local node is ignored
Adds test cases to ensure that the local node is ignored from the announcement
process.
2025-08-13 11:09:49 +02:00
Fintan Halpenny 8a6e55502c radicle: Announcer can exit on preferred seeds or replication factor
The `Announcer` logic was subtly different to the fetching logic, where the
preferred seeds need to be announced to *and* the replication factor had to be
reached.

This patch relaxes that constraint, and allows it to hit either targets before
exiting.

This also surfaced an issue with the with the `Progress` calculation, where
calculating the `unsynced` used the `synced` value to subtract. However, this
was not required because `to_sync` is mutated, so the value is simply
`to_sync.len()`. A test case was added to ensure this is correct by checking
that invariant that the total between synced and unsynced nodes always matches
the total of synced and unsynced progress.
2025-08-13 11:09:49 +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
Fintan Halpenny 70009f7af2 release: 1.3.0 CHANGELOG 2025-08-12 12:13:49 +02:00
Lorenz Leutgeb 944d394247 node: Restrict use of systemd to Linux not Unix
Building with Zigbuild for macOS caused build issues. Strengthen the
condition for using systemd from the Unix family to Linux specifically.
2025-08-12 12:13:49 +02:00
Fintan Halpenny 11d29b280a nix: Update nix packages to 25.05 2025-08-12 08:38:57 +01:00
Fintan Halpenny a8dac56ca6 node: add radicle-protocol to dev-dependencies
If one attempted to compile the test target for `radicle-node` by itself, it
would result in a compiler error – due to missing trait implementations that are
provided by `radicle-protocol/test`.

It would compile fine when `--all` is used due to cargo unifying feature sets,
so it went unnoticed until now.

This fixes the issue by adding `radicle-protocol` to the `dev-dependencies` and
enabling the `test` feature flag.
2025-08-07 09:36:20 +01:00
Lorenz Leutgeb d7b48b9e29 radicle: Move logging setup calls to binaries 2025-08-07 08:30:59 +01:00
Lorenz Leutgeb b2a41025ce node: Enable logging via systemd journal 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 2776e003dc systemd: Move socket activation to module 2025-08-07 08:30:59 +01:00
Fintan Halpenny 7a9d4512f9 radicle: fix Canonical::quorum doc link 2025-08-05 15:00:26 +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
Lorenz Leutgeb 4934473b86 cli/node: Improve log rotation
Only the latest log was kept as `node.log.old`. Now, log files are
numbered (`node.log.1`, `node.log.2` and so on). Also `node.log` is now
a hard link to the current log file. `rad node stop` will delete
`node.log` (note that `node.log.x` stays intact) and `rad node start`
will delete `node.log` before it creates `node.log.y` in case the node
crashed.

Also, when running in foreground mode, now a log file is created. It
just contains the hint that the node was started in foreground mode,
just to avoid confusion.

The implementation is split into a sans I/O part as `struct LogRotator`,
while the I/O counterpart is captured by `struct LogRotatorFileSystem`.
2025-08-04 17:13:11 +02:00
Lorenz Leutgeb 3d352f23e6 canonical: Support Annotated Tags
The logic for computing canonical references conflated the semantics of
annotated and lighweight tags, yielding confusing/wrong results. The
main culprit was the call to `peel_to_commit` in
`impl ReadRepository for Repository`, peeling tag objects away.

To resolve this, we separate out quroum computation per object type: one
implementation for commits, and one for tags.

Also move  move canonical error types and methods into their own
module to have a cleaner file structure for the main logic.

Capture the `BTreeMap<Oid, u8>` type into a `Votes` struct, with its own API.

We were getting the objects from the repository twice – once in `Canonical::new`
and once again in `ensure_commit_or_tag` – so the latter was removed.

Use an `enum CanonicalObject` to specify which object types the canonical
process supports.

During `converges`, separate commits and tags, and ensure that we are only
looking at objects of one type. Note, that Fintan think this is actually the
*wrong* place to do it because we already filter the objects – so we should
keep track of that information higher up the callstack.

Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
2025-08-04 17:00:54 +02:00
Erik Kundt 54fd8c40a0 node: clean up logging
Do not print errors to stderr anymore if logger is not enabled
2025-07-30 13:41:17 +01:00
Fintan Halpenny 174792813a node: register backtrace
To better help debugging when things go wrong after `radicle-node` crashes,
`RUST_BACKTRACE` is registered in the `main`. According to this [StackOverflow
answer][so], this should not affect performance

[so]: https://stackoverflow.com/questions/29421727/how-much-overhead-does-rust-backtrace-1-have/45402131#45402131
2025-07-30 13:41:17 +01:00
Fintan Halpenny 0aaa81f82a cli: mention binary names as part of unknown
When we fail to get the info for the binary names of `radicle-node` and
`git-remote-rad`, we still mention the binary name which is usually a part of
their output.
2025-07-28 11:38:24 +01:00
Lorenz Leutgeb fdb1ac4e3a radicle: Fix clippy::result_large_err
After upgrading from Rust 1.85 to 1.88 in 586eefc, clippy started
warning about large error types. Box action to make
`radicle::cob::patch::Error` lighter.
2025-07-27 23:32:39 +02:00
Lorenz Leutgeb 5bab3f9cc0 clippy: Allow doc_overindented_list_items
After upgrading from Rust 1.85 to 1.88 in 586eefc3e4,
clippy now warns about "overindented" lines in comments. I did not
manage to fix this by hand without breaking the second level of the
lists in question.

See
 - https://rust-lang.github.io/rust-clippy/master/index.html#doc_overindented_list_items
 - https://github.com/rust-lang/rust-clippy/issues/14275
2025-07-27 23:32:02 +02:00
Lorenz Leutgeb 9068033789 chore: Automated fixes generated by clippy 2025-07-25 11:25:05 +02:00
Lorenz Leutgeb 586eefc3e4 rust-toolchain: 1.85 → 1.88 2025-07-24 17:43:12 +02:00
Sebastian Martinez efeefd0daa chore(debian/changelog): update package version to match upstream 2025-07-23 11:34:20 +02:00
Fintan Halpenny 2a47bc0c7d term: provide default HELP message
Provide a default message that informs the user of the `(e)`, `(enter)`, and
`(esc)` functionality.

Unfortunately, it is not possible to provide any message that is better
customised to each case, due to `inquire` requiring a `'a` lifetime on all its
inputs – this rules out providing any kind of `String` input.

The first paramter of `Editor::new` can already be used to provide more
contextual information. The second parameter is left configurable, but for now
`Editor::HELP` is used everywhere.
2025-07-23 10:31:15 +02:00
Fintan Halpenny a998ce691d ssh: provide path on connect error
Provide the path that is being used for connecting to the SSH agent, when an I/O
error occurs.
2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 8224819fed radicle/profile: Enable home detection on Windows
To avoid that users on Windows have to explcitly set `HOME`, also accept
`USERPROFILE` which is considered equivalent.

To avoid repeating to join `.radicle`, split the logic up into two
phases. Also take care to provide a good error message, as this error is
fatal and user-facing.
2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 1e0a14ddcf ssh: Remove dependency on log 2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 8e6279a382 ssh: Remove dependency on byteorder 2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 95b3303eb9 term: Remove unused dependency shlex 2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 009436efac ssh: Use winpipe for SSH agent on Windows
The trait `radicle_ssh::agent::client::ClientStream` trait was
simplified, because `winpipe::WinStream` is so similar to
`std::os::unix::net::UnixStream` that we can just use the same
implementation for both platforms.

However, obtaining the process identifier of the SSH agent process is
not common on Windows, so we instead track the path that we used to
connect to the agent. This is also helpful on Unix. In some cases, the
path will even contain the process identifier. The path is printed by
`rad self`.

Errors are cleaned up, and error messages are improved.
2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 0705501537 radicle: Depend on winpipe for Windows support 2025-07-23 10:31:15 +02:00
Lorenz Leutgeb 08b535d567 radicle: Only set file limits on Unix 2025-07-23 10:31:13 +02:00
Lorenz Leutgeb e7fb5647ac term: Remove dependency on libc
Introducing the new enum `TerminalFile` to model which standard stream
stream the terminal uses allows us to remove the dependency on `libc`
which does not build on Windows.
2025-07-23 10:30:33 +02:00
Lorenz Leutgeb 70fb0d3fef term: Use inquire for spawning the editor
`radicle-term` includes quite a lot of rather "low-level" logic to spawn
the preferred editor of the user. In particular, this logic is
platform-dependent and only works on Unix-like platforms.

Also, `radicle-term` already depends on `inquire` which features an
editor prompt. It is a cross-platform solution to spawn the editor.
This commit changes the implementation of `Editor` to be a wrapper of
`inquire::Editor`, keeping the interface mostly intact.

Downsides:
 - We cannot edit a file "in place" this way, instead we have to read
   it, as `inquire` only supports editing temporary files. This can also
   be viewed as a benefit, as we lessen the risk of corruption of these
   files.
 - `inquire::Editor` contains borrows, so it is quite cumbersome to
   extend it with a custom mechanism for looking up the preferred
   editor. The lookup logic was kept, but needs to be invoked by the
   caller. In the future we might consider just using the logic provided
   by `inquire` or requesting a change to `inquire`.
 - The prompt is a bit strange. It does not show the current state of
   the output, see <https://github.com/mikaelmello/inquire/issues/280>
   and <https://github.com/mikaelmello/inquire/pull/271>.
2025-07-23 10:30:33 +02:00
Lorenz Leutgeb a28fd65e89 term/ansi: Remove unused Windows module 2025-07-23 10:30:33 +02:00
Lorenz Leutgeb d46d36ecee term/spinner: Only handle signals on Unix
The `radicle-signals` crate only supports Unix, so using it prevents
`radicle-term` to build on Windows.

Of course, this means that non-Unix platforms will not support any
signal handling at all, but at least we can build.
2025-07-23 10:30:33 +02:00
Lorenz Leutgeb 92d77f9ec3 crypto/ssh/keystore: Reduce scope of DirBuilderExt
Directory builder extensions are platform specific and only available on
Unix. Move their use into a conditionally compiled block, so that we can
build on Windows.
2025-07-23 10:30:33 +02:00
Sekhat Temporus 37ea81766e cli: improve default branch pick
When using `rad init` the default branch for the project can be predetermined by
inspecting the working copy repository.

To improve the experience, it will first check `init.defaultBranch` in the Git
configuration file.

If it does not find this, it falls back to choosing the default head of the
repository at the time. This may be HEAD, and in this case it will error and
provide helpful information.

The repository may also not have any default head at the time, and this also
results in an error and hint.
2025-07-23 07:43:27 +01:00
Ivan Stanković 85ddcace0a docs: fix installation instructions in README.md
Crates have been moved, so make sure the paths are correct.
2025-07-20 15:33:12 +00:00
Tobias Hunger 7c4b71ab82 radicle: Keep pinned repos ordered in config
Do not return them in a random order in radicle-httpd,
so that we can have them in a defined order in
radicle-explorer.
2025-07-19 12:59:02 +01:00
Fintan Halpenny 1fa30e2e88 cli: test missing commits for canonical quorum
Test the scenario where 2 delegates are collaborating, where one delegate is
missing the other's commit while pushing to the default branch.
2025-07-19 12:32:45 +01:00
Fintan Halpenny afe64d5175 remote-helper: improve canonical handling
This set of changes refactors the canonical handling by isolating the business
logic into another type, `Canonical`.

The functionality remains the same, but certain error scenarios are better
handled. Primarily, the commits of the inner `Canonical` type are checked to see
if they exist in the working copy, and if not, provide a more useful message
about which commit was missing or invalid for which DID.
2025-07-19 12:32:31 +01:00
Fintan Halpenny 14444a43ea remote-helper: refactor pushing action
Reduce the nesting of if statements by using a `PushAction` enum that is
constructed by checking the `dst` reference and parsing the correct action, one
of:

- `OpenPatch`
- `UpdatePatch`
- `PushRef`

This makes the intent of the code a little bit more clear and reduces the tabbing
of big code blocks. It also captures the error specifically for handling the
parsing of this `dst` reference.
2025-07-19 10:53:51 +01:00
Tobias Hunger a9f75d47ec remote-helper: allow any revision in push src
This allows any revision that can resolve to an object. The `src` side of the
refspec is resolved to its corresponding `Oid` which is further used for remote
helper pushing and patch creation/update.

Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
2025-07-18 22:22:43 +01:00