flowey_lib_common/
download_protoc.rs1use flowey::node::prelude::*;
7
8#[derive(Serialize, Deserialize)]
9pub struct ProtocPackage {
10 pub protoc_bin: PathBuf,
11 pub include_dir: PathBuf,
12}
13
14flowey_request! {
15 pub enum Request {
16 Version(String),
18 Get(WriteVar<ProtocPackage>),
20 }
21}
22
23new_flow_node!(struct Node);
24
25impl FlowNode for Node {
26 type Request = Request;
27
28 fn imports(ctx: &mut ImportCtx<'_>) {
29 ctx.import::<crate::install_dist_pkg::Node>();
30 ctx.import::<crate::download_gh_release::Node>();
31 ctx.import::<crate::cache::Node>();
32 }
33
34 fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
35 let mut version = None;
36 let mut get_reqs = Vec::new();
37
38 for req in requests {
39 match req {
40 Request::Version(v) => same_across_all_reqs("Version", &mut version, v)?,
41 Request::Get(v) => get_reqs.push(v),
42 }
43 }
44
45 let version = version.ok_or(anyhow::anyhow!("Missing essential request: Version"))?;
46
47 if get_reqs.is_empty() {
50 return Ok(());
51 }
52
53 let tag = format!("v{version}");
54 let file_name = format!(
55 "protoc-{}-{}.zip",
56 version,
57 match (ctx.platform(), ctx.arch()) {
58 (FlowPlatform::Windows, _) => "win64",
61 (FlowPlatform::Linux(_), FlowArch::X86_64) => "linux-x86_64",
62 (FlowPlatform::Linux(_), FlowArch::Aarch64) => "linux-aarch_64",
63 (FlowPlatform::MacOs, FlowArch::X86_64) => "osx-x86_64",
64 (FlowPlatform::MacOs, FlowArch::Aarch64) => "osx-aarch_64",
65 (platform, arch) => anyhow::bail!("unsupported platform {platform} {arch}"),
66 }
67 );
68
69 let protoc_zip = ctx.reqv(|v| crate::download_gh_release::Request {
70 repo_owner: "protocolbuffers".into(),
71 repo_name: "protobuf".into(),
72 needs_auth: false,
73 tag: tag.clone(),
74 file_name: file_name.clone(),
75 path: v,
76 });
77
78 let extract_zip_deps = crate::_util::extract::extract_zip_if_new_deps(ctx);
79 ctx.emit_rust_step("unpack protoc", |ctx| {
80 let extract_zip_deps = extract_zip_deps.clone().claim(ctx);
81 let get_reqs = get_reqs.claim(ctx);
82 let protoc_zip = protoc_zip.claim(ctx);
83 move |rt| {
84 let protoc_zip = rt.read(protoc_zip);
85
86 let extract_dir = crate::_util::extract::extract_zip_if_new(
87 rt,
88 extract_zip_deps,
89 &protoc_zip,
90 &tag,
91 )?;
92
93 let protoc_bin = extract_dir
94 .join("bin")
95 .join(rt.platform().binary("protoc"))
96 .absolute()?;
97
98 assert!(protoc_bin.exists());
99
100 #[cfg(unix)]
102 {
103 use std::os::unix::fs::PermissionsExt;
104 let old_mode = protoc_bin.metadata()?.permissions().mode();
105 fs_err::set_permissions(
106 &protoc_bin,
107 std::fs::Permissions::from_mode(old_mode | 0o111),
108 )?;
109 }
110
111 let protoc_includes = extract_dir.join("include").absolute()?;
112 assert!(protoc_includes.exists());
113
114 let pkg = ProtocPackage {
115 protoc_bin,
116 include_dir: protoc_includes,
117 };
118
119 rt.write_all(get_reqs, &pkg);
120
121 Ok(())
122 }
123 });
124
125 Ok(())
126 }
127}