fluidattacks-core-git 0.47.0

Fluid Attacks Core Git
Documentation
use anyhow::Result;
use std::path::Path;

use super::types::RebaseResult;
use crate::cli;

pub async fn rebase(
    repo: &Path,
    file: &Path,
    line: usize,
    rev_a: &str,
    rev_b: &str,
) -> Result<Option<RebaseResult>> {
    let Some(blame) = cli::blame_reverse(repo, file, line, rev_a, rev_b, true).await? else {
        return Ok(None);
    };

    let path = if blame.path.as_os_str().is_empty() {
        file.to_path_buf()
    } else {
        blame.path
    };

    Ok(Some(RebaseResult {
        path,
        line: blame.line,
        rev: blame.rev,
    }))
}

#[cfg(test)]
mod tests {
    use super::rebase;
    use std::path::{Path, PathBuf};

    fn run(repo: &Path, args: &[&str]) -> String {
        let output = std::process::Command::new("git")
            .arg("-C")
            .arg(repo)
            .arg("-c")
            .arg("user.email=dev@fluidattacks.com")
            .arg("-c")
            .arg("user.name=dev")
            .args(args)
            .output()
            .unwrap();
        assert!(output.status.success(), "git {args:?} failed");
        String::from_utf8(output.stdout).unwrap().trim().to_owned()
    }

    #[tokio::test]
    async fn a_line_that_moved_to_a_renamed_file_is_reported_at_its_new_home() {
        let dir = tempfile::tempdir().unwrap();
        std::env::set_var("GIT_CONFIG_GLOBAL", dir.path().join("gitconfig"));

        let repo = dir.path().join("repo");
        std::fs::create_dir_all(&repo).unwrap();
        run(&repo, &["init", "-q"]);
        std::fs::write(repo.join("old.txt"), b"first\nsecond\nthird\n").unwrap();
        run(&repo, &["add", "-A"]);
        run(&repo, &["commit", "-q", "-m", "add"]);
        let rev_a = run(&repo, &["rev-parse", "HEAD"]);

        run(&repo, &["mv", "old.txt", "new.txt"]);
        run(&repo, &["commit", "-q", "-m", "rename"]);
        let head = run(&repo, &["rev-parse", "HEAD"]);

        let result = rebase(&repo, Path::new("old.txt"), 2, &rev_a, "HEAD")
            .await
            .unwrap()
            .unwrap();

        assert_eq!(result.path, PathBuf::from("new.txt"));
        assert_eq!(result.line, 2);
        assert_eq!(result.rev, head);
    }
}