feat: git cmd and tests
This commit is contained in:
parent
17efcac145
commit
44a97e8928
2 changed files with 128 additions and 12 deletions
94
src/git.rs
94
src/git.rs
|
@ -1,36 +1,106 @@
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
pub struct Git;
|
pub struct Git;
|
||||||
|
|
||||||
impl Git {
|
impl Git {
|
||||||
pub fn clone(url: &Url, dest: &Path) {
|
pub fn clone(url: &str, dest: &Path, dir: &str) {
|
||||||
let dest = dest.canonicalize().unwrap();
|
let dest = dest.canonicalize().unwrap();
|
||||||
let mut child = Command::new("git")
|
let mut child = Command::new("git")
|
||||||
.args(["clone", url.as_str()])
|
.args(["clone", url, dir])
|
||||||
.current_dir(dest)
|
.current_dir(dest)
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("unable to obtain Docker version");
|
.expect("unable to obtain Docker version");
|
||||||
child.wait().unwrap();
|
child.wait().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pull(dest: &Path, branch: &str) {
|
pub fn pull(repo: &Path, branch: &str) {
|
||||||
let dest = dest.canonicalize().unwrap();
|
let repo = repo.canonicalize().unwrap();
|
||||||
Command::new("git")
|
let mut c = Command::new("git")
|
||||||
.current_dir(dest)
|
.current_dir(repo)
|
||||||
.args(["pull", "origin", branch])
|
.args(["pull", "origin", branch])
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("unable to obtain Docker version");
|
.expect("unable to obtain Docker version");
|
||||||
|
c.wait().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(branch: &str, dest: &Path) {
|
pub fn push(branch: &str, repo: &Path) {
|
||||||
let dest = dest.canonicalize().unwrap();
|
let repo = repo.canonicalize().unwrap();
|
||||||
let output = Command::new("git")
|
let mut child = Command::new("git")
|
||||||
.current_dir(dest)
|
.current_dir(repo)
|
||||||
.args(["push", "origin", branch])
|
.args(["push", "origin", branch])
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("unable to get logs");
|
.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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
tests/git_cmd_init.sh
Executable file
46
tests/git_cmd_init.sh
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
readonly DIR=/tmp/git_cmd_init_tmp
|
||||||
|
readonly REPO=$DIR/repo
|
||||||
|
|
||||||
|
commit() {
|
||||||
|
git add --all
|
||||||
|
git commit \
|
||||||
|
--author="ftest-test-util-script <ftest-test-util-script@example.org>" \
|
||||||
|
--message="$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_commits_to_file() {
|
||||||
|
pushd $REPO
|
||||||
|
popd
|
||||||
|
rm -rf $DIR/commits
|
||||||
|
git log --pretty=oneline | cut -d ' ' -f 1 > $DIR/commits
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
init() {
|
||||||
|
rm -rf $DIR || true
|
||||||
|
mkdir -p $REPO
|
||||||
|
cd $REPO
|
||||||
|
git init
|
||||||
|
echo "foo" > 1_commit.txt
|
||||||
|
commit "first commit"
|
||||||
|
echo "bar" > 2_commit.txt
|
||||||
|
commit "second commit"
|
||||||
|
write_commits_to_file
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
update() {
|
||||||
|
cd $REPO
|
||||||
|
echo "bar" >> 3_commit.txt
|
||||||
|
commit "new commit"
|
||||||
|
write_commits_to_file
|
||||||
|
}
|
||||||
|
|
||||||
|
$@
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in a new issue