#![allow(dead_code)]
use std::path::{Path, PathBuf};
type CargoResult<T> = anyhow::Result<T>;
use anyhow::anyhow;
use crate::print_debug;
use crate::util::cargo::paths;
use super::paths::normalize_path;
use super::toml::InheritableFields;
#[derive(Debug, Clone)]
pub enum WorkspaceConfig {
Root(WorkspaceRootConfig),
Member { root: Option<String> },
}
impl WorkspaceConfig {
pub fn inheritable(&self) -> Option<&InheritableFields> {
match self {
WorkspaceConfig::Root(root) => Some(&root.inheritable_fields),
WorkspaceConfig::Member { .. } => None,
}
}
fn get_ws_root(&self, self_path: &Path, look_from: &Path) -> Option<PathBuf> {
match self {
WorkspaceConfig::Root(ances_root_config) => {
print_debug!("find_root - found a root checking exclusion");
if !ances_root_config.is_excluded(look_from) {
print_debug!("find_root - found!");
Some(self_path.to_owned())
} else {
None
}
}
WorkspaceConfig::Member {
root: Some(path_to_root),
} => {
print_debug!("find_root - found pointer");
Some(read_root_pointer(self_path, path_to_root))
}
WorkspaceConfig::Member { .. } => None,
}
}
}
fn read_root_pointer(member_manifest: &Path, root_link: &str) -> PathBuf {
let path = member_manifest
.parent()
.unwrap()
.join(root_link)
.join("Cargo.toml");
print_debug!("find_root - pointer {}", path.display());
paths::normalize_path(&path)
}
#[derive(Debug, Clone)]
pub struct WorkspaceRootConfig {
root_dir: PathBuf,
members: Option<Vec<String>>,
default_members: Option<Vec<String>>,
exclude: Vec<String>,
inheritable_fields: InheritableFields,
custom_metadata: Option<toml::Value>,
}
impl WorkspaceRootConfig {
pub fn new(
root_dir: &Path,
members: &Option<Vec<String>>,
default_members: &Option<Vec<String>>,
exclude: &Option<Vec<String>>,
inheritable: &Option<InheritableFields>,
custom_metadata: &Option<toml::Value>,
) -> WorkspaceRootConfig {
WorkspaceRootConfig {
root_dir: root_dir.to_path_buf(),
members: members.clone(),
default_members: default_members.clone(),
exclude: exclude.clone().unwrap_or_default(),
inheritable_fields: inheritable.clone().unwrap_or_default(),
custom_metadata: custom_metadata.clone(),
}
}
fn is_excluded(&self, manifest_path: &Path) -> bool {
let excluded = self
.exclude
.iter()
.any(|ex| manifest_path.starts_with(self.root_dir.join(ex)));
let explicit_member = match self.members {
Some(ref members) => members
.iter()
.any(|mem| manifest_path.starts_with(self.root_dir.join(mem))),
None => false,
};
!explicit_member && excluded
}
fn has_members_list(&self) -> bool {
self.members.is_some()
}
pub fn inheritable(&self) -> &InheritableFields {
&self.inheritable_fields
}
}
pub fn resolve_relative_path(
label: &str,
old_root: &Path,
new_root: &Path,
rel_path: &str,
) -> CargoResult<String> {
let joined_path = normalize_path(&old_root.join(rel_path));
match pathdiff::diff_paths(joined_path, new_root) {
None => Err(anyhow!(
"`{}` was defined in {} but could not be resolved with {}",
label,
old_root.display(),
new_root.display()
)),
Some(path) => Ok(path
.to_str()
.ok_or_else(|| {
anyhow!(
"`{}` resolved to non-UTF value (`{}`)",
label,
path.display()
)
})?
.to_owned()),
}
}