Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add `rad-push`
Alexis Sellier committed 3 years ago
commit 51e18c27fce03d536df9c797b289d364b6727368
parent a3bf5ab7c3c6df038bb49e72073a9e43f89ad92d
6 files changed +73 -9
modified radicle-tools/Cargo.toml
@@ -23,3 +23,7 @@ path = "src/rad-auth.rs"
[[bin]]
name = "rad-self"
path = "src/rad-self.rs"
+

+
[[bin]]
+
name = "rad-push"
+
path = "src/rad-push.rs"
added radicle-tools/src/rad-push.rs
@@ -0,0 +1,19 @@
+
use std::path::Path;
+

+
use radicle::storage::WriteStorage;
+

+
fn main() -> anyhow::Result<()> {
+
    let cwd = Path::new(".").canonicalize()?;
+
    let repo = radicle::git::raw::Repository::open(&cwd)?;
+
    let profile = radicle::Profile::load()?;
+
    let (_, id) = radicle::rad::remote(&repo)?;
+

+
    let output = radicle::git::run(&cwd, &["push", "rad"])?;
+
    println!("{}", output);
+

+
    let project = profile.storage.repository(&id)?;
+
    let sigrefs = profile.storage.sign_refs(&project, &profile.signer)?;
+
    println!("ok: {}", sigrefs.signature);
+

+
    Ok(())
+
}
modified radicle/src/git.rs
@@ -1,4 +1,6 @@
+
use std::io;
use std::path::Path;
+
use std::process::Command;
use std::str::FromStr;

use git_ref_format as format;
@@ -238,3 +240,25 @@ pub fn set_upstream(

    Ok(())
}
+

+
/// Execute a git command by spawning a child process.
+
pub fn run<P: AsRef<Path>, S: AsRef<std::ffi::OsStr>>(
+
    repo: &P,
+
    args: impl IntoIterator<Item = S>,
+
) -> Result<String, io::Error> {
+
    let output = Command::new("git").current_dir(repo).args(args).output()?;
+

+
    if output.status.success() {
+
        let out = if output.stdout.is_empty() {
+
            &output.stderr
+
        } else {
+
            &output.stdout
+
        };
+
        return Ok(String::from_utf8_lossy(out).into());
+
    }
+

+
    Err(io::Error::new(
+
        io::ErrorKind::Other,
+
        String::from_utf8_lossy(&output.stderr),
+
    ))
+
}
modified radicle/src/rad.rs
@@ -1,6 +1,7 @@
#![allow(clippy::let_unit_value)]
use std::io;
use std::path::Path;
+
use std::str::FromStr;

use thiserror::Error;

@@ -57,7 +58,7 @@ pub fn init<G: Signer, S: storage::WriteStorage>(
    )
    .verified()?;

-
    let (id, _, project) = doc.create(pk, "Initialize Radicle", storage)?;
+
    let (id, _, project) = doc.create(pk, "Initialize Radicle\n", storage)?;
    let url = storage.url(&id);

    git::set_upstream(
@@ -299,6 +300,18 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
    Ok(repo)
}

+
/// Get the radicle ("rad") remote of a repository, and return the associated project id.
+
pub fn remote(repo: &git2::Repository) -> Result<(git2::Remote<'_>, Id), git2::Error> {
+
    let remote = repo.find_remote(REMOTE_NAME)?;
+
    let url = remote.url_bytes();
+
    let url = git::Url::from_bytes(url).unwrap();
+
    let path = url.path.to_string();
+
    let id = path.split('/').last().unwrap();
+
    let id = Id::from_str(id).unwrap();
+

+
    Ok((remote, id))
+
}
+

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
modified radicle/src/storage/git.rs
@@ -91,13 +91,7 @@ impl WriteStorage for Storage {
        repository: &Repository,
        signer: G,
    ) -> Result<SignedRefs<Verified>, Error> {
-
        let remote = signer.public_key();
-
        let refs = repository.references(remote)?;
-
        let signed = refs.signed(&signer)?;
-

-
        signed.save(remote, repository)?;
-

-
        Ok(signed)
+
        repository.sign_refs(signer)
    }

    fn fetch(&self, proj_id: &Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError> {
@@ -370,6 +364,16 @@ impl Repository {
        );
        Ok(remotes)
    }
+

+
    pub fn sign_refs<G: Signer>(&self, signer: G) -> Result<SignedRefs<Verified>, Error> {
+
        let remote = signer.public_key();
+
        let refs = self.references(remote)?;
+
        let signed = refs.signed(&signer)?;
+

+
        signed.save(remote, self)?;
+

+
        Ok(signed)
+
    }
}

impl ReadRepository for Repository {
modified radicle/src/storage/refs.rs
@@ -288,7 +288,7 @@ impl SignedRefs<Verified> {
            Some(&sigref),
            &author,
            &author,
-
            &format!("Update {} for {}", sigref, remote),
+
            &format!("Update signature for {}\n", remote),
            &tree,
            &parent.iter().collect::<Vec<&git2::Commit>>(),
        );