use crate::{core_config::XCoreConfig, git::GitCli};
use camino::{Utf8Path, Utf8PathBuf};
use debug_ignore::DebugIgnore;
use graph::PackageGraphPlus;
use guppy::graph::PackageGraph;
use once_cell::sync::OnceCell;
pub mod core_config;
mod errors;
pub mod git;
mod graph;
mod workspace_subset;
pub use errors::*;
pub use workspace_subset::*;
#[derive(Debug)]
pub struct XCoreContext {
project_root: &'static Utf8Path,
config: XCoreConfig,
current_dir: Utf8PathBuf,
current_rel_dir: Utf8PathBuf,
git_cli: OnceCell<GitCli>,
package_graph_plus: DebugIgnore<OnceCell<PackageGraphPlus>>,
}
impl XCoreContext {
pub fn new(
project_root: &'static Utf8Path,
current_dir: Utf8PathBuf,
config: XCoreConfig,
) -> Result<Self> {
let current_rel_dir = match current_dir.strip_prefix(project_root) {
Ok(rel_dir) => rel_dir.to_path_buf(),
Err(_) => {
return Err(SystemError::CwdNotInProjectRoot {
current_dir,
project_root,
})
}
};
Ok(Self {
project_root,
config,
current_dir,
current_rel_dir,
git_cli: OnceCell::new(),
package_graph_plus: DebugIgnore(OnceCell::new()),
})
}
pub fn project_root(&self) -> &'static Utf8Path {
self.project_root
}
pub fn config(&self) -> &XCoreConfig {
&self.config
}
pub fn current_dir(&self) -> &Utf8Path {
&self.current_dir
}
pub fn current_rel_dir(&self) -> &Utf8Path {
&self.current_rel_dir
}
pub fn current_dir_is_root(&self) -> bool {
self.current_rel_dir == ""
}
pub fn git_cli(&self) -> Result<&GitCli> {
let root = self.project_root;
self.git_cli.get_or_try_init(|| GitCli::new(root))
}
pub fn package_graph(&self) -> Result<&PackageGraph> {
Ok(self.package_graph_plus()?.package_graph())
}
pub fn partition_workspace_names<'a, B>(
&self,
names: impl IntoIterator<Item = &'a str>,
) -> Result<(B, B)>
where
B: Default + Extend<&'a str>,
{
let workspace = self.package_graph()?.workspace();
let (known, unknown) = names
.into_iter()
.partition(|name| workspace.contains_name(name));
Ok((known, unknown))
}
pub fn subsets(&self) -> Result<&WorkspaceSubsets> {
Ok(self.package_graph_plus()?.subsets())
}
fn package_graph_plus(&self) -> Result<&PackageGraphPlus> {
self.package_graph_plus
.get_or_try_init(|| PackageGraphPlus::create(self))
}
}