feat: proof of concept implementation

This commit is contained in:
əlemi 2024-02-13 16:58:04 +01:00
parent 7e3386242e
commit 3f95b8b733
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 61 additions and 5 deletions

View file

@ -1,16 +1,18 @@
[package]
name = "{{project-name}}"
name = "tci"
version = "0.1.0"
edition = "2021"
authors = [ "alemi <me@alemi.dev>" ]
readme = "README.md"
#description = ""
#keywords = []
description = "tiny custom CI runner for your selfhosted just-git repositories"
keywords = ["git", "ci", "workflows", "minimal", "selfhosted"]
repository = "https://git.alemi.dev/tci.git"
#documentation = ""
#repository = "https://git.alemi.dev/{{project-name}}"
#license = "LICENSE"
[dependencies]
git2 = "0.18.2"
tempdir = "0.3.7"
[dev-dependencies]

View file

@ -1,4 +1,58 @@
use git2::{Config, Repository};
fn main() {
println!("Hello, world!");
// println!("{:?}", std::env::args());
// println!("{}", std::env::current_dir().unwrap().display());
// for (key, value) in std::env::vars() {
// println!("{key}: \t{value}");
// }
let callback = std::path::Path::new(&std::env::args().next().expect("no argv0??"))
.file_name()
.expect("path terminates with '...'")
.to_str()
.expect("could not represent OsStr")
.to_string();
let repo_path = std::env::current_dir()
.expect("not in a directory???");
let repo_name = repo_path
.parent()
.expect("in root???")
.file_name()
.expect("path terminates with '...'")
.to_str()
.expect("could not represent OsStr")
.to_string();
// check config before even creating temp dir and cloning repo
let cfg = Config::open(&repo_path.join("config")).expect("could not read git config");
let Ok(true) = cfg.get_bool("tci.allow") else {
std::process::exit(0);
};
let tmp = tempdir::TempDir::new(&format!("tci-{repo_name}")).expect("could not create tempdir");
let repo = Repository::clone(repo_path.to_str().unwrap(), tmp.path()).expect("could not clone repository");
std::env::set_current_dir(tmp.path()).expect("could not change directory");
println!("[+] running tci hook [{callback}] for repo '{repo_name}'");
let tci_script = cfg.get_str("tci.script").unwrap_or(".tci").to_string();
if !tmp.path().join(&tci_script).is_file() {
println!("[?] tci enabled for repo, but no .tci script found");
std::process::exit(1);
}
let output = std::process::Command::new(tmp.path().join(&tci_script)).output().expect("could not run tci script");
match std::str::from_utf8(&output.stdout) {
Ok(s) => println!("{s}"),
Err(e) => {
println!("[?] script produced non-utf8 output ({e}), showing as bytes");
println!("{:?}", output.stdout);
},
}
}