flowey_lib_hvlite/
init_openvmm_magicpath_protoc.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Ensure protoc is symlinked into the correct "magic directory" set by the
5//! project-level `[env]` table in `.cargo/config.toml`
6
7use flowey::node::prelude::*;
8
9flowey_request! {
10    pub struct Request(pub WriteVar<SideEffect>);
11}
12
13new_flow_node!(struct Node);
14
15impl FlowNode for Node {
16    type Request = Request;
17
18    fn imports(ctx: &mut ImportCtx<'_>) {
19        ctx.import::<crate::cfg_openvmm_magicpath::Node>();
20        ctx.import::<flowey_lib_common::resolve_protoc::Node>();
21    }
22
23    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
24        let protoc_pkg = ctx.reqv(flowey_lib_common::resolve_protoc::Request::Get);
25        let openvmm_magicpath = ctx.reqv(crate::cfg_openvmm_magicpath::Request);
26
27        ctx.emit_rust_step("symlink protoc", move |ctx| {
28            requests.into_iter().for_each(|x| {
29                x.0.claim(ctx);
30            });
31            let protoc_pkg = protoc_pkg.claim(ctx);
32            let openvmm_magicpath = openvmm_magicpath.claim(ctx);
33            move |rt| {
34                let expected_protoc_bin = {
35                    match rt.platform() {
36                        FlowPlatform::Windows => "protoc.exe",
37                        FlowPlatform::MacOs | FlowPlatform::Linux(_) => "protoc",
38                        _ => unreachable!("unknown host os"),
39                    }
40                };
41
42                let openvmm_magicpath = rt.read(openvmm_magicpath);
43                let dst_folder = openvmm_magicpath.join("Google.Protobuf.Tools/tools");
44                fs_err::create_dir_all(&dst_folder)?;
45
46                let protoc_pkg = rt.read(protoc_pkg);
47
48                let include_dst = openvmm_magicpath.join("Google.Protobuf.Tools/tools/include");
49
50                #[cfg(unix)]
51                {
52                    // May be a symlink from previous run or directory from old code
53                    let _ = fs_err::remove_file(&include_dst);
54                    let _ = fs_err::remove_dir_all(&include_dst);
55                    fs_err::os::unix::fs::symlink(&protoc_pkg.include_dir, &include_dst)?;
56                }
57                #[cfg(windows)]
58                {
59                    let _ = fs_err::remove_dir_all(&include_dst);
60                    flowey_lib_common::_util::copy_dir_all(&protoc_pkg.include_dir, &include_dst)?;
61                }
62
63                let src = protoc_pkg.protoc_bin;
64                let dst = dst_folder.join(expected_protoc_bin);
65
66                let _ = fs_err::remove_file(&dst);
67
68                if !dst.exists() {
69                    #[cfg(unix)]
70                    fs_err::os::unix::fs::symlink(&src, &dst)?;
71                    #[cfg(windows)]
72                    fs_err::copy(&src, &dst)?;
73                }
74
75                Ok(())
76            }
77        });
78
79        Ok(())
80    }
81}