flowey_lib_hvlite/
build_rustdoc.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Document crates in the hvlite repo using rustdoc (via `cargo doc`).
5
6use flowey::node::prelude::*;
7use flowey_lib_common::run_cargo_doc::DocPackage;
8use flowey_lib_common::run_cargo_doc::DocPackageKind;
9
10new_flow_node!(struct Node);
11
12flowey_request! {
13    pub struct Request {
14        pub target_triple: target_lexicon::Triple,
15        pub docs: WriteVar<RustdocOutput>,
16    }
17}
18
19#[derive(Serialize, Deserialize)]
20pub struct RustdocOutput {
21    pub docs: PathBuf,
22}
23
24impl Artifact for RustdocOutput {
25    // The rustdoc output has too many files for Azure DevOps to handle,
26    // so we need to archive it before uploading.
27    const TAR_GZ_NAME: Option<&'static str> = Some("rustdoc.tar.gz");
28}
29
30impl FlowNode for Node {
31    type Request = Request;
32
33    fn imports(ctx: &mut ImportCtx<'_>) {
34        ctx.import::<crate::git_checkout_openvmm_repo::Node>();
35        ctx.import::<crate::install_openvmm_rust_build_essential::Node>();
36        ctx.import::<flowey_lib_common::run_cargo_doc::Node>();
37    }
38
39    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
40        let mut doc_requests = Vec::new();
41
42        for Request {
43            target_triple,
44            docs,
45        } in requests
46        {
47            doc_requests.push((target_triple, docs));
48        }
49
50        let doc_requests = doc_requests;
51
52        // -- end of req processing -- //
53
54        if doc_requests.is_empty() {
55            return Ok(());
56        }
57
58        let side_effects = [ctx.reqv(crate::install_openvmm_rust_build_essential::Request)];
59
60        let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
61
62        let no_deps = true;
63        let document_private_items = false; // TODO: would be nice to turn this on
64
65        for (target_triple, output) in doc_requests {
66            let cargo_cmd = ctx.reqv(|v| {
67                flowey_lib_common::run_cargo_doc::Request {
68                    in_folder: openvmm_repo_path.clone(),
69                    packages: vec![
70                        DocPackage {
71                            kind: DocPackageKind::Workspace {
72                                // this is a bin crate with no interesting docs;
73                                // easier to just exclude it.
74                                exclude: vec!["vmfirmwareigvm_dll".into()],
75                            },
76                            no_deps,
77                            document_private_items,
78                        },
79                        DocPackage {
80                            kind: DocPackageKind::NoStdCrate("guest_test_uefi".into()),
81                            no_deps,
82                            document_private_items,
83                        },
84                    ],
85                    target_triple: target_triple.clone(),
86                    cargo_cmd: v,
87                }
88            });
89
90            ctx.emit_rust_step(format!("document repo for target {target_triple}"), |ctx| {
91                side_effects.to_vec().claim(ctx);
92                let output = output.claim(ctx);
93                let cargo_cmd = cargo_cmd.claim(ctx);
94                move |rt| {
95                    let cargo_cmd = rt.read(cargo_cmd);
96                    let sh = xshell::Shell::new()?;
97                    let out_path = cargo_cmd.run(&sh)?;
98
99                    rt.write(output, &RustdocOutput { docs: out_path });
100                    Ok(())
101                }
102            });
103        }
104
105        Ok(())
106    }
107}