1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use crate::{core_config::XCoreConfig, git::GitCli};
use camino::{Utf8Path, Utf8PathBuf};
use graph::PackageGraphPlus;
use guppy::graph::PackageGraph;
use hakari::{HakariBuilder, TomlOptions};
use once_cell::sync::OnceCell;
pub mod core_config;
mod debug_ignore;
mod errors;
pub mod git;
mod graph;
mod workspace_subset;
pub use debug_ignore::*;
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())
}
pub fn hakari_builder(&self) -> Result<HakariBuilder<'_>> {
let graph = self.package_graph()?;
self.config
.hakari
.to_hakari_builder(graph)
.map_err(|err| SystemError::guppy("while resolving Hakari config", err))
}
pub fn hakari_toml_options(&self) -> TomlOptions {
let mut options = TomlOptions::new();
options.set_exact_versions(true);
options
}
fn package_graph_plus(&self) -> Result<&PackageGraphPlus> {
self.package_graph_plus
.get_or_try_init(|| PackageGraphPlus::create(self))
}
}