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::process::Command;
|
||||
|
||||
use url::Url;
|
||||
|
||||
pub struct 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 mut child = Command::new("git")
|
||||
.args(["clone", url.as_str()])
|
||||
.args(["clone", url, dir])
|
||||
.current_dir(dest)
|
||||
.spawn()
|
||||
.expect("unable to obtain Docker version");
|
||||
child.wait().unwrap();
|
||||
}
|
||||
|
||||
pub fn pull(dest: &Path, branch: &str) {
|
||||
let dest = dest.canonicalize().unwrap();
|
||||
Command::new("git")
|
||||
.current_dir(dest)
|
||||
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, dest: &Path) {
|
||||
let dest = dest.canonicalize().unwrap();
|
||||
let output = Command::new("git")
|
||||
.current_dir(dest)
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
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