Compare commits

...

2 Commits

Author SHA1 Message Date
cuddle-please
5b670ed775 chore(release): 0.2.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2024-09-14 19:22:00 +00:00
e4d5d5302e
feat: add cache get
All checks were successful
continuous-integration/drone/push Build is passing
This now introduces the `settings.cache.duration` key, which can either be false, true (default)

or a map `{days, hours, minutes}` for how long the cache should last. If the cache is expired an eager load of the repositories will be executed

Signed-off-by: kjuulh <contact@kjuulh.io>
2024-09-14 21:17:20 +02:00
7 changed files with 131 additions and 13 deletions

View File

@ -6,6 +6,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.2.0] - 2024-09-14
### Added
- add cache get
- send out wait
- add cache
- add settings config
- add github fetch prs refactoring
- gitea able to pull repositories
- add config
### Docs
- add readme
### Fixed
- don't have to use user for basic auth
### Other
- removed unused code
- move projects list into separate file
- separate files
- move config out
- remove unused libraries
## [0.1.0] - 2024-09-12 ## [0.1.0] - 2024-09-12
### Added ### Added

View File

@ -3,7 +3,7 @@ members = ["crates/*"]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
version = "0.1.0" version = "0.2.0"
[workspace.dependencies] [workspace.dependencies]
gitnow = { path = "crates/gitnow" } gitnow = { path = "crates/gitnow" }

View File

@ -52,7 +52,37 @@ impl Cache {
return Ok(None); return Ok(None);
} }
let file = tokio::fs::read(location).await?; if let Some(cache_duration) = self.app.config.settings.cache.duration.get_duration() {
let metadata = tokio::fs::metadata(&location).await?;
if let Ok(file_modified_last) = metadata
.modified()
.context("failed to get modified date")
.inspect_err(|e| {
tracing::warn!(
"could not get valid metadata from file, cache will be reused: {}",
e
);
})
.and_then(|m| {
m.elapsed()
.context("failed to get elapsed from file")
.inspect_err(|e| tracing::warn!("failed to get elapsed from system: {}", e))
})
{
tracing::trace!(
cache = file_modified_last.as_secs(),
expiry = cache_duration.as_secs(),
"checking if cache is valid"
);
if file_modified_last > cache_duration {
tracing::debug!("cache has expired");
return Ok(None);
}
}
}
let file = tokio::fs::read(&location).await?;
if file.is_empty() { if file.is_empty() {
tracing::debug!("cache file appears to be empty"); tracing::debug!("cache file appears to be empty");
return Ok(None); return Ok(None);
@ -87,7 +117,7 @@ pub trait CacheConfig {
impl CacheConfig for Config { impl CacheConfig for Config {
fn get_cache_location(&self) -> anyhow::Result<PathBuf> { fn get_cache_location(&self) -> anyhow::Result<PathBuf> {
Ok(self.settings.cache.location.clone()) Ok(self.settings.cache.location.clone().into())
} }
fn get_cache_file_location(&self) -> anyhow::Result<PathBuf> { fn get_cache_file_location(&self) -> anyhow::Result<PathBuf> {

View File

@ -27,7 +27,7 @@ impl RootCommand {
}; };
for repo in &repositories { for repo in &repositories {
tracing::info!("repo: {}", repo.to_rel_path().display()); //tracing::info!("repo: {}", repo.to_rel_path().display());
} }
tracing::info!("amount of repos fetched {}", repositories.len()); tracing::info!("amount of repos fetched {}", repositories.len());

View File

@ -18,17 +18,76 @@ pub struct Settings {
pub cache: Cache, pub cache: Cache,
} }
#[derive(Debug, Serialize, Deserialize, PartialEq)] #[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct Cache { pub struct Cache {
pub location: PathBuf, #[serde(default)]
pub location: CacheLocation,
#[serde(default)]
pub duration: CacheDuration,
} }
impl Default for Cache { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CacheLocation(PathBuf);
impl From<PathBuf> for CacheLocation {
fn from(value: PathBuf) -> Self {
Self(value)
}
}
impl From<CacheLocation> for PathBuf {
fn from(value: CacheLocation) -> Self {
value.0
}
}
impl Default for CacheLocation {
fn default() -> Self { fn default() -> Self {
let home = dirs::home_dir().unwrap_or_default(); let home = dirs::home_dir().unwrap_or_default();
Self { Self(home.join(".cache/gitnow"))
location: home.join(".cache/gitnow"), }
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum CacheDuration {
Enabled(bool),
Precise {
#[serde(default)]
days: u64,
#[serde(default)]
hours: u64,
#[serde(default)]
minutes: u64,
},
}
impl CacheDuration {
pub fn get_duration(&self) -> Option<std::time::Duration> {
match self {
CacheDuration::Enabled(true) => CacheDuration::default().get_duration(),
CacheDuration::Enabled(false) => None,
CacheDuration::Precise {
days,
hours,
minutes,
} => Some(
std::time::Duration::from_days(*days)
+ std::time::Duration::from_hours(*hours)
+ std::time::Duration::from_mins(*minutes),
),
}
}
}
impl Default for CacheDuration {
fn default() -> Self {
Self::Precise {
days: 1,
hours: 0,
minutes: 0,
} }
} }
} }
@ -174,6 +233,7 @@ mod test {
let content = r#" let content = r#"
[settings.cache] [settings.cache]
location = ".cache/gitnow" location = ".cache/gitnow"
duration = { days = 2 }
[[providers.github]] [[providers.github]]
current_user = "kjuulh" current_user = "kjuulh"
@ -250,7 +310,12 @@ mod test {
}, },
settings: Settings { settings: Settings {
cache: Cache { cache: Cache {
location: PathBuf::from(".cache/gitnow/") location: PathBuf::from(".cache/gitnow").into(),
duration: CacheDuration::Precise {
days: 2,
hours: 0,
minutes: 0
}
} }
} }
}, },

View File

@ -120,7 +120,6 @@ impl GiteaProvider {
.collect()) .collect())
} }
#[tracing::instrument(skip(self))]
pub async fn list_repositories_for_user_with_page( pub async fn list_repositories_for_user_with_page(
&self, &self,
user: &str, user: &str,
@ -135,7 +134,6 @@ impl GiteaProvider {
Ok(repos) Ok(repos)
} }
#[tracing::instrument]
pub async fn list_repositories_for_organisation( pub async fn list_repositories_for_organisation(
&self, &self,
organisation: &str, organisation: &str,
@ -181,7 +179,6 @@ impl GiteaProvider {
.collect()) .collect())
} }
#[tracing::instrument(skip(self))]
pub async fn list_repositories_for_organisation_with_page( pub async fn list_repositories_for_organisation_with_page(
&self, &self,
organisation: &str, organisation: &str,

View File

@ -1,3 +1,5 @@
#![feature(duration_constructors)]
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::Context; use anyhow::Context;