1use crate::{prelude::*, LintContext};
5use guppy::graph::PackageGraph;
6use hakari::Hakari;
7use std::path::{Path, PathBuf};
8use x_core::{WorkspaceSubset, XCoreContext};
9
10pub trait ProjectLinter: Linter {
14 #[allow(clippy::trivially_copy_pass_by_ref)]
17 fn run<'l>(
19 &self,
20 ctx: &ProjectContext<'l>,
21 out: &mut LintFormatter<'l, '_>,
22 ) -> Result<RunStatus<'l>>;
23}
24
25#[derive(Debug)]
27pub struct ProjectContext<'l> {
28 core: &'l XCoreContext,
29}
30
31impl<'l> ProjectContext<'l> {
32 pub fn new(core: &'l XCoreContext) -> Self {
33 Self { core }
34 }
35
36 pub fn core(&self) -> &'l XCoreContext {
38 self.core
39 }
40
41 pub fn project_root(&self) -> &'l Path {
43 self.core.project_root()
44 }
45
46 pub fn package_graph(&self) -> Result<&'l PackageGraph> {
48 Ok(self.core.package_graph()?)
49 }
50
51 pub fn full_path(&self, path: impl AsRef<Path>) -> PathBuf {
53 self.core.project_root().join(path.as_ref())
54 }
55
56 pub fn default_members(&self) -> Result<&WorkspaceSubset> {
61 Ok(self.core.subsets()?.default_members())
62 }
63
64 pub fn hakari(&self) -> Result<Hakari<'l, 'static>> {
66 Ok(self.core.hakari_builder()?.compute())
67 }
68}
69
70impl<'l> LintContext<'l> for ProjectContext<'l> {
71 fn kind(&self) -> LintKind<'l> {
72 LintKind::Project
73 }
74}