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, BACKEND_URL,
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) -> Result<TemplateInfoRes> {
26  let user = get_auth_user(auth_path)?;
27
28  let res: TemplateInfoRes = client
29    .get(format!("{BACKEND_URL}/template/{template_name}/url"))
30    .bearer_auth(user.token)
31    .header("Content-Type", "application/json")
32    .send()
33    .await?
34    .error_for_status()?
35    .json()
36    .await?;
37
38  Ok(res)
39}
40
41pub async fn install_template(ctx: &AppContext, template_name: &str) -> Result<()> {
42  let info = get_template_info(template_name, &ctx.client, &ctx.paths.auth).await?;
43
44  // Skip download if the cached commit matches the server's latest
45  if let Some(cached) = get_cached_template(ctx, template_name)?
46    && cached.commit_sha == info.commit_sha
47    && ctx.paths.templates.join(template_name).exists()
48  {
49    println!("Template '{}' is already up to date", template_name);
50    return Ok(());
51  }
52
53  let dest = ctx.paths.templates.join(template_name);
54
55  {
56    let mut guard = ctx.cleanup_state.lock().unwrap_or_else(|e| e.into_inner());
57    *guard = Some(dest.clone());
58  }
59
60  download_and_extract(
61    &ctx.client,
62    &info.archive_url,
63    &dest,
64    info.subdir.as_deref(),
65  )
66  .await?;
67
68  {
69    let mut guard = ctx.cleanup_state.lock().unwrap_or_else(|e| e.into_inner());
70    *guard = None;
71  }
72
73  update_templates_cache(
74    &ctx.paths.templates,
75    Path::new(template_name),
76    &info.commit_sha,
77  )?;
78  println!("Template successfully downloaded");
79
80  Ok(())
81}