use crate::core::refs::with_ref_manager;
use crate::error::OxenError;
use crate::model::{LocalRepository, ParsedResource};
use crate::repositories;
use crate::util;
use std::path::{Path, PathBuf};
pub fn parse_resource_from_path(
repo: &LocalRepository,
path: &Path,
) -> Result<Option<ParsedResource>, OxenError> {
let mut components = path.components().collect::<Vec<_>>();
if let Some(first_component) = components.first() {
let base_path: &Path = first_component.as_ref();
let first_str = base_path.to_str().unwrap();
if let Some(commit) = repositories::commits::get_by_id(repo, first_str)? {
let mut file_path = PathBuf::new();
for (i, component) in components.iter().enumerate() {
if i != 0 {
let component_path: &Path = component.as_ref();
file_path = file_path.join(component_path);
}
}
log::debug!(
"parse_resource_from_path got commit.id [{}] and filepath [{:?}]",
commit.id,
file_path
);
return Ok(Some(ParsedResource {
commit: Some(commit.clone()),
branch: None,
workspace: None,
path: file_path,
version: PathBuf::from(commit.id.to_string()),
resource: path.to_owned(),
}));
}
match repositories::workspaces::get(repo, first_str) {
Ok(Some(workspace)) => {
let mut file_path = PathBuf::new();
for (i, component) in components.iter().enumerate() {
if i != 0 {
let component_path: &Path = component.as_ref();
file_path = file_path.join(component_path);
}
}
log::debug!(
"parse_resource_from_path got workspace.id [{}] and filepath [{:?}]",
workspace.id,
file_path
);
return Ok(Some(ParsedResource {
commit: None,
branch: None,
workspace: Some(workspace.clone()),
path: file_path,
version: PathBuf::from(workspace.id),
resource: path.to_owned(),
}));
}
Ok(None) => {
log::debug!("Workspace not found: {first_str}");
}
Err(e) => {
log::debug!("Workspace lookup failed for '{first_str}' with error: {e:?}");
}
}
}
let mut file_path = PathBuf::new();
while let Some(component) = components.pop() {
let component_path: &Path = component.as_ref();
if file_path == PathBuf::new() {
file_path = component_path.to_path_buf();
} else {
file_path = component_path.join(file_path);
}
if components.is_empty() {
let branch_name = util::fs::linux_path_str(file_path.to_str().unwrap());
let maybe_branch =
with_ref_manager(repo, |manager| manager.get_branch_by_name(&branch_name))?;
if let Some(branch) = maybe_branch {
log::debug!(
"parse_resource_from_path got branch [{branch_name}] with no file path"
);
let commit = repositories::commits::get_by_id(repo, &branch.commit_id)?;
file_path = PathBuf::from("");
return Ok(Some(ParsedResource {
commit,
branch: Some(branch.clone()),
workspace: None,
path: file_path,
version: PathBuf::from(branch.name),
resource: path.to_owned(),
}));
} else {
return Ok(None);
}
}
let mut branch_path = PathBuf::new();
for component in components.iter() {
let component_path: &Path = component.as_ref();
branch_path = branch_path.join(component_path);
}
let branch_name = util::fs::linux_path_str(branch_path.to_str().unwrap());
let maybe_branch =
with_ref_manager(repo, |manager| manager.get_branch_by_name(&branch_name))?;
if let Some(branch) = maybe_branch {
log::debug!(
"parse_resource_from_path got branch [{branch_name}] and filepath [{file_path:?}]"
);
let commit = repositories::commits::get_by_id(repo, &branch.commit_id)?;
return Ok(Some(ParsedResource {
commit,
branch: Some(branch.clone()),
workspace: None,
path: file_path,
version: PathBuf::from(branch.name),
resource: path.to_owned(),
}));
}
}
Ok(None)
}