1#[macro_use]
5extern crate rental;
6
7use guppy::graph::PackageGraph;
8use once_cell::sync::OnceCell;
9use std::path::{Path, PathBuf};
10
11pub mod core_config;
12mod debug_ignore;
13mod errors;
14mod git;
15mod graph;
16mod workspace_subset;
17
18use crate::{core_config::XCoreConfig, git::GitCli};
19pub use debug_ignore::*;
20pub use errors::*;
21use graph::PackageGraphPlus;
22use hakari::{HakariBuilder, TomlOptions};
23pub use workspace_subset::*;
24
25#[derive(Debug)]
27pub struct XCoreContext {
28 project_root: &'static Path,
29 config: XCoreConfig,
30 current_dir: PathBuf,
31 current_rel_dir: PathBuf,
32 git_cli: GitCli,
33 package_graph_plus: DebugIgnore<OnceCell<PackageGraphPlus>>,
34}
35
36impl XCoreContext {
37 pub fn new(
39 project_root: &'static Path,
40 current_dir: PathBuf,
41 config: XCoreConfig,
42 ) -> Result<Self> {
43 let current_rel_dir = match current_dir.strip_prefix(project_root) {
44 Ok(rel_dir) => rel_dir.to_path_buf(),
45 Err(_) => {
46 return Err(SystemError::CwdNotInProjectRoot {
47 current_dir,
48 project_root,
49 })
50 }
51 };
52 Ok(Self {
55 project_root,
56 config,
57 current_dir,
58 current_rel_dir,
59 git_cli: GitCli::new(project_root)?,
60 package_graph_plus: DebugIgnore(OnceCell::new()),
61 })
62 }
63
64 pub fn project_root(&self) -> &'static Path {
66 self.project_root
67 }
68
69 pub fn config(&self) -> &XCoreConfig {
71 &self.config
72 }
73
74 pub fn current_dir(&self) -> &Path {
76 &self.current_dir
77 }
78
79 pub fn current_rel_dir(&self) -> &Path {
81 &self.current_rel_dir
82 }
83
84 pub fn current_dir_is_root(&self) -> bool {
86 self.current_rel_dir == Path::new("")
87 }
88
89 pub fn git_cli(&self) -> &GitCli {
91 &self.git_cli
92 }
93
94 pub fn package_graph(&self) -> Result<&PackageGraph> {
96 Ok(self.package_graph_plus()?.head())
97 }
98
99 pub fn subsets(&self) -> Result<&WorkspaceSubsets> {
101 Ok(self.package_graph_plus()?.suffix())
102 }
103
104 pub fn hakari_builder<'a>(&'a self) -> Result<HakariBuilder<'a, 'static>> {
106 let graph = self.package_graph()?;
107 self.config
108 .hakari
109 .to_hakari_builder(graph)
110 .map_err(|err| SystemError::guppy("while resolving Hakari config", err))
111 }
112
113 pub fn hakari_toml_options(&self) -> TomlOptions {
115 let mut options = TomlOptions::new();
116 options.set_exact_versions(true);
117 options
118 }
119
120 fn package_graph_plus(&self) -> Result<&PackageGraphPlus> {
125 self.package_graph_plus
126 .get_or_try_init(|| PackageGraphPlus::create(self))
127 }
128}