cli: remove the 'rad' remote during `rad rm`
If the 'rad' remote is still in the git config, then some of the CLI tooling will think the project exists -- even after running `rad rm`. For example, in the current state, if `rad rm` is followed by `rad init` then the operation will fail. During `rad rm`, attempt to delete the 'rad' remote. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
c49412a73f
commit
2ff6bf2fc4
|
|
@ -11,6 +11,7 @@ Now let's delete the `heartwood` project:
|
|||
```
|
||||
$ rad rm rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --no-confirm
|
||||
✓ Untracked rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||
✓ Successfully removed 'rad' remote
|
||||
✓ Successfully removed rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from storage
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ use anyhow::anyhow;
|
|||
use radicle::identity::Id;
|
||||
use radicle::node;
|
||||
use radicle::node::Handle as _;
|
||||
use radicle::storage;
|
||||
use radicle::Profile;
|
||||
|
||||
use crate::git;
|
||||
use crate::terminal as term;
|
||||
use crate::terminal::args::{Args, Error, Help};
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let profile = ctx.profile()?;
|
||||
let storage = &profile.storage;
|
||||
let rid = options.rid;
|
||||
let path = radicle::storage::git::paths::repository(storage, &rid);
|
||||
let path = storage::git::paths::repository(storage, &rid);
|
||||
|
||||
if !path.exists() {
|
||||
anyhow::bail!("repository {rid} was not found");
|
||||
|
|
@ -79,6 +81,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
|
||||
if !options.confirm || term::confirm(format!("Remove {rid}?")) {
|
||||
untrack(&rid, &profile)?;
|
||||
remove_remote(&rid)?;
|
||||
fs::remove_dir_all(path)?;
|
||||
term::success!("Successfully removed {rid} from storage");
|
||||
}
|
||||
|
|
@ -106,3 +109,20 @@ fn untrack(rid: &Id, profile: &Profile) -> anyhow::Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_remote(rid: &Id) -> anyhow::Result<()> {
|
||||
let cwd = std::env::current_dir()?;
|
||||
if let Err(e) = git::Repository::open(cwd)
|
||||
.map_err(|err| err.into())
|
||||
.and_then(|repo| git::remove_remote(&repo, rid))
|
||||
{
|
||||
term::warning(&format!(
|
||||
"Attempted to remove 'rad' remote from working copy: {e}"
|
||||
));
|
||||
term::warning("In case a working copy exists, make sure to `git remote remove rad`");
|
||||
} else {
|
||||
term::success!("Successfully removed 'rad' remote");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,28 @@ pub fn rad_remote(repo: &Repository) -> anyhow::Result<(git2::Remote, Id)> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_remote(repo: &Repository, rid: &Id) -> anyhow::Result<()> {
|
||||
// N.b. ensure that we are removing the remote for the correct RID
|
||||
match radicle::rad::remote(repo) {
|
||||
Ok((_, rid_)) => {
|
||||
if rid_ != *rid {
|
||||
return Err(radicle::rad::RemoteError::RidMismatch {
|
||||
found: rid_,
|
||||
expected: *rid,
|
||||
}
|
||||
.into());
|
||||
}
|
||||
}
|
||||
Err(radicle::rad::RemoteError::NotFound(_)) => return Ok(()),
|
||||
Err(err) => return Err(err).context("could not read git remote configuration"),
|
||||
};
|
||||
|
||||
match radicle::rad::remove_remote(repo) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(err) => Err(err).context("could not read git remote configuration"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_remote<'a>(
|
||||
repo: &'a Repository,
|
||||
name: &'a str,
|
||||
|
|
|
|||
|
|
@ -265,6 +265,8 @@ pub enum RemoteError {
|
|||
InvalidUtf8,
|
||||
#[error("remote `{0}` not found")]
|
||||
NotFound(String),
|
||||
#[error("expected remote for {expected} but found {found}")]
|
||||
RidMismatch { found: Id, expected: Id },
|
||||
}
|
||||
|
||||
/// Get the radicle ("rad") remote of a repository, and return the associated project id.
|
||||
|
|
@ -282,6 +284,18 @@ pub fn remote(repo: &git2::Repository) -> Result<(git2::Remote<'_>, Id), RemoteE
|
|||
Ok((remote, url.repo))
|
||||
}
|
||||
|
||||
/// Delete the radicle ("rad") remote of a repository.
|
||||
pub fn remove_remote(repo: &git2::Repository) -> Result<(), RemoteError> {
|
||||
repo.remote_delete(&REMOTE_NAME).map_err(|e| {
|
||||
if e.code() == git2::ErrorCode::NotFound {
|
||||
RemoteError::NotFound(REMOTE_NAME.to_string())
|
||||
} else {
|
||||
RemoteError::from(e)
|
||||
}
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the Id of project in current working directory
|
||||
pub fn cwd() -> Result<(git2::Repository, Id), RemoteError> {
|
||||
let repo = git2::Repository::open(Path::new("."))?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue