feat(crates/tuono): add --head flag to download most recent template (#408)

Co-authored-by: Valerio Ageno <51341197+Valerioageno@users.noreply.github.com>
This commit is contained in:
Jacob Marshall
2025-01-25 12:42:29 +00:00
committed by GitHub
parent 3cb150b090
commit d5cc65983e
2 changed files with 80 additions and 18 deletions
+5 -1
View File
@@ -33,6 +33,9 @@ enum Actions {
/// examples
#[arg(short, long)]
template: Option<String>,
/// Load the latest commit available on the main branch
#[arg(long)]
head: Option<bool>,
},
}
@@ -142,8 +145,9 @@ pub fn app() -> std::io::Result<()> {
Actions::New {
folder_name,
template,
head,
} => {
scaffold_project::create_new_project(folder_name, template);
scaffold_project::create_new_project(folder_name, template, head);
}
}
+75 -17
View File
@@ -1,5 +1,6 @@
use clap::crate_version;
use reqwest::blocking;
use reqwest::blocking::Client;
use serde::Deserialize;
use std::env;
use std::fs::{self, create_dir, File, OpenOptions};
@@ -61,7 +62,11 @@ fn create_file(path: PathBuf, content: String) -> std::io::Result<()> {
Ok(())
}
pub fn create_new_project(folder_name: Option<String>, template: Option<String>) {
pub fn create_new_project(
folder_name: Option<String>,
template: Option<String>,
select_head: Option<bool>,
) {
let folder = folder_name.unwrap_or(".".to_string());
// In case of missing select the tuono example
@@ -74,23 +79,10 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
// This string does not include the "v" version prefix
let cli_version: &str = crate_version!();
let res_tag: GithubTagResponse = client
.get(format!("{}v{}", GITHUB_TUONO_TAGS_URL, cli_version))
.send()
.and_then(|response| response.json::<GithubTagResponse>())
.unwrap_or_else(|_| {
exit_with_error(&format!(
"Error: Failed to call or parse the tag github API for v{cli_version}"
))
});
let sha_tagged_commit = res_tag.object.sha;
let tree_url: String = generate_tree_url(select_head, &client, cli_version);
let res_tree = client
.get(format!(
"{}{}?recursive=1",
GITHUB_TUONO_TAG_COMMIT_TREES_URL, sha_tagged_commit
))
.get(tree_url)
.send()
.unwrap_or_else(|_| {
exit_with_error(&format!(
@@ -134,8 +126,10 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
} in new_project_files.iter()
{
if let GithubFileType::Blob = element_type {
let url = generate_raw_content_url(select_head, cli_version, path);
let file_content = client
.get(format!("{GITHUB_RAW_CONTENT_URL}/v{cli_version}/{path}"))
.get(url)
.send()
.map_err(|_| exit_with_error("Failed to call the folder github API"))
.and_then(|response| {
@@ -160,6 +154,36 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
outro(folder);
}
fn generate_raw_content_url(select_head: Option<bool>, cli_version: &str, path: &String) -> String {
let tag = if select_head.unwrap_or(false) {
"main"
} else {
&format!("v{cli_version}")
};
format!("{}/{}/{}", GITHUB_RAW_CONTENT_URL, tag, path)
}
fn generate_tree_url(select_head: Option<bool>, client: &Client, cli_version: &str) -> String {
if select_head.unwrap_or(false) {
format!("{}main?recursive=1", GITHUB_TUONO_TAG_COMMIT_TREES_URL)
} else {
// This string does not include the "v" version prefix
let res_tag = client
.get(format!("{}v{}", GITHUB_TUONO_TAGS_URL, cli_version))
.send()
.unwrap_or_else(|_| {
exit_with_error("Failed to call the tag github API for v{cli_version}")
})
.json::<GithubTagResponse>()
.unwrap_or_else(|_| exit_with_error("Failed to parse the tag response"));
format!(
"{}{}?recursive=1",
GITHUB_TUONO_TAG_COMMIT_TREES_URL, res_tag.object.sha
)
}
}
fn create_directories(
new_project_files: &[&GithubFile],
folder_path: &Path,
@@ -233,3 +257,37 @@ fn outro(folder_name: String) {
println!("\nRun the local environment:");
println!("tuono dev");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn generate_valid_content_url_from_head() {
let expected = format!(
"{}/{}/{}",
GITHUB_RAW_CONTENT_URL, "main", "examples/tuono-app"
);
let generated = generate_raw_content_url(
Some(true),
crate_version!(),
&String::from("examples/tuono-app"),
);
assert_eq!(expected, generated)
}
#[test]
fn generate_valid_content_url_from_cli_version() {
let expected = format!(
"{}/{}/{}",
GITHUB_RAW_CONTENT_URL,
&format!("v{}", crate_version!()),
"examples/tuono-app"
);
let generated = generate_raw_content_url(
Some(false),
crate_version!(),
&String::from("examples/tuono-app"),
);
assert_eq!(expected, generated)
}
}