cli/init: Allow `--setup-signing` with bare repos

The `--setup-signing` flag is a no-op when combined with `--existing`
and errors on bare repositories.

Make it effective in combination with `--existing` and also rewrite it
to support bare repositories, gracefully falling back to just avoid
writing to `.gitsigners`.
This commit is contained in:
Lorenz Leutgeb 2025-09-12 11:17:17 +02:00 committed by Fintan Halpenny
parent fd93240b9d
commit 6b9ff4f99e
4 changed files with 47 additions and 16 deletions

View File

@ -15,9 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `rad clone` now supports the flag `--bare` which works analoguously to - `rad clone` now supports the flag `--bare` which works analoguously to
`git clone --bare`. `git clone --bare`.
- `rad init --setup-signing` now works on bare repositories.
## Fixed Bugs ## Fixed Bugs
- `rad init --setup-signing` now works in combination with `--existing`.
## 1.4.0 ## 1.4.0
## Release Highlights ## Release Highlights

View File

@ -20,10 +20,18 @@ rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
And initialize this working copy as that existing repository: And initialize this working copy as that existing repository:
``` ```
$ rad init --existing rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji $ rad init --setup-signing --existing rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
Configuring radicle signing key SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA...
✓ Signing configured in [..]/heartwood/config
! Not writing .gitsigners file.
✓ Initialized existing repository rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji in [..]/heartwood/.. ✓ Initialized existing repository rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji in [..]/heartwood/..
``` ```
The warning about not writing `.gitsigners` is expected, as this requires a
working directory, which a bare repository does not have.
We can confirm that the working copy is initialized: We can confirm that the working copy is initialized:
``` ```
$ rad . $ rad .

View File

@ -20,7 +20,12 @@ rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
And initialize this working copy as that existing repository: And initialize this working copy as that existing repository:
``` ```
$ rad init --existing rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji $ rad init --setup-signing --existing rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
Configuring radicle signing key SHA256:UIedaL6Cxm6OUErh9GQUzzglSk7VpQlVTI1TAFB/HWA...
✓ Signing configured in [..]/heartwood/.git/config
✓ Created .gitsigners file
✓ Initialized existing repository rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji in [..]/heartwood/.. ✓ Initialized existing repository rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji in [..]/heartwood/..
``` ```

View File

@ -403,6 +403,11 @@ pub fn init_existing(
)?; )?;
} }
if options.setup_signing {
// Setup radicle signing key.
self::setup_signing(profile.id(), &working, options.interactive)?;
}
term::success!( term::success!(
"Initialized existing repository {} in {}..", "Initialized existing repository {} in {}..",
term::format::tertiary(rid), term::format::tertiary(rid),
@ -633,11 +638,13 @@ pub fn setup_signing(
repo: &git::Repository, repo: &git::Repository,
interactive: Interactive, interactive: Interactive,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let repo = repo const SIGNERS: &str = ".gitsigners";
.workdir()
.ok_or(anyhow!("cannot setup signing in bare repository"))?; let path = repo.path();
let config = path.join("config");
let key = ssh::fmt::fingerprint(node_id); let key = ssh::fmt::fingerprint(node_id);
let yes = if !git::is_signing_configured(repo)? { let yes = if !git::is_signing_configured(path)? {
term::headline(format!( term::headline(format!(
"Configuring radicle signing key {}...", "Configuring radicle signing key {}...",
term::format::tertiary(key) term::format::tertiary(key)
@ -645,14 +652,25 @@ pub fn setup_signing(
true true
} else if interactive.yes() { } else if interactive.yes() {
term::confirm(format!( term::confirm(format!(
"Configure radicle signing key {} in local checkout?", "Configure radicle signing key {} in {}?",
term::format::tertiary(key), term::format::tertiary(key),
term::format::tertiary(config.display()),
)) ))
} else { } else {
true true
}; };
if yes { if !yes {
return Ok(());
}
git::configure_signing(path, node_id)?;
term::success!(
"Signing configured in {}",
term::format::tertiary(config.display())
);
if let Some(repo) = repo.workdir() {
match git::write_gitsigners(repo, [node_id]) { match git::write_gitsigners(repo, [node_id]) {
Ok(file) => { Ok(file) => {
git::ignore(repo, file.as_path())?; git::ignore(repo, file.as_path())?;
@ -661,11 +679,11 @@ pub fn setup_signing(
} }
Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => { Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => {
let ssh_key = ssh::fmt::key(node_id); let ssh_key = ssh::fmt::key(node_id);
let gitsigners = term::format::tertiary(".gitsigners"); let gitsigners = term::format::tertiary(SIGNERS);
term::success!("Found existing {} file", gitsigners); term::success!("Found existing {} file", gitsigners);
let ssh_keys = let ssh_keys =
git::read_gitsigners(repo).context("error reading .gitsigners file")?; git::read_gitsigners(repo).context(format!("error reading {SIGNERS} file"))?;
if ssh_keys.contains(&ssh_key) { if ssh_keys.contains(&ssh_key) {
term::success!("Signing key is already in {gitsigners} file"); term::success!("Signing key is already in {gitsigners} file");
@ -677,13 +695,10 @@ pub fn setup_signing(
return Err(err.into()); return Err(err.into());
} }
} }
git::configure_signing(repo, node_id)?; } else {
term::notice!("Not writing {SIGNERS} file.")
term::success!(
"Signing configured in {}",
term::format::tertiary(".git/config")
);
} }
Ok(()) Ok(())
} }