use std::path::{Path, PathBuf};
pub fn is_package(path: &Path, namespace_packages: &[PathBuf]) -> bool {
namespace_packages
.iter()
.any(|namespace_package| path.starts_with(namespace_package))
|| path.join("__init__.py").is_file()
}
pub fn detect_package_root<'a>(path: &'a Path, namespace_packages: &[PathBuf]) -> Option<&'a Path> {
let mut current = None;
for parent in path.ancestors() {
if !is_package(parent, namespace_packages) {
return current;
}
current = Some(parent);
}
current
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use crate::packaging::detect_package_root;
use crate::test::test_resource_path;
#[test]
fn package_detection() {
assert_eq!(
detect_package_root(&test_resource_path("package/src/package"), &[],),
Some(test_resource_path("package/src/package").as_path())
);
assert_eq!(
detect_package_root(&test_resource_path("project/python_modules/core/core"), &[],),
Some(test_resource_path("project/python_modules/core/core").as_path())
);
assert_eq!(
detect_package_root(
&test_resource_path("project/examples/docs/docs/concepts"),
&[],
),
Some(test_resource_path("project/examples/docs/docs").as_path())
);
assert_eq!(
detect_package_root(
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("setup.py")
.as_path(),
&[],
),
None,
);
}
#[test]
fn package_detection_with_namespace_packages() {
assert_eq!(
detect_package_root(&test_resource_path("project/python_modules/core/core"), &[],),
Some(test_resource_path("project/python_modules/core/core").as_path())
);
assert_eq!(
detect_package_root(
&test_resource_path("project/python_modules/core/core"),
&[test_resource_path("project/python_modules/core"),],
),
Some(test_resource_path("project/python_modules/core").as_path())
);
assert_eq!(
detect_package_root(
&test_resource_path("project/python_modules/core/core"),
&[
test_resource_path("project/python_modules/core"),
test_resource_path("project/python_modules"),
],
),
Some(test_resource_path("project/python_modules").as_path())
);
assert_eq!(
detect_package_root(
&test_resource_path("project/python_modules/core/core"),
&[test_resource_path("project/python_modules"),],
),
Some(test_resource_path("project/python_modules").as_path())
);
}
}