Skip to content

Commit

Permalink
feat: Improve error handling (#398)
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-maker1994 authored Jan 22, 2025
1 parent 8730bdb commit 8fe8930
Showing 1 changed file with 48 additions and 20 deletions.
68 changes: 48 additions & 20 deletions crates/tuono/src/scaffold_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ struct GithubTreeResponse<T> {
tree: Vec<T>,
}

fn exit_with_error(message: &str) -> ! {
eprintln!("{}", message);
std::process::exit(1);
}

#[derive(Deserialize, Debug)]
struct GithubFile {
path: String,
Expand All @@ -44,7 +49,13 @@ struct GithubFile {
}

fn create_file(path: PathBuf, content: String) -> std::io::Result<()> {
let mut file = File::create(path)?;
let mut file = File::create(&path).unwrap_or_else(|err| {
exit_with_error(&format!(
"Failed to create file {}: {}",
path.display(),
err
));
});
let _ = file.write_all(content.as_bytes());

Ok(())
Expand All @@ -55,21 +66,23 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)

// In case of missing select the tuono example
let template = template.unwrap_or("tuono-app".to_string());

let client = blocking::Client::builder()
.user_agent("")
.build()
.expect("Failed to build reqwest client");
.unwrap_or_else(|_| exit_with_error("Error: Failed to build request client"));

// This string does not include the "v" version prefix
let cli_version: &str = crate_version!();

let res_tag = client
let res_tag: GithubTagResponse = client
.get(format!("{}v{}", GITHUB_TUONO_TAGS_URL, cli_version))
.send()
.unwrap_or_else(|_| panic!("Failed to call the tag github API for v{cli_version}"))
.json::<GithubTagResponse>()
.expect("Failed to parse the tag response");
.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;

Expand All @@ -80,7 +93,9 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
))
.send()
.unwrap_or_else(|_| {
panic!("Failed to call the tagged commit tree github API for v{cli_version}")
exit_with_error(&format!(
"Failed to call the tagged commit tree github API for v{cli_version}"
))
})
.json::<GithubTreeResponse<GithubFile>>()
.expect("Failed to parse the tree structure");
Expand Down Expand Up @@ -112,7 +127,7 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
let folder_path = current_dir.join(folder_name);

create_directories(&new_project_files, &folder_path, &template)
.expect("Failed to create directories");
.unwrap_or_else(|err| exit_with_error(&format!("Failed to create directories: {}", err)));

for GithubFile {
element_type, path, ..
Expand All @@ -122,15 +137,21 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
let file_content = client
.get(format!("{GITHUB_RAW_CONTENT_URL}/v{cli_version}/{path}"))
.send()
.expect("Failed to call the folder github API")
.text()
.expect("Failed to parse the repo structure");
.map_err(|_| exit_with_error("Failed to call the folder github API"))
.and_then(|response| {
response
.text()
.map_err(|_| exit_with_error("Failed to parse the repo structure"))
})
.unwrap();

let path = PathBuf::from(&path.replace(&format!("examples/{template}/"), ""));

let file_path = folder_path.join(&path);

create_file(file_path, file_content).expect("failed to create file");
if let Err(err) = create_file(file_path, file_content) {
exit_with_error(&format!("Failed to create file: {}", err));
}
}
}

Expand All @@ -157,36 +178,43 @@ fn create_directories(
}
Ok(())
}

fn update_package_json_version(folder_path: &Path) -> io::Result<()> {
let v = crate_version!();
let package_json_path = folder_path.join(PathBuf::from("package.json"));
let package_json = fs::read_to_string(&package_json_path)?;
let package_json = fs::read_to_string(&package_json_path)
.unwrap_or_else(|err| exit_with_error(&format!("Failed to read package.json: {}", err)));
let package_json = package_json.replace("link:../../packages/tuono", v);

let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.open(package_json_path)?;
.open(package_json_path)
.unwrap_or_else(|err| exit_with_error(&format!("Failed to open package.json: {}", err)));

file.write_all(package_json.as_bytes())?;
file.write_all(package_json.as_bytes())
.unwrap_or_else(|err| {
exit_with_error(&format!("Failed to write to package.json: {}", err))
});

Ok(())
}

fn update_cargo_toml_version(folder_path: &Path) -> io::Result<()> {
let v = crate_version!();
let cargo_toml_path = folder_path.join(PathBuf::from("Cargo.toml"));
let cargo_toml = fs::read_to_string(&cargo_toml_path)?;
let cargo_toml = fs::read_to_string(&cargo_toml_path)
.unwrap_or_else(|err| exit_with_error(&format!("Failed to read Cargo.toml: {}", err)));
let cargo_toml =
cargo_toml.replace("{ path = \"../../crates/tuono_lib/\"}", &format!("\"{v}\""));

let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.open(cargo_toml_path)?;
.open(cargo_toml_path)
.unwrap_or_else(|err| exit_with_error(&format!("Failed to open Cargo.toml: {}", err)));

file.write_all(cargo_toml.as_bytes())?;
file.write_all(cargo_toml.as_bytes())
.unwrap_or_else(|err| exit_with_error(&format!("Failed to write to Cargo.toml: {}", err)));

Ok(())
}
Expand Down

0 comments on commit 8fe8930

Please sign in to comment.