fix: use https to get goose recipes and cleanup temp cloned dir if the clone repo is not in good state (#2674)
This commit is contained in:
Generated
+4
@@ -2695,10 +2695,12 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"docx-rs",
|
"docx-rs",
|
||||||
"etcetera",
|
"etcetera",
|
||||||
|
"google-apis-common",
|
||||||
"google-docs1",
|
"google-docs1",
|
||||||
"google-drive3",
|
"google-drive3",
|
||||||
"google-sheets4",
|
"google-sheets4",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
|
"hyper 1.6.0",
|
||||||
"ignore",
|
"ignore",
|
||||||
"image 0.24.9",
|
"image 0.24.9",
|
||||||
"include_dir",
|
"include_dir",
|
||||||
@@ -2715,6 +2717,7 @@ dependencies = [
|
|||||||
"reqwest 0.11.27",
|
"reqwest 0.11.27",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_with",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"sysinfo 0.32.1",
|
"sysinfo 0.32.1",
|
||||||
@@ -2727,6 +2730,7 @@ dependencies = [
|
|||||||
"umya-spreadsheet",
|
"umya-spreadsheet",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
|
"utoipa",
|
||||||
"webbrowser",
|
"webbrowser",
|
||||||
"xcap",
|
"xcap",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -20,32 +20,62 @@ pub fn retrieve_recipe_from_github(
|
|||||||
recipe_name, recipe_repo_full_name
|
recipe_name, recipe_repo_full_name
|
||||||
);
|
);
|
||||||
ensure_gh_authenticated()?;
|
ensure_gh_authenticated()?;
|
||||||
let local_repo_path = ensure_repo_cloned(recipe_repo_full_name)?;
|
let max_attempts = 2;
|
||||||
fetch_origin(&local_repo_path)?;
|
let mut last_err = None;
|
||||||
let download_dir = get_folder_from_github(&local_repo_path, recipe_name)?;
|
|
||||||
|
|
||||||
|
for attempt in 1..=max_attempts {
|
||||||
|
match clone_and_download_recipe(recipe_name, recipe_repo_full_name) {
|
||||||
|
Ok(download_dir) => match read_recipe_file(&download_dir) {
|
||||||
|
Ok(content) => return Ok((content, download_dir)),
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
last_err = Some(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if attempt < max_attempts {
|
||||||
|
clean_cloned_dirs(recipe_repo_full_name)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(last_err.unwrap_or_else(|| anyhow::anyhow!("Unknown error occurred")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clean_cloned_dirs(recipe_repo_full_name: &str) -> anyhow::Result<()> {
|
||||||
|
let local_repo_path = get_local_repo_path(&env::temp_dir(), recipe_repo_full_name)?;
|
||||||
|
if local_repo_path.exists() {
|
||||||
|
fs::remove_dir_all(&local_repo_path)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn read_recipe_file(download_dir: &Path) -> Result<String> {
|
||||||
for ext in RECIPE_FILE_EXTENSIONS {
|
for ext in RECIPE_FILE_EXTENSIONS {
|
||||||
let candidate_file_path = download_dir.join(format!("recipe.{}", ext));
|
let candidate_file_path = download_dir.join(format!("recipe.{}", ext));
|
||||||
if candidate_file_path.exists() {
|
if candidate_file_path.exists() {
|
||||||
let content = std::fs::read_to_string(&candidate_file_path)?;
|
let content = fs::read_to_string(&candidate_file_path)?;
|
||||||
println!(
|
println!(
|
||||||
"⬇️ Retrieved recipe from github repo {}/{}",
|
"⬇️ Retrieved recipe file: {}",
|
||||||
recipe_repo_full_name,
|
|
||||||
candidate_file_path
|
candidate_file_path
|
||||||
.strip_prefix(&download_dir)
|
.strip_prefix(download_dir)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.display()
|
.display()
|
||||||
);
|
);
|
||||||
return Ok((content, download_dir));
|
return Ok(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(anyhow::anyhow!(
|
Err(anyhow::anyhow!(
|
||||||
"Failed to retrieve recipe.yaml or recipe.json in path {} in github repo {} ",
|
"No recipe file found in {} (looked for extensions: {:?})",
|
||||||
recipe_name,
|
download_dir.display(),
|
||||||
recipe_repo_full_name,
|
RECIPE_FILE_EXTENSIONS
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_and_download_recipe(recipe_name: &str, recipe_repo_full_name: &str) -> Result<PathBuf> {
|
||||||
|
let local_repo_path = ensure_repo_cloned(recipe_repo_full_name)?;
|
||||||
|
fetch_origin(&local_repo_path)?;
|
||||||
|
get_folder_from_github(&local_repo_path, recipe_name)
|
||||||
|
}
|
||||||
|
|
||||||
fn ensure_gh_authenticated() -> Result<()> {
|
fn ensure_gh_authenticated() -> Result<()> {
|
||||||
// Check authentication status
|
// Check authentication status
|
||||||
let status = Command::new("gh")
|
let status = Command::new("gh")
|
||||||
@@ -61,7 +91,7 @@ fn ensure_gh_authenticated() -> Result<()> {
|
|||||||
println!("GitHub CLI is not authenticated. Launching `gh auth login`...");
|
println!("GitHub CLI is not authenticated. Launching `gh auth login`...");
|
||||||
// Run `gh auth login` interactively
|
// Run `gh auth login` interactively
|
||||||
let login_status = Command::new("gh")
|
let login_status = Command::new("gh")
|
||||||
.args(["auth", "login"])
|
.args(["auth", "login", "--git-protocol", "https"])
|
||||||
.status()
|
.status()
|
||||||
.map_err(|_| anyhow::anyhow!("Failed to run `gh auth login`"))?;
|
.map_err(|_| anyhow::anyhow!("Failed to run `gh auth login`"))?;
|
||||||
|
|
||||||
@@ -72,20 +102,27 @@ fn ensure_gh_authenticated() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_repo_cloned(recipe_repo_full_name: &str) -> Result<PathBuf> {
|
fn get_local_repo_path(
|
||||||
let local_repo_parent_path = env::temp_dir();
|
local_repo_parent_path: &Path,
|
||||||
|
recipe_repo_full_name: &str,
|
||||||
|
) -> Result<PathBuf> {
|
||||||
let (_, repo_name) = recipe_repo_full_name
|
let (_, repo_name) = recipe_repo_full_name
|
||||||
.split_once('/')
|
.split_once('/')
|
||||||
.ok_or_else(|| anyhow::anyhow!("Invalid repository name format"))?;
|
.ok_or_else(|| anyhow::anyhow!("Invalid repository name format"))?;
|
||||||
|
let local_repo_path = local_repo_parent_path.to_path_buf().join(repo_name);
|
||||||
|
Ok(local_repo_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ensure_repo_cloned(recipe_repo_full_name: &str) -> Result<PathBuf> {
|
||||||
|
let local_repo_parent_path = env::temp_dir();
|
||||||
|
if !local_repo_parent_path.exists() {
|
||||||
|
std::fs::create_dir_all(local_repo_parent_path.clone())?;
|
||||||
|
}
|
||||||
|
let local_repo_path = get_local_repo_path(&local_repo_parent_path, recipe_repo_full_name)?;
|
||||||
|
|
||||||
let local_repo_path = local_repo_parent_path.clone().join(repo_name);
|
|
||||||
if local_repo_path.join(".git").exists() {
|
if local_repo_path.join(".git").exists() {
|
||||||
Ok(local_repo_path)
|
Ok(local_repo_path)
|
||||||
} else {
|
} else {
|
||||||
// Create the local repo parent directory if it doesn't exist
|
|
||||||
if !local_repo_parent_path.exists() {
|
|
||||||
std::fs::create_dir_all(local_repo_parent_path.clone())?;
|
|
||||||
}
|
|
||||||
let error_message: String = format!("Failed to clone repo: {}", recipe_repo_full_name);
|
let error_message: String = format!("Failed to clone repo: {}", recipe_repo_full_name);
|
||||||
let status = Command::new("gh")
|
let status = Command::new("gh")
|
||||||
.args(["repo", "clone", recipe_repo_full_name])
|
.args(["repo", "clone", recipe_repo_full_name])
|
||||||
|
|||||||
Reference in New Issue
Block a user