From 6c92eb6e7470dfb13f1b5aea8015db2b2937bb7e Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 23 Jun 2021 23:10:36 +0200 Subject: main: Use test repositories instead of getting repos from GitHub Add a couple of test repositories that we can use to test empty repository handling. --- src/main.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 2de21b9..f6e69f8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -109,8 +109,35 @@ fn run() -> Result<(), MultiError> { let base_cgitrc = opt_matches.opt_str("cgitrc") .map(|s| PathBuf::from(s)); - let repos = github::fetch_repos(username) - .context("unable to fetch GitHub repositories")?; + // let repos = github::fetch_repos(username) + // .context("unable to fetch GitHub repositories")?; + + let repos = vec![ + github::Repo { + id: 5924490, + name: "THWAP".to_owned(), + description: None, + fork: false, + git_url: "git://github.com/teddywing/THWAP.git".to_owned(), + default_branch: "master".to_owned(), + size: 48, + updated_at: "2013-01-12T09:09:38Z".to_owned(), + // pushed_at: "2012-09-23T17:45:14Z".to_owned(), + }, + github::Repo { + id: 158463778, + name: "youtube-turn-off-annotations".to_owned(), + description: Some( + "A user script that turns off annotations on YouTube videos".to_owned(), + ), + fork: false, + git_url: "git://github.com/teddywing/youtube-turn-off-annotations.git".to_owned(), + default_branch: "master".to_owned(), + size: 17, + updated_at: "2018-11-20T23:44:31Z".to_owned(), + // pushed_at: "2018-11-20T23:44:29Z".to_owned(), + }, + ]; let db = database::Db::connect(&database_file) .context("unable to connect to database")?; -- cgit v1.2.3 From 8695d3845c154ea06a8e69dd0a4552ecc907dcb3 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 23 Jun 2021 23:14:25 +0200 Subject: update_mtime(): Idea for `.or_else()` chaining An idea to chain the error handling here instead of using `match` expressions. --- src/main.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index f6e69f8..8f6b9bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -325,6 +325,46 @@ fn update_mtime>( DateTime::parse_from_rfc3339(&repo.updated_at)?.into() ); + // filetime::set_file_times( + // &default_branch_ref, + // update_time, + // update_time, + // ) + // .or_else(|e| { + // if (e.kind != io::ErrorKind::NotFound) { + // return Err(e); + // } + // + // let packed_refs_path = repo_path + // .as_ref() + // .join("packed-refs"); + // + // filetime::set_file_times( + // &packed_refs_path, + // update_time, + // update_time, + // ) + // }) + // .or_else(|e| { + // if (e.kind != io::ErrorKind::NotFound) { + // return Err(e); + // } + // + // let packed_refs_path = repo_path + // .as_ref() + // .join("packed-refs"); + // + // filetime::set_file_times( + // &packed_refs_path, + // update_time, + // update_time, + // ) + // }) + // .with_context(|| format!( + // "unable to set mtime on '{}'", + // &default_branch_ref.display(), + // ))?; + // Try updating times on the default ref. match filetime::set_file_times( &default_branch_ref, -- cgit v1.2.3 From b0287e272376fe788fffdd0fe7d5e799f3517d6e Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 23 Jun 2021 23:20:51 +0200 Subject: 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. --- src/main.rs | 101 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 22 deletions(-) (limited to 'src') 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>( 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>( 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 '{}'", -- cgit v1.2.3 From 0e2faed4ac9b5950eb786a7127f9fc02df050c25 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 23 Jun 2021 23:34:00 +0200 Subject: update_mtime(): Remove `.or_else()` idea Decided to keep the `match` expressions. Still working out how to clean up the code in this function, though. --- src/main.rs | 40 ---------------------------------------- 1 file changed, 40 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 6dae021..be06c28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -326,46 +326,6 @@ fn update_mtime>( .join("refs/heads") .join(&repo.default_branch); - // filetime::set_file_times( - // &default_branch_ref, - // update_time, - // update_time, - // ) - // .or_else(|e| { - // if (e.kind != io::ErrorKind::NotFound) { - // return Err(e); - // } - // - // let packed_refs_path = repo_path - // .as_ref() - // .join("packed-refs"); - // - // filetime::set_file_times( - // &packed_refs_path, - // update_time, - // update_time, - // ) - // }) - // .or_else(|e| { - // if (e.kind != io::ErrorKind::NotFound) { - // return Err(e); - // } - // - // let packed_refs_path = repo_path - // .as_ref() - // .join("packed-refs"); - // - // filetime::set_file_times( - // &packed_refs_path, - // update_time, - // update_time, - // ) - // }) - // .with_context(|| format!( - // "unable to set mtime on '{}'", - // &default_branch_ref.display(), - // ))?; - // Try updating times on the default ref. match filetime::set_file_times( &default_branch_ref, -- cgit v1.2.3 From 5de391101d72f0d2239a69073b08861641d9c878 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 23 Jun 2021 23:45:47 +0200 Subject: update_mtime(): Extract agefile handling to a separate function The `update_mtime()` function is getting pretty long. Extract this into a new function since it's more of a self-contained unit. --- src/main.rs | 107 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 56 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index be06c28..a888883 100644 --- a/src/main.rs +++ b/src/main.rs @@ -349,57 +349,7 @@ fn update_mtime>( 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 write to '{}'", - &cgitrc_path.display(), - ))?; - - Ok(()) + Ok(set_agefile_time(&repo_path, &repo.updated_at)?) }, Err(e) => Err(e), } @@ -419,3 +369,58 @@ fn update_mtime>( Ok(()) } + +/// Write `update_time` into the repo's `info/web/last-modified` file. +fn set_agefile_time>( + repo_path: P, + update_time: &str, +) -> anyhow::Result<()> { + 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, "{}", &update_time) + .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 write to '{}'", + &cgitrc_path.display(), + ))?; + + Ok(()) +} -- cgit v1.2.3 From 1aaef56e5b3c3f4ba6e479c809bd77bc585c716b Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 23 Jun 2021 23:52:19 +0200 Subject: update_mtime(): Set the mtime to the repo's `pushed_at` time Use `pushed_at` instead of `updated_at`. This mtime is used to sort repositories on CGit's repository index page. Prevent things like GitHub stars from changing the sort order. The sort should instead be influenced by repository changes. --- src/github.rs | 1 + src/main.rs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/github.rs b/src/github.rs index 5289a0d..a3bb74e 100644 --- a/src/github.rs +++ b/src/github.rs @@ -47,6 +47,7 @@ pub struct Repo { pub default_branch: String, pub size: u64, pub updated_at: String, + pub pushed_at: String, } impl Repo { diff --git a/src/main.rs b/src/main.rs index a888883..a776070 100644 --- a/src/main.rs +++ b/src/main.rs @@ -122,7 +122,7 @@ fn run() -> Result<(), MultiError> { default_branch: "master".to_owned(), size: 48, updated_at: "2013-01-12T09:09:38Z".to_owned(), - // pushed_at: "2012-09-23T17:45:14Z".to_owned(), + pushed_at: "2012-09-23T17:45:14Z".to_owned(), }, github::Repo { id: 158463778, @@ -135,7 +135,7 @@ fn run() -> Result<(), MultiError> { default_branch: "master".to_owned(), size: 17, updated_at: "2018-11-20T23:44:31Z".to_owned(), - // pushed_at: "2018-11-20T23:44:29Z".to_owned(), + pushed_at: "2018-11-20T23:44:29Z".to_owned(), }, ]; @@ -309,16 +309,20 @@ fn update>( Ok(()) } -/// Set the mtime of the repository to GitHub's `updated_at` time. +/// Set the mtime of the repository to GitHub's `pushed_at` time. /// /// Used for CGit "age" sorting. fn update_mtime>( 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() + DateTime::parse_from_rfc3339(&repo.pushed_at) + .with_context(|| format!( + "unable to parse update time from '{}'", + &repo.pushed_at, + ))? + .into() ); let default_branch_ref = repo_path @@ -349,7 +353,7 @@ fn update_mtime>( 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. - Ok(set_agefile_time(&repo_path, &repo.updated_at)?) + Ok(set_agefile_time(&repo_path, &repo.pushed_at)?) }, Err(e) => Err(e), } -- cgit v1.2.3