111 lines
3.4 KiB
Rust
111 lines
3.4 KiB
Rust
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
|
|
pub struct Git;
|
|
|
|
impl Git {
|
|
pub fn clone(url: &str, dest: &Path, dir: &str) {
|
|
let dest = dest.canonicalize().unwrap();
|
|
let mut child = Command::new("git")
|
|
.args(["clone", url, dir])
|
|
.current_dir(dest)
|
|
.spawn()
|
|
.expect("unable to obtain Docker version");
|
|
child.wait().unwrap();
|
|
}
|
|
|
|
pub fn pull(repo: &Path, branch: &str) {
|
|
let repo = repo.canonicalize().unwrap();
|
|
let mut c = Command::new("git")
|
|
.current_dir(repo)
|
|
.args(["pull", "origin", branch])
|
|
.spawn()
|
|
.expect("unable to obtain Docker version");
|
|
c.wait().unwrap();
|
|
}
|
|
|
|
pub fn push(branch: &str, repo: &Path) {
|
|
let repo = repo.canonicalize().unwrap();
|
|
let mut child = Command::new("git")
|
|
.current_dir(repo)
|
|
.args(["push", "origin", branch])
|
|
.spawn()
|
|
.expect("unable to get logs");
|
|
child.wait().unwrap();
|
|
}
|
|
|
|
pub fn checkout_commit(commit: &str, repo: &Path) {
|
|
let repo = repo.canonicalize().unwrap();
|
|
let mut child = Command::new("git")
|
|
.current_dir(repo)
|
|
.args(["checkout", commit])
|
|
.spawn()
|
|
.expect("unable to get logs");
|
|
child.wait().unwrap();
|
|
}
|
|
|
|
pub fn files_changed_from_previous_commit(repo: &Path) -> Vec<String> {
|
|
let repo = repo.canonicalize().unwrap();
|
|
let out = Command::new("git")
|
|
.current_dir(repo)
|
|
.args(["--no-pager", "diff", "--name-only", "HEAD^"])
|
|
.output()
|
|
.expect("unable to get logs");
|
|
let out = String::from_utf8(out.stdout).unwrap();
|
|
let mut s = Vec::default();
|
|
for f in out.lines() {
|
|
s.push(f.trim().to_owned())
|
|
}
|
|
s
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use std::fs;
|
|
|
|
use super::*;
|
|
use mktemp::Temp;
|
|
|
|
#[test]
|
|
fn git_works() {
|
|
let tmp = Temp::new_dir().unwrap();
|
|
let tmp = tmp.as_path();
|
|
let upstream = "/tmp/git_cmd_init_tmp/repo";
|
|
let commits_file = "/tmp/git_cmd_init_tmp/commits";
|
|
let script = "./tests/git_cmd_init.sh";
|
|
|
|
Command::new(script).args(["init"]).output().unwrap();
|
|
|
|
Git::clone(upstream, tmp, "git_works");
|
|
let repo = tmp.join("git_works");
|
|
let contents = fs::read_to_string(repo.join("2_commit.txt")).unwrap();
|
|
let commits = fs::read_to_string(commits_file).unwrap();
|
|
assert_eq!(commits.lines().into_iter().count(), 2);
|
|
assert!(contents.contains("bar"));
|
|
assert!(!contents.contains("new commit"));
|
|
|
|
let first_commit = commits.lines().last().unwrap();
|
|
|
|
Git::checkout_commit(first_commit, repo.as_path());
|
|
assert!(!repo.join("2_commit.txt").exists());
|
|
|
|
Git::checkout_commit("master", repo.as_path());
|
|
assert!(repo.join("2_commit.txt").exists());
|
|
|
|
Command::new(script).args(["update"]).output().unwrap();
|
|
Git::pull(&repo, "master");
|
|
|
|
let new_commits = fs::read_to_string(commits_file).unwrap();
|
|
assert_eq!(new_commits.lines().into_iter().count(), 3);
|
|
|
|
let changes = Git::files_changed_from_previous_commit(&repo);
|
|
assert_eq!(changes.len(), 1);
|
|
assert_eq!(changes.get(0).unwrap(), "3_commit.txt");
|
|
}
|
|
}
|