#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn resolve_repository(
path: Option<PathBuf>,
url: Option<String>,
repo: Option<String>,
) -> Result<PathBuf> {
if let Some(repo_spec) = repo {
resolve_repo_spec(&repo_spec)
} else if let Some(url) = url {
Ok(PathBuf::from(url))
} else {
detect_repository(path)
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub async fn resolve_repository_async(
path: Option<PathBuf>,
url: Option<String>,
repo: Option<String>,
) -> Result<PathBuf> {
let resolved_path = resolve_repository(path, url, repo)?;
let path_str = resolved_path.to_string_lossy();
if path_str.starts_with("https://") || path_str.starts_with("git@") {
let _temp_dir = std::env::temp_dir()
.join("pmat-demo-repos")
.join(format!("repo-{}", uuid::Uuid::new_v4()));
let server = crate::stateless_server::StatelessTemplateServer::new()?;
let runner = DemoRunner::new(Arc::new(server));
runner.clone_and_prepare(&path_str).await
} else {
Ok(resolved_path)
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn resolve_repo_spec(repo_spec: &str) -> Result<PathBuf> {
if let Some(result) = try_local_path(repo_spec) {
return result;
}
if let Some(result) = try_github_shorthand(repo_spec) {
return result;
}
if let Some(result) = try_github_url(repo_spec) {
return result;
}
if let Some(result) = try_owner_repo_format(repo_spec) {
return result;
}
Err(anyhow!("Repository not found: {repo_spec}"))
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn try_local_path(repo_spec: &str) -> Option<Result<PathBuf>> {
let path = PathBuf::from(repo_spec);
if path.exists() {
Some(detect_repository(Some(path)))
} else {
None
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn try_github_shorthand(repo_spec: &str) -> Option<Result<PathBuf>> {
if repo_spec.starts_with("gh:") {
let repo_name = repo_spec
.strip_prefix("gh:")
.expect("Writing to String buffer cannot fail");
let github_url = format!("https://github.com/{repo_name}");
Some(Ok(PathBuf::from(github_url)))
} else {
None
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn try_github_url(repo_spec: &str) -> Option<Result<PathBuf>> {
if repo_spec.starts_with("https://github.com/") || repo_spec.starts_with("git@github.com:") {
Some(Ok(PathBuf::from(repo_spec)))
} else {
None
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn try_owner_repo_format(repo_spec: &str) -> Option<Result<PathBuf>> {
if repo_spec.contains('/') && !repo_spec.contains('.') {
let github_url = format!("https://github.com/{repo_spec}");
Some(Ok(PathBuf::from(github_url)))
} else {
None
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn get_canonical_path(hint: Option<PathBuf>) -> Result<PathBuf> {
match hint {
Some(p) => {
if !p.exists() {
return Err(anyhow!("Path does not exist: {p:?}"));
}
p.canonicalize()
.map_err(|e| anyhow!("Failed to canonicalize path {p:?}: {e}"))
}
None => env::current_dir()
.and_then(|p| p.canonicalize())
.map_err(|e| anyhow!("Failed to get current directory: {e}")),
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn find_git_root(start_path: &Path) -> Option<PathBuf> {
if start_path.join(".git").is_dir() {
return Some(start_path.to_path_buf());
}
let mut current = start_path;
let mut iterations = 0;
const MAX_ITERATIONS: usize = 100;
while let Some(parent) = current.parent() {
if parent == current || parent.as_os_str().is_empty() {
break; }
if parent.join(".git").is_dir() {
return Some(parent.to_path_buf());
}
current = parent;
iterations += 1;
if iterations >= MAX_ITERATIONS {
break;
}
}
None
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn is_interactive_environment() -> bool {
use std::io::IsTerminal;
std::io::stdout().is_terminal() && env::var("CI").is_err()
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn read_repository_path_from_user() -> Result<PathBuf> {
eprintln!("No git repository found in current directory");
eprint!("Enter path to a git repository (or press Enter to cancel): ");
io::stdout().flush()?;
let mut input = String::with_capacity(1024);
io::stdin()
.read_line(&mut input)
.map_err(|e| anyhow!("Failed to read user input: {e}"))?;
let trimmed = input.trim();
if trimmed.is_empty() {
return Err(anyhow!("Repository detection cancelled by user"));
}
let path = PathBuf::from(trimmed);
if !path.exists() {
return Err(anyhow!("Specified path does not exist: {path:?}"));
}
let canonical = path
.canonicalize()
.map_err(|e| anyhow!("Failed to canonicalize user path: {e}"))?;
if canonical.join(".git").is_dir() {
Ok(canonical)
} else {
Err(anyhow!("No .git directory found at: {canonical:?}"))
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn detect_repository(hint: Option<PathBuf>) -> Result<PathBuf> {
let candidate = get_canonical_path(hint)?;
if let Some(git_root) = find_git_root(&candidate) {
return Ok(git_root);
}
if !is_interactive_environment() {
return Err(anyhow!(
"No git repository found in {candidate:?} or its parent directories"
));
}
read_repository_path_from_user()
}