cmake_parser/doc/command/scripting/
find_package.rs

1use cmake_parser_derive::CMake;
2
3use crate::{
4    command::common::{FindRoot, WindowsRegistryView},
5    doc::command_scope::{CommandScope, ToCommandScope},
6    Token,
7};
8
9/// Find a package
10///
11/// Reference: <https://cmake.org/cmake/help/v3.26/command/find_package.html>
12#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[cmake(pkg = "crate", untagged)]
14pub enum FindPackage<'t> {
15    Full(FindPackageFull<'t>),
16    Basic(FindPackageBasic<'t>),
17}
18
19impl<'t> ToCommandScope for FindPackage<'t> {
20    fn to_command_scope(&self) -> CommandScope {
21        CommandScope::Scripting
22    }
23}
24
25#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
26#[cmake(pkg = "crate", complete, default = "version")]
27pub struct FindPackageBasic<'t> {
28    #[cmake(positional)]
29    pub package_name: Token<'t>,
30    #[cmake(rename = "")]
31    pub version: Option<Token<'t>>,
32    pub exact: bool,
33    pub quiet: bool,
34    pub module: bool,
35    pub components: Option<PackageComponents<'t>>,
36    pub optional_components: Option<Vec<Token<'t>>>,
37    pub registry_view: Option<WindowsRegistryView>,
38    pub global: bool,
39    pub no_policy_scope: bool,
40    pub bypass_provider: bool,
41}
42
43#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
44#[cmake(pkg = "crate", complete, default = "version", except = ["MODULE"])]
45pub struct FindPackageFull<'t> {
46    #[cmake(positional)]
47    pub package_name: Token<'t>,
48    #[cmake(rename = "")]
49    pub version: Option<Token<'t>>,
50    pub exact: bool,
51    pub quiet: bool,
52    pub components: Option<PackageComponents<'t>>,
53    pub optional_components: Option<Vec<Token<'t>>>,
54    pub config_mode: Option<ConfigMode>,
55    pub global: bool,
56    pub no_policy_scope: bool,
57    pub bypass_provider: bool,
58    pub names: Option<Vec<Token<'t>>>,
59    pub configs: Option<Vec<Token<'t>>>,
60    pub hints: Option<Vec<Token<'t>>>,
61    pub paths: Option<Vec<Token<'t>>>,
62    pub registry_view: Option<WindowsRegistryView>,
63    pub path_suffixes: Option<Vec<Token<'t>>>,
64    pub no_default_path: bool,
65    pub no_package_root_path: bool,
66    pub no_cmake_path: bool,
67    pub no_cmake_environment_path: bool,
68    pub no_system_environment_path: bool,
69    pub no_cmake_package_registry: bool,
70    pub no_cmake_builds_path: bool,
71    pub no_cmake_system_path: bool,
72    pub no_cmake_install_prefix: bool,
73    pub find_root: Option<FindRoot>,
74}
75
76#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
77#[cmake(pkg = "crate", positional, complete)]
78pub enum PackageComponents<'t> {
79    Components(Components<'t>),
80    #[cmake(transparent)]
81    Required(Option<Components<'t>>),
82}
83
84#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
85#[cmake(pkg = "crate", default = "components")]
86pub struct Components<'t> {
87    pub components: Vec<Token<'t>>,
88}
89
90#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
91#[cmake(pkg = "crate")]
92pub enum ConfigMode {
93    Config,
94    NoModule,
95}
96#[cfg(test)]
97mod tests {
98    use super::*;
99    use crate::doc::cmake_parse::tests::{token, tokens_vec};
100    use crate::*;
101    use pretty_assertions::assert_eq;
102
103    #[test]
104    fn package_components() {
105        #[derive(CMake, Debug, PartialEq, Eq)]
106        #[cmake(pkg = "crate", allow_empty)]
107        struct Test<'t> {
108            components: Option<PackageComponents<'t>>,
109        }
110        assert_eq!(
111            CMakeParse::complete(&tokens_vec([])),
112            Ok(Test { components: None })
113        );
114        assert_eq!(
115            CMakeParse::complete(&tokens_vec([b"COMPONENTS", b"component1"])),
116            Ok(Test {
117                components: Some(PackageComponents::Components(Components {
118                    components: tokens_vec([b"component1"]),
119                })),
120            })
121        );
122        assert_eq!(
123            CMakeParse::complete(&tokens_vec([b"REQUIRED"])),
124            Ok(Test {
125                components: Some(PackageComponents::Required(None)),
126            })
127        );
128        assert_eq!(
129            CMakeParse::complete(&tokens_vec([b"REQUIRED", b"COMPONENTS", b"component1"])),
130            Ok(Test {
131                components: Some(PackageComponents::Required(Some(Components {
132                    components: tokens_vec([b"component1"]),
133                }))),
134            })
135        );
136        assert_eq!(
137            CMakeParse::complete(&tokens_vec([b"REQUIRED", b"component1", b"component2"])),
138            Ok(Test {
139                components: Some(PackageComponents::Required(Some(Components {
140                    components: tokens_vec([b"component1", b"component2"]),
141                }))),
142            })
143        );
144    }
145
146    #[test]
147    fn find_package() {
148        let src = include_bytes!("../../../../../fixture/commands/scripting/find_package");
149        let cmakelists = parse_cmakelists(src).unwrap();
150        let doc = Doc::from(cmakelists);
151        assert_eq!(
152            doc.commands(),
153            Ok(vec![
154                Command::FindPackage(Box::new(FindPackage::Full(FindPackageFull {
155                    package_name: token(b"package_name1"),
156                    version: None,
157                    exact: false,
158                    quiet: false,
159                    components: None,
160                    optional_components: None,
161                    config_mode: None,
162                    global: false,
163                    no_policy_scope: false,
164                    bypass_provider: false,
165                    names: None,
166                    configs: None,
167                    hints: None,
168                    paths: None,
169                    registry_view: None,
170                    path_suffixes: None,
171                    no_default_path: false,
172                    no_package_root_path: false,
173                    no_cmake_path: false,
174                    no_cmake_environment_path: false,
175                    no_system_environment_path: false,
176                    no_cmake_package_registry: false,
177                    no_cmake_builds_path: false,
178                    no_cmake_system_path: false,
179                    no_cmake_install_prefix: false,
180                    find_root: None,
181                }))),
182                Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
183                    package_name: token(b"package_name1"),
184                    version: None,
185                    exact: false,
186                    quiet: false,
187                    module: true,
188                    components: None,
189                    optional_components: None,
190                    global: false,
191                    no_policy_scope: false,
192                    bypass_provider: false,
193                    registry_view: None,
194                }))),
195                Command::FindPackage(Box::new(FindPackage::Full(FindPackageFull {
196                    package_name: token(b"package_name1"),
197                    version: None,
198                    exact: false,
199                    quiet: false,
200                    components: Some(PackageComponents::Required(Some(Components {
201                        components: tokens_vec([b"component1", b"component2"]),
202                    }))),
203                    optional_components: None,
204                    config_mode: None,
205                    global: false,
206                    no_policy_scope: false,
207                    bypass_provider: false,
208                    names: None,
209                    configs: None,
210                    hints: None,
211                    paths: None,
212                    registry_view: None,
213                    path_suffixes: None,
214                    no_default_path: false,
215                    no_package_root_path: false,
216                    no_cmake_path: false,
217                    no_cmake_environment_path: false,
218                    no_system_environment_path: false,
219                    no_cmake_package_registry: false,
220                    no_cmake_builds_path: false,
221                    no_cmake_system_path: false,
222                    no_cmake_install_prefix: false,
223                    find_root: None,
224                }))),
225                Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
226                    package_name: token(b"package_name1"),
227                    version: None,
228                    exact: false,
229                    quiet: false,
230                    module: true,
231                    components: Some(PackageComponents::Required(Some(Components {
232                        components: tokens_vec([b"component1", b"component2"]),
233                    }))),
234                    optional_components: None,
235                    global: false,
236                    no_policy_scope: false,
237                    bypass_provider: false,
238                    registry_view: None,
239                }))),
240                Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
241                    package_name: token(b"package_name1"),
242                    version: None,
243                    exact: false,
244                    quiet: false,
245                    module: true,
246                    components: Some(PackageComponents::Components(Components {
247                        components: tokens_vec([b"component1", b"component2"]),
248                    })),
249                    optional_components: None,
250                    global: false,
251                    no_policy_scope: false,
252                    bypass_provider: false,
253                    registry_view: None,
254                }))),
255                Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
256                    package_name: token(b"package_name1"),
257                    version: None,
258                    exact: false,
259                    quiet: false,
260                    module: true,
261                    components: Some(PackageComponents::Required(None)),
262                    optional_components: None,
263                    global: false,
264                    no_policy_scope: false,
265                    bypass_provider: false,
266                    registry_view: None,
267                }))),
268                Command::FindPackage(Box::new(FindPackage::Full(FindPackageFull {
269                    package_name: token(b"package_name1"),
270                    version: Some(token(b"version1")),
271                    exact: true,
272                    quiet: true,
273                    components: Some(PackageComponents::Required(Some(Components {
274                        components: tokens_vec([b"component1", b"component2"]),
275                    }))),
276                    optional_components: Some(tokens_vec([b"component1", b"component2"])),
277                    config_mode: Some(ConfigMode::NoModule),
278                    global: true,
279                    no_policy_scope: true,
280                    bypass_provider: true,
281                    names: Some(tokens_vec([b"name1", b"name2"])),
282                    configs: Some(tokens_vec([b"config1", b"config2"])),
283                    hints: Some(tokens_vec([b"hint1", b"hint2"])),
284                    paths: Some(tokens_vec([b"path1", b"path2"])),
285                    registry_view: Some(WindowsRegistryView::Bits64Fallback32),
286                    path_suffixes: Some(tokens_vec([b"suffix1", b"suffix2"])),
287                    no_default_path: true,
288                    no_package_root_path: true,
289                    no_cmake_path: true,
290                    no_cmake_environment_path: true,
291                    no_system_environment_path: true,
292                    no_cmake_package_registry: true,
293                    no_cmake_builds_path: true,
294                    no_cmake_system_path: true,
295                    no_cmake_install_prefix: true,
296                    find_root: Some(FindRoot::OnlyCMakeFindRootPath),
297                }))),
298                Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
299                    package_name: token(b"package_name1"),
300                    version: Some(token(b"version1")),
301                    exact: true,
302                    quiet: true,
303                    module: true,
304                    components: Some(PackageComponents::Components(Components {
305                        components: tokens_vec([b"component1", b"component2"]),
306                    })),
307                    optional_components: Some(tokens_vec([b"component1", b"component2"])),
308                    registry_view: Some(WindowsRegistryView::Host),
309                    global: true,
310                    no_policy_scope: true,
311                    bypass_provider: true,
312                }))),
313            ])
314        )
315    }
316}