93 lines
2.3 KiB
Rust
93 lines
2.3 KiB
Rust
use std::{path::PathBuf, str::FromStr};
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
pub enum GitService {
|
|
UploadPack,
|
|
ReceivePack,
|
|
UploadArchive,
|
|
}
|
|
|
|
impl FromStr for GitService {
|
|
type Err = ();
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
"upload-pack" => Ok(Self::UploadPack),
|
|
"receive-pack" => Ok(Self::ReceivePack),
|
|
"upload-archive" => Ok(Self::UploadArchive),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn parse_git_command(cmd: &str) -> Option<(GitService, &str)> {
|
|
let (svc, path) = match cmd.split_once(' ') {
|
|
Some(("git-receive-pack", path)) => (GitService::ReceivePack, path),
|
|
Some(("git-upload-pack", path)) => (GitService::UploadPack, path),
|
|
Some(("git-upload-archive", path)) => (GitService::UploadArchive, path),
|
|
_ => return None,
|
|
};
|
|
Some((svc, strip_apostrophes(path)))
|
|
}
|
|
|
|
pub fn parse_repo_path(path: &str) -> Option<(&str, &str)> {
|
|
let path = path.trim_matches('/');
|
|
let mut parts = path.splitn(2, '/');
|
|
match (parts.next(), parts.next()) {
|
|
(Some(owner), Some(repo)) if !owner.is_empty() && !repo.is_empty() => {
|
|
Some((owner, repo))
|
|
}
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn build_git_command(
|
|
service: GitService,
|
|
path: PathBuf,
|
|
) -> tokio::process::Command {
|
|
let mut cmd = tokio::process::Command::new("git");
|
|
|
|
let cwd = match path.canonicalize() {
|
|
Ok(p) => p,
|
|
Err(e) => {
|
|
tracing::debug!(error = %e, "path canonicalize failed, falling back to raw path");
|
|
path.clone()
|
|
}
|
|
};
|
|
cmd.current_dir(cwd);
|
|
|
|
match service {
|
|
GitService::UploadPack => {
|
|
cmd.arg("upload-pack");
|
|
}
|
|
GitService::ReceivePack => {
|
|
cmd.arg("receive-pack");
|
|
}
|
|
GitService::UploadArchive => {
|
|
cmd.arg("upload-archive");
|
|
}
|
|
}
|
|
|
|
cmd.arg(".")
|
|
.env("GIT_CONFIG_NOSYSTEM", "1")
|
|
.env("GIT_NO_REPLACE_OBJECTS", "1");
|
|
|
|
#[cfg(unix)]
|
|
{
|
|
cmd.env("GIT_CONFIG_GLOBAL", "/dev/null")
|
|
.env("GIT_CONFIG_SYSTEM", "/dev/null");
|
|
}
|
|
#[cfg(windows)]
|
|
{
|
|
let nul = "NUL";
|
|
cmd.env("GIT_CONFIG_GLOBAL", nul)
|
|
.env("GIT_CONFIG_SYSTEM", nul);
|
|
}
|
|
|
|
cmd
|
|
}
|
|
|
|
fn strip_apostrophes(s: &str) -> &str {
|
|
s.trim_matches('\'')
|
|
}
|