Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;

use swirl::PerformError;
use tempfile::TempDir;
use url::Url;

Expand Down Expand Up @@ -197,8 +196,11 @@ impl Repository {
/// - If cloning the crate index fails.
/// - If reading the global git config fails.
///
pub fn open(repository_config: &RepositoryConfig) -> Result<Self, PerformError> {
let checkout_path = tempfile::Builder::new().prefix("git").tempdir()?;
pub fn open(repository_config: &RepositoryConfig) -> anyhow::Result<Self> {
let checkout_path = tempfile::Builder::new()
.prefix("git")
.tempdir()
.context("Failed to create temporary directory")?;

let repository = git2::build::RepoBuilder::new()
.fetch_options(Self::fetch_options(&repository_config.credentials))
Expand All @@ -213,13 +215,21 @@ impl Repository {
.clone(
repository_config.index_location.as_str(),
checkout_path.path(),
)?;
)
.context("Failed to clone index repository")?;

// All commits to the index registry made through crates.io will be made by bors, the Rust
// community's friendly GitHub bot.
let mut cfg = repository.config()?;
cfg.set_str("user.name", "bors")?;
cfg.set_str("user.email", "[email protected]")?;

let mut cfg = repository
.config()
.context("Failed to read git configuration")?;

cfg.set_str("user.name", "bors")
.context("Failed to set user name")?;

cfg.set_str("user.email", "[email protected]")
.context("Failed to set user email address")?;

Ok(Self {
checkout_path,
Expand Down Expand Up @@ -260,16 +270,18 @@ impl Repository {
///
/// - If the `HEAD` pointer can't be retrieved.
///
pub fn head_oid(&self) -> Result<git2::Oid, PerformError> {
Ok(self.repository.head()?.target().unwrap())
pub fn head_oid(&self) -> anyhow::Result<git2::Oid> {
let repo = &self.repository;
let head = repo.head().context("Failed to read HEAD reference")?;
Ok(head.target().unwrap())
}

/// Commits the specified file with the specified commit message and pushes
/// the commit to the `master` branch on the `origin` remote.
///
/// Note that `modified_file` expects a file path **relative** to the
/// repository working folder!
fn perform_commit_and_push(&self, msg: &str, modified_file: &Path) -> Result<(), PerformError> {
fn perform_commit_and_push(&self, msg: &str, modified_file: &Path) -> anyhow::Result<()> {
// git add $file
let mut index = self.repository.index()?;
index.add_path(modified_file)?;
Expand All @@ -288,7 +300,7 @@ impl Repository {
}

/// Push the current branch to the provided refname
fn push(&self, refspec: &str) -> Result<(), PerformError> {
fn push(&self, refspec: &str) -> anyhow::Result<()> {
let mut ref_status = Ok(());
let mut callback_called = false;
{
Expand All @@ -299,7 +311,7 @@ impl Repository {
});
callbacks.push_update_reference(|_, status| {
if let Some(s) = status {
ref_status = Err(format!("failed to push a ref: {}", s).into())
ref_status = Err(anyhow!("failed to push a ref: {}", s))
}
callback_called = true;
Ok(())
Expand All @@ -310,7 +322,7 @@ impl Repository {
}

if !callback_called {
ref_status = Err("update_reference callback was not called".into());
ref_status = Err(anyhow!("update_reference callback was not called"));
}

ref_status
Expand All @@ -323,7 +335,7 @@ impl Repository {
///
/// This function also prints the commit message and a success or failure
/// message to the console.
pub fn commit_and_push(&self, message: &str, modified_file: &Path) -> Result<(), PerformError> {
pub fn commit_and_push(&self, message: &str, modified_file: &Path) -> anyhow::Result<()> {
println!("Committing and pushing \"{}\"", message);

let relative_path = modified_file.strip_prefix(self.checkout_path.path())?;
Expand All @@ -337,7 +349,7 @@ impl Repository {

/// Fetches any changes from the `origin` remote and performs a hard reset
/// to the tip of the `origin/master` branch.
pub fn reset_head(&self) -> Result<(), PerformError> {
pub fn reset_head(&self) -> anyhow::Result<()> {
let mut origin = self.repository.find_remote("origin")?;
let original_head = self.head_oid()?;
origin.fetch(
Expand Down Expand Up @@ -371,7 +383,7 @@ impl Repository {
}

/// Reset `HEAD` to a single commit with all the index contents, but no parent
pub fn squash_to_single_commit(&self, msg: &str) -> Result<(), PerformError> {
pub fn squash_to_single_commit(&self, msg: &str) -> anyhow::Result<()> {
let tree = self.repository.find_commit(self.head_oid()?)?.tree()?;
let sig = self.repository.signature()?;

Expand All @@ -393,7 +405,7 @@ impl Repository {
///
/// This function also temporarily sets the `GIT_SSH_COMMAND` environment
/// variable to ensure that `git push` commands are able to succeed.
pub fn run_command(&self, command: &mut Command) -> Result<(), PerformError> {
pub fn run_command(&self, command: &mut Command) -> anyhow::Result<()> {
let checkout_path = self.checkout_path.path();
command.current_dir(checkout_path);

Expand All @@ -409,8 +421,7 @@ impl Repository {
let output = command.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
let message = format!("Running git command failed with: {}", stderr);
return Err(message.into());
return Err(anyhow!("Running git command failed with: {}", stderr));
}

Ok(())
Expand Down
4 changes: 3 additions & 1 deletion src/worker/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ pub fn add_crate(env: &Environment, krate: Crate) -> Result<(), PerformError> {

let message: String = format!("Updating crate `{}#{}`", krate.name, krate.vers);

repo.commit_and_push(&message, &dst)
repo.commit_and_push(&message, &dst)?;

Ok(())
}

/// Yanks or unyanks a crate version. This requires finding the index
Expand Down