diff options
| -rw-r--r-- | src/github.rs | 1 | ||||
| -rw-r--r-- | src/main.rs | 147 | 
2 files changed, 121 insertions, 27 deletions
| 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 2de21b9..a776070 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; @@ -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")?; @@ -282,22 +309,27 @@ fn update<P: AsRef<Path>>(      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<P: AsRef<Path>>(      repo_path: P,      repo: &github::Repo,  ) -> anyhow::Result<()> { +    let update_time = filetime::FileTime::from_system_time( +        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          .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() -    ); -      // Try updating times on the default ref.      match filetime::set_file_times(          &default_branch_ref, @@ -305,28 +337,34 @@ 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, -                    ) -                        .with_context(|| format!( -                            "unable to set mtime on '{}'", -                            &packed_refs_path.display(), -                        ))? -                ) -            }, -            _ => Err(e), +            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. +                    Ok(set_agefile_time(&repo_path, &repo.pushed_at)?) +                }, +                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 '{}'", @@ -335,3 +373,58 @@ fn update_mtime<P: AsRef<Path>>(      Ok(())  } + +/// Write `update_time` into the repo's `info/web/last-modified` file. +fn set_agefile_time<P: AsRef<Path>>( +    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(()) +} | 
