Skip to main content

oxide_cli/templates/
install.rs

1use std::path::Path;
2
3use anyhow::Result;
4use reqwest::Client;
5use serde::Deserialize;
6
7use crate::{
8  AppContext,
9  auth::token::get_auth_user,
10  cache::{get_cached_template, update_templates_cache},
11  utils::archive::download_and_extract,
12};
13
14#[derive(Deserialize)]
15struct TemplateInfoRes {
16  archive_url: String,
17  commit_sha: String,
18  subdir: Option<String>,
19}
20
21async fn get_template_info(
22  template_name: &str,
23  client: &Client,
24  auth_path: &Path,
25  backend_url: &str,
26) -> Result<TemplateInfoRes> {
27  let user = get_auth_user(auth_path)?;
28
29  let res: TemplateInfoRes = client
30    .get(format!("{backend_url}/template/{template_name}/url"))
31    .bearer_auth(user.token)
32    .header("Content-Type", "application/json")
33    .send()
34    .await?
35    .error_for_status()?
36    .json()
37    .await?;
38
39  Ok(res)
40}
41
42pub async fn install_template(ctx: &AppContext, template_name: &str) -> Result<()> {
43  let info = get_template_info(template_name, &ctx.client, &ctx.paths.auth, &ctx.backend_url).await?;
44
45  // Skip download if the cached commit matches the server's latest
46  if let Some(cached) = get_cached_template(ctx, template_name)?
47    && cached.commit_sha == info.commit_sha
48    && ctx.paths.templates.join(template_name).exists()
49  {
50    println!("Template '{}' is already up to date", template_name);
51    return Ok(());
52  }
53
54  let dest = ctx.paths.templates.join(template_name);
55
56  {
57    let mut guard = ctx.cleanup_state.lock().unwrap_or_else(|e| e.into_inner());
58    *guard = Some(dest.clone());
59  }
60
61  download_and_extract(
62    &ctx.client,
63    &info.archive_url,
64    &dest,
65    info.subdir.as_deref(),
66  )
67  .await?;
68
69  {
70    let mut guard = ctx.cleanup_state.lock().unwrap_or_else(|e| e.into_inner());
71    *guard = None;
72  }
73
74  update_templates_cache(
75    &ctx.paths.templates,
76    Path::new(template_name),
77    &info.commit_sha,
78  )?;
79  println!("Template successfully downloaded");
80
81  Ok(())
82}