qtcloud-devops-cli 0.9.3

量潮DevOps云命令行工具
Documentation
use std::path::PathBuf;
use std::process::Command;

use qtcloud_devops_cli::git::GitSubmoduleEditor;

fn git_init(path: &std::path::Path) {
    Command::new("git")
        .args(["init"])
        .current_dir(path)
        .output()
        .unwrap();
    Command::new("git")
        .args(["config", "user.email", "test@test.com"])
        .current_dir(path)
        .output()
        .unwrap();
    Command::new("git")
        .args(["config", "user.name", "Test"])
        .current_dir(path)
        .output()
        .unwrap();
}

fn git_commit(path: &std::path::Path, msg: &str) {
    std::fs::write(path.join("file"), msg).unwrap();
    Command::new("git")
        .args(["add", "."])
        .current_dir(path)
        .output()
        .unwrap();
    Command::new("git")
        .args(["commit", "-m", msg])
        .current_dir(path)
        .output()
        .unwrap();
}

fn setup_repo_with_submodule(tmp: &std::path::Path) -> PathBuf {
    let parent = tmp.join("parent");
    let sub = tmp.join("sub");
    std::fs::create_dir_all(&sub).unwrap();
    Command::new("git")
        .args(["init"])
        .current_dir(&sub)
        .output()
        .unwrap();
    Command::new("git")
        .args(["config", "user.email", "test@test.com"])
        .current_dir(&sub)
        .output()
        .unwrap();
    Command::new("git")
        .args(["config", "user.name", "Test"])
        .current_dir(&sub)
        .output()
        .unwrap();
    std::fs::write(sub.join("file"), "init sub").unwrap();
    Command::new("git")
        .args(["add", "."])
        .current_dir(&sub)
        .output()
        .unwrap();
    Command::new("git")
        .args(["commit", "-m", "init sub"])
        .current_dir(&sub)
        .output()
        .unwrap();
    std::fs::create_dir_all(&parent).unwrap();
    Command::new("git")
        .args(["init"])
        .current_dir(&parent)
        .output()
        .unwrap();
    Command::new("git")
        .args(["config", "user.email", "test@test.com"])
        .current_dir(&parent)
        .output()
        .unwrap();
    Command::new("git")
        .args(["config", "user.name", "Test"])
        .current_dir(&parent)
        .output()
        .unwrap();
    std::fs::write(parent.join("file"), "init parent").unwrap();
    Command::new("git")
        .args(["add", "."])
        .current_dir(&parent)
        .output()
        .unwrap();
    Command::new("git")
        .args(["commit", "-m", "init parent"])
        .current_dir(&parent)
        .output()
        .unwrap();
    Command::new("git")
        .args(["submodule", "add", &sub.to_string_lossy(), "libs/sub"])
        .current_dir(&parent)
        .output()
        .unwrap();
    Command::new("git")
        .args(["commit", "-m", "add submodule"])
        .current_dir(&parent)
        .output()
        .unwrap();
    parent
}

fn editor_sync(root: &std::path::Path, name: &str) -> Result<(), Box<dyn std::error::Error>> {
    GitSubmoduleEditor::new(root.to_path_buf()).sync_to_parent(name)
}

fn editor_sync_all(root: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
    GitSubmoduleEditor::new(root.to_path_buf()).sync_all_to_parent()
}

#[test]
fn test_integration_scan_submodule() {
    let t = tempfile::tempdir().unwrap();
    let p = setup_repo_with_submodule(t.path());
    let s = qtcloud_devops_cli::git::RepoState::scan(&p).unwrap();
    assert_eq!(s.total, 1);
    assert_eq!(s.submodules[0].name, "libs/sub");
}
#[test]
fn test_integration_scan_no_gitmodules() {
    assert!(
        qtcloud_devops_cli::git::RepoState::scan(&tempfile::tempdir().unwrap().path()).is_err()
    );
}
#[test]
fn test_integration_sync_submodule() {
    let t = tempfile::tempdir().unwrap();
    assert!(editor_sync(&setup_repo_with_submodule(t.path()), "libs/sub").is_ok());
}
#[test]
fn test_integration_sync_nonexistent() {
    let t = tempfile::tempdir().unwrap();
    git_init(t.path());
    git_commit(t.path(), "init");
    assert!(editor_sync(t.path(), "no-such-module").is_err());
}
#[test]
fn test_integration_sync_all() {
    let t = tempfile::tempdir().unwrap();
    assert!(editor_sync_all(&setup_repo_with_submodule(t.path())).is_ok());
}
#[test]
fn test_integration_sync_all_no_submodules() {
    let t = tempfile::tempdir().unwrap();
    git_init(t.path());
    git_commit(t.path(), "init");
    assert!(editor_sync_all(t.path()).is_ok());
}
#[test]
fn test_integration_status_clean_submodule() {
    let t = tempfile::tempdir().unwrap();
    assert!(GitSubmoduleEditor::new(setup_repo_with_submodule(t.path()))
        .status()
        .unwrap()
        .is_empty());
}
#[test]
fn test_integration_status_not_a_repo() {
    let t = tempfile::tempdir().unwrap();
    std::fs::write(t.path().join(".gitmodules"), "").unwrap();
    assert!(GitSubmoduleEditor::new(t.path().to_path_buf())
        .status()
        .is_err());
}
#[test]
fn test_integration_sync_fails_without_submodule_repo() {
    let t = tempfile::tempdir().unwrap();
    git_init(t.path());
    git_commit(t.path(), "init");
    assert!(GitSubmoduleEditor::new(t.path().to_path_buf())
        .sync_to_parent("no-such-module")
        .is_err());
}
#[test]
fn test_integration_sync_all_on_repo_without_submodules() {
    let t = tempfile::tempdir().unwrap();
    git_init(t.path());
    git_commit(t.path(), "init");
    assert!(GitSubmoduleEditor::new(t.path().to_path_buf())
        .sync_all_to_parent()
        .is_ok());
}
#[test]
fn test_integration_status_with_fetch() {
    let t = tempfile::tempdir().unwrap();
    let mut e = GitSubmoduleEditor::new(setup_repo_with_submodule(t.path()));
    e.set_offline(true);
    assert!(e.status().unwrap().is_empty());
}