Skip to content

Commit 4558801

Browse files
authored
Merge pull request #99 from Woody4618/commit-hash
Get commit hash from remote
2 parents 5c13843 + 379e88b commit 4558801

File tree

1 file changed

+82
-5
lines changed

1 file changed

+82
-5
lines changed

src/main.rs

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use solana_sdk::{
1616
use std::{
1717
io::Read,
1818
path::PathBuf,
19-
process::{exit, Stdio},
19+
process::{exit, Command, Stdio},
2020
sync::{
2121
atomic::{AtomicBool, Ordering},
2222
Arc,
@@ -154,7 +154,7 @@ async fn main() -> anyhow::Result<()> {
154154
.arg(Arg::with_name("commit-hash")
155155
.long("commit-hash")
156156
.takes_value(true)
157-
.help("Optional commit hash to checkout"))
157+
.help("Commit hash to checkout. Required to know the correct program snapshot. Will fallback to HEAD if not provided"))
158158
.arg(Arg::with_name("program-id")
159159
.long("program-id")
160160
.required(true)
@@ -279,7 +279,6 @@ async fn main() -> anyhow::Result<()> {
279279
let remote = sub_m.is_present("remote");
280280
let mount_path = sub_m.value_of("mount-path").map(|s| s.to_string()).unwrap();
281281
let repo_url = sub_m.value_of("repo-url").map(|s| s.to_string()).unwrap();
282-
let commit_hash = sub_m.value_of("commit-hash").map(|s| s.to_string());
283282
let program_id = sub_m.value_of("program-id").unwrap();
284283
let base_image = sub_m.value_of("base-image").map(|s| s.to_string());
285284
let library_name = sub_m.value_of("library-name").map(|s| s.to_string());
@@ -293,13 +292,27 @@ async fn main() -> anyhow::Result<()> {
293292
.map(|s| s.to_string())
294293
.collect();
295294

296-
println!(" Skipping prompt: {}", skip_prompt);
295+
let commit_hash = sub_m
296+
.value_of("commit-hash")
297+
.map(String::from)
298+
.or_else(|| {
299+
get_commit_hash_from_remote(&repo_url).ok() // Dynamically determine commit hash from remote
300+
})
301+
.ok_or_else(|| {
302+
anyhow::anyhow!(
303+
"Commit hash must be provided or inferred from the remote repository"
304+
)
305+
})?;
306+
307+
println!("Commit hash from remote: {}", commit_hash);
308+
309+
println!("Skipping prompt: {}", skip_prompt);
297310
verify_from_repo(
298311
remote,
299312
mount_path,
300313
&connection,
301314
repo_url,
302-
commit_hash,
315+
Some(commit_hash),
303316
Pubkey::try_from(program_id)?,
304317
base_image,
305318
library_name,
@@ -375,6 +388,70 @@ pub fn get_client(url: Option<String>) -> RpcClient {
375388
RpcClient::new(url)
376389
}
377390

391+
fn get_commit_hash_from_remote(repo_url: &str) -> anyhow::Result<String> {
392+
// Fetch the symbolic reference of the default branch
393+
let output = Command::new("git")
394+
.arg("ls-remote")
395+
.arg("--symref")
396+
.arg(repo_url)
397+
.output()
398+
.map_err(|e| anyhow::anyhow!("Failed to run git ls-remote: {}", e))?;
399+
400+
if !output.status.success() {
401+
return Err(anyhow::anyhow!(
402+
"Failed to fetch default branch information: {}",
403+
String::from_utf8_lossy(&output.stderr)
404+
));
405+
}
406+
407+
// Find out if the branch is called master or main
408+
let output_str = String::from_utf8(output.stdout)?;
409+
let default_branch = output_str
410+
.lines()
411+
.find_map(|line| {
412+
if line.starts_with("ref: refs/heads/") {
413+
Some(
414+
line.trim_start_matches("ref: refs/heads/")
415+
.split_whitespace()
416+
.next()?
417+
.to_string(),
418+
)
419+
} else {
420+
None
421+
}
422+
})
423+
.ok_or_else(|| {
424+
anyhow::anyhow!(
425+
"Unable to determine default branch from remote repository '{}'",
426+
repo_url
427+
)
428+
})?;
429+
430+
println!("Default branch detected: {}", default_branch);
431+
432+
// Fetch the latest commit hash for the default branch
433+
let hash_output = Command::new("git")
434+
.arg("ls-remote")
435+
.arg(repo_url)
436+
.arg(&default_branch)
437+
.output()
438+
.map_err(|e| anyhow::anyhow!("Failed to fetch commit hash for default branch: {}", e))?;
439+
440+
if !hash_output.status.success() {
441+
return Err(anyhow::anyhow!(
442+
"Failed to fetch commit hash: {}",
443+
String::from_utf8_lossy(&hash_output.stderr)
444+
));
445+
}
446+
447+
// Parse and return the commit hash
448+
String::from_utf8(hash_output.stdout)?
449+
.split_whitespace()
450+
.next()
451+
.map(|s| s.to_string())
452+
.ok_or_else(|| anyhow::anyhow!("Failed to parse commit hash from git ls-remote output"))
453+
}
454+
378455
pub fn get_binary_hash(program_data: Vec<u8>) -> String {
379456
let buffer = program_data
380457
.into_iter()

0 commit comments

Comments
 (0)