OXYGENHUB
◆ main oxygen / tests / cli_colocate.rs
3.3 KiB · Rust · last changed oxy git colocate: a .git beside .oxy, kept up to date after every command; .git is never content and never written by checkout (closes #160) 3 days ago source blame history raw
1
//! `oxy git colocate` (oxygenhub#355, part two): a `.git` beside `.oxy`,
2
//! kept up to date after every oxy command, so Git tools read an Oxygen
3
//! checkout; oxy never takes `.git` as content.
4
5
use std::path::Path;
6
use std::process::Command;
7
8
fn oxy(dir: &Path, home: &Path, args: &[&str]) -> (bool, String) {
9
    let out = Command::new(env!("CARGO_BIN_EXE_oxy"))
10
        .arg("--plain")
11
        .args(args)
12
        .current_dir(dir)
13
        .env("OXY_HOME", home)
14
        .env("NO_COLOR", "1")
15
        .output()
16
        .unwrap();
17
    (
18
        out.status.success(),
19
        format!(
20
            "{}{}",
21
            String::from_utf8_lossy(&out.stdout),
22
            String::from_utf8_lossy(&out.stderr)
23
        ),
24
    )
25
}
26
27
fn git(dir: &Path, args: &[&str]) -> String {
28
    let out = Command::new("git")
29
        .args(args)
30
        .current_dir(dir)
31
        .env("GIT_CONFIG_NOSYSTEM", "1")
32
        .env("HOME", dir)
33
        .output()
34
        .unwrap();
35
    assert!(
36
        out.status.success(),
37
        "git {args:?}: {}",
38
        String::from_utf8_lossy(&out.stderr)
39
    );
40
    String::from_utf8_lossy(&out.stdout).trim().to_string()
41
}
42
43
#[test]
44
fn a_colocated_git_follows_the_bookmark() {
45
    if Command::new("git").arg("--version").output().is_err() {
46
        eprintln!("git not installed; skipping");
47
        return;
48
    }
49
    let tmp = tempfile::tempdir().unwrap();
50
    let home = tmp.path().join("home");
51
    std::fs::create_dir_all(&home).unwrap();
52
    let r = tmp.path().join("r");
53
    assert!(oxy(tmp.path(), &home, &["init", r.to_str().unwrap()]).0);
54
    assert!(
55
        oxy(
56
            &r,
57
            &home,
58
            &[
59
                "identity",
60
                "create",
61
                "--name",
62
                "Ada",
63
                "--email",
64
                "[email protected]"
65
            ]
66
        )
67
        .0
68
    );
69
    std::fs::write(r.join("a.txt"), "one\n").unwrap();
70
    assert!(oxy(&r, &home, &["commit", "-m", "first"]).0);
71
72
    let (ok, out) = oxy(&r, &home, &["git", "colocate"]);
73
    assert!(ok, "{out}");
74
    assert!(r.join(".git/HEAD").exists());
75
    assert_eq!(git(&r, &["log", "--format=%s"]), "first");
76
    assert_eq!(git(&r, &["symbolic-ref", "HEAD"]), "refs/heads/main");
77
    assert_eq!(
78
        git(&r, &["status", "--porcelain"]),
79
        "",
80
        "Git sees no difference, and not .oxy either"
81
    );
82
    let (_, status) = oxy(&r, &home, &["status"]);
83
    assert!(
84
        !status.contains(".git"),
85
        "oxy never takes .git as content: {status}"
86
    );
87
88
    // An oxy commit shows in Git without asking.
89
    std::fs::write(r.join("a.txt"), "one\ntwo\n").unwrap();
90
    assert_eq!(
91
        git(&r, &["status", "--porcelain"]),
92
        "M a.txt",
93
        "uncommitted work shows as modified"
94
    );
95
    assert!(oxy(&r, &home, &["commit", "-m", "second"]).0);
96
    assert_eq!(git(&r, &["log", "--format=%s"]), "second\nfirst");
97
    assert_eq!(git(&r, &["status", "--porcelain"]), "");
98
    assert_eq!(git(&r, &["show", "HEAD:a.txt"]), "one\ntwo");
99
100
    // Off: no more updates, the .git stays.
101
    assert!(oxy(&r, &home, &["git", "colocate", "--off"]).0);
102
    std::fs::write(r.join("b.txt"), "b\n").unwrap();
103
    assert!(oxy(&r, &home, &["commit", "-m", "third"]).0);
104
    assert_eq!(
105
        git(&r, &["log", "--format=%s"]),
106
        "second\nfirst",
107
        "no longer followed"
108
    );
109
    assert!(r.join(".git/HEAD").exists());
110
}