Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: remove the 'rad' remote during `rad rm`
Fintan Halpenny committed 3 years ago
commit 2ff6bf2fc47b191d614c95f4f6b20a448927dc1a
parent c49412a73fef2233473f9ffe5fd62b12301c52f4
4 files changed +58 -1
modified radicle-cli/examples/rad-rm.md
@@ -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
```

modified radicle-cli/src/commands/rm.rs
@@ -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(())
+
}
modified radicle-cli/src/git.rs
@@ -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,
modified radicle/src/rad.rs
@@ -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("."))?;