flowey_lib_common/
download_mdbook.rs1use flowey::node::prelude::*;
7
8flowey_config! {
9 pub struct Config {
11 pub version: Option<String>,
13 }
14}
15
16flowey_request! {
17 pub enum Request {
18 GetMdbook(WriteVar<PathBuf>),
20 }
21}
22
23new_flow_node_with_config!(struct Node);
24
25impl FlowNodeWithConfig for Node {
26 type Request = Request;
27 type Config = Config;
28
29 fn imports(ctx: &mut ImportCtx<'_>) {
30 ctx.import::<crate::install_dist_pkg::Node>();
31 ctx.import::<crate::download_gh_release::Node>();
32 }
33
34 fn emit(
35 config: Config,
36 requests: Vec<Self::Request>,
37 ctx: &mut NodeCtx<'_>,
38 ) -> anyhow::Result<()> {
39 let (version, get_mdbook) =
40 collect_download_requests(config.version, requests, |Request::GetMdbook(v)| v)?;
41
42 if get_mdbook.is_empty() {
43 return Ok(());
44 }
45
46 download_mdbook_tool(ctx, "mdbook", "rust-lang", "mdBook", &version, get_mdbook)
47 }
48}
49
50pub(crate) fn collect_download_requests<T>(
51 version: Option<String>,
52 requests: Vec<T>,
53 get_path: impl FnMut(T) -> WriteVar<PathBuf>,
54) -> anyhow::Result<(String, Vec<WriteVar<PathBuf>>)> {
55 let version = version.ok_or(anyhow::anyhow!("missing config: version"))?;
56 let paths = requests.into_iter().map(get_path).collect();
57 Ok((version, paths))
58}
59
60pub(crate) fn download_mdbook_tool(
61 ctx: &mut NodeCtx<'_>,
62 name: &str,
63 repo_owner: &str,
64 repo_name: &str,
65 version: &str,
66 paths: Vec<WriteVar<PathBuf>>,
67) -> anyhow::Result<()> {
68 let binary = ctx.platform().binary(name);
69 let tag = format!("v{version}");
70 let file_name = format!(
71 "{name}-v{version}-x86_64-{}",
72 match ctx.platform() {
73 FlowPlatform::Windows => "pc-windows-msvc.zip",
74 FlowPlatform::Linux(_) => "unknown-linux-gnu.tar.gz",
75 FlowPlatform::MacOs => "apple-darwin.tar.gz",
76 platform => anyhow::bail!("unsupported platform {platform}"),
77 }
78 );
79
80 let archive = ctx.reqv(|v| crate::download_gh_release::Request {
81 repo_owner: repo_owner.into(),
82 repo_name: repo_name.into(),
83 needs_auth: false,
84 tag: tag.clone(),
85 file_name,
86 path: v,
87 });
88
89 let extract_zip_deps = crate::_util::extract::extract_zip_if_new_deps(ctx);
90 ctx.emit_rust_step(format!("unpack {name}"), |ctx| {
91 let extract_zip_deps = extract_zip_deps.claim(ctx);
92 let paths = paths.claim(ctx);
93 let archive = archive.claim(ctx);
94 move |rt| {
95 let archive = rt.read(archive);
96
97 let extract_dir =
98 crate::_util::extract::extract_zip_if_new(rt, extract_zip_deps, &archive, &tag)?;
99
100 rt.write_all(paths, &extract_dir.join(binary));
101
102 Ok(())
103 }
104 });
105 Ok(())
106}