Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tool cache loading erroring on first startup #42

Merged
merged 3 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fixed Rokit erroring on first startup due to some directories not yet being created ([#42])
- Fixed `selene` and other tools not being installable because their releases contain multiple archives / binaries ([#45])

[#42]: https://github.com/rojo-rbx/rokit/pull/42
[#45]: https://github.com/rojo-rbx/rokit/pull/45

## `0.1.7` - July 15th, 2024
Expand Down
3 changes: 3 additions & 0 deletions lib/storage/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use std::env::var;
use std::path::{Path, PathBuf};
use std::sync::Arc;

use tokio::fs::create_dir_all;

use crate::manifests::AuthManifest;
use crate::result::{RokitError, RokitResult};
use crate::sources::ArtifactSource;
Expand Down Expand Up @@ -60,6 +62,7 @@ impl Home {
let path = dirs::home_dir()
.ok_or(RokitError::HomeNotFound)?
.join(".rokit");
create_dir_all(&path).await?;
Self::load_from_path(path).await
}
}
Expand Down
26 changes: 22 additions & 4 deletions lib/storage/tool_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::{
use dashmap::DashSet;
use semver::Version;
use serde::Deserialize;
use tokio::{task::spawn_blocking, time::Instant};
use tokio::{fs::create_dir_all, task::spawn_blocking, time::Instant};
use tracing::{instrument, trace};

use crate::{
Expand Down Expand Up @@ -191,19 +191,37 @@ impl ToolCache {
}

async fn load_impl(path: PathBuf) -> RokitResult<ToolCache> {
// Make sure we have created the directory for the cache file, since
// OpenOptions::create will only create the file and not the directory.
let dir = path
.parent()
.expect("should not be given empty or root path");
create_dir_all(dir).await?;

// NOTE: Using std::fs here and passing a reader to serde_json lets us
// deserialize the cache faster and without storing the file in memory.
let result = spawn_blocking(move || {
use std::{
fs::File,
fs::OpenOptions,
io::{BufReader, Error},
};
let reader = BufReader::new(File::open(path)?);

let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(false)
.open(path)?;
let reader = BufReader::new(file);
let this: ToolCache = serde_json::from_reader(reader)?;

Ok::<_, Error>(this)
});

Ok(result.await?.unwrap_or_default())
let read_result = result
.await
.expect("blocking reader task panicked unexpectedly");
Ok(read_result.unwrap_or_default())
}

async fn save_impl(path: PathBuf, cache: &ToolCache) -> RokitResult<()> {
Expand Down