diff options
author | Teddy Wing | 2021-06-23 23:20:51 +0200 |
---|---|---|
committer | Teddy Wing | 2021-06-23 23:20:51 +0200 |
commit | b0287e272376fe788fffdd0fe7d5e799f3517d6e (patch) | |
tree | 9e535e17ed621395a6bc6606fa954d8367f67a13 | |
parent | 8695d3845c154ea06a8e69dd0a4552ecc907dcb3 (diff) | |
download | reflectub-b0287e272376fe788fffdd0fe7d5e799f3517d6e.tar.bz2 |
update_mtime(): Write update time to CGit agefile as last recourse
Adjust the match arms to remove a bit of indentation.
Add some 'anyhow' context to errors for better error reporting.
When "repo/refs/heads/[default-branch]" or "repo/packed-refs" files
don't exist, create a "repo/info/web/last-modified" file and set this
file as the CGit agefile in the repo's local 'cgitrc' file.
It's possible for a repo to not have either of the first two files when
the repo is empty and has no commits.
-rw-r--r-- | src/main.rs | 101 |
1 files changed, 79 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs index 8f6b9bb..6dae021 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,7 @@ use multi_error::MultiError; use std::env; use std::fs; -use std::io; +use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::process; @@ -316,15 +316,16 @@ fn update_mtime<P: AsRef<Path>>( repo_path: P, repo: &github::Repo, ) -> anyhow::Result<()> { + // TODO: Use `pushed_at` instead of `updated_at` to set the mtime. + let update_time = filetime::FileTime::from_system_time( + DateTime::parse_from_rfc3339(&repo.updated_at)?.into() + ); + let default_branch_ref = repo_path .as_ref() .join("refs/heads") .join(&repo.default_branch); - let update_time = filetime::FileTime::from_system_time( - DateTime::parse_from_rfc3339(&repo.updated_at)?.into() - ); - // filetime::set_file_times( // &default_branch_ref, // update_time, @@ -372,28 +373,84 @@ fn update_mtime<P: AsRef<Path>>( update_time, ) { Ok(_) => Ok(()), - Err(e) => match e.kind() { + Err(e) if e.kind() == io::ErrorKind::NotFound => { // If the default ref file doesn't exist, update times on the // 'packed-refs' file. - io::ErrorKind::NotFound => { - let packed_refs_path = repo_path - .as_ref() - .join("packed-refs"); - - Ok( - filetime::set_file_times( - &packed_refs_path, - update_time, - update_time, + let packed_refs_path = repo_path + .as_ref() + .join("packed-refs"); + + match filetime::set_file_times( + &packed_refs_path, + update_time, + update_time, + ) { + Ok(_) => Ok(()), + Err(e) if e.kind() == io::ErrorKind::NotFound => { + // In the absence of a 'packed-refs' file, create a CGit + // agefile and add the update time to it. + let agefile_dir = repo_path.as_ref().join("info/web"); + + fs::DirBuilder::new() + .create(&agefile_dir) + .with_context(|| format!( + "unable to create directory '{}'", + &agefile_dir.display(), + ))?; + + let agefile_path = agefile_dir.join("last-modified"); + + let mut agefile = fs::OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(&agefile_path) + .with_context(|| format!( + "unable to open '{}'", + &agefile_path.display(), + ))?; + + writeln!(agefile, "{}", &repo.updated_at) + .with_context(|| format!( + "unable to write to '{}'", + &agefile_path.display(), + ))?; + + let cgitrc_path = repo_path + .as_ref() + .join("cgitrc"); + + let mut cgitrc_file = fs::OpenOptions::new() + .append(true) + .create(true) + .open(&cgitrc_path) + .with_context(|| format!( + "unable to open '{}'", + &cgitrc_path.display(), + ))?; + + writeln!( + cgitrc_file, + "{}", + "agefile=info/web/last-modified", ) .with_context(|| format!( - "unable to set mtime on '{}'", - &packed_refs_path.display(), - ))? - ) - }, - _ => Err(e), + "unable to write to '{}'", + &cgitrc_path.display(), + ))?; + + Ok(()) + }, + Err(e) => Err(e), + } + .with_context(|| format!( + "unable to set mtime on '{}'", + &packed_refs_path.display(), + ))?; + + Ok(()) }, + Err(e) => Err(e), } .with_context(|| format!( "unable to set mtime on '{}'", |