Store uv cache inside AnkiProgramFiles, and allow disabling

This commit is contained in:
Damien Elmes 2025-06-29 11:42:21 +07:00
parent aa8dfe1cf4
commit b872852afe

View file

@ -35,6 +35,8 @@ struct State {
has_existing_install: bool, has_existing_install: bool,
prerelease_marker: std::path::PathBuf, prerelease_marker: std::path::PathBuf,
uv_install_root: std::path::PathBuf, uv_install_root: std::path::PathBuf,
uv_cache_dir: std::path::PathBuf,
no_cache_marker: std::path::PathBuf,
uv_path: std::path::PathBuf, uv_path: std::path::PathBuf,
user_pyproject_path: std::path::PathBuf, user_pyproject_path: std::path::PathBuf,
user_python_version_path: std::path::PathBuf, user_python_version_path: std::path::PathBuf,
@ -56,6 +58,7 @@ pub enum MainMenuChoice {
KeepExisting, KeepExisting,
Version(VersionKind), Version(VersionKind),
ToggleBetas, ToggleBetas,
ToggleCache,
Quit, Quit,
} }
@ -81,6 +84,8 @@ fn run() -> Result<()> {
has_existing_install: uv_install_root.join(".sync_complete").exists(), has_existing_install: uv_install_root.join(".sync_complete").exists(),
prerelease_marker: uv_install_root.join("prerelease"), prerelease_marker: uv_install_root.join("prerelease"),
uv_install_root: uv_install_root.clone(), uv_install_root: uv_install_root.clone(),
uv_cache_dir: uv_install_root.join("cache"),
no_cache_marker: uv_install_root.join("nocache"),
uv_path: exe_dir.join(get_uv_binary_name()), uv_path: exe_dir.join(get_uv_binary_name()),
user_pyproject_path: uv_install_root.join("pyproject.toml"), user_pyproject_path: uv_install_root.join("pyproject.toml"),
user_python_version_path: uv_install_root.join(".python-version"), user_python_version_path: uv_install_root.join(".python-version"),
@ -155,8 +160,11 @@ fn run() -> Result<()> {
fn main_menu_loop(state: &State) -> Result<()> { fn main_menu_loop(state: &State) -> Result<()> {
loop { loop {
let menu_choice = let menu_choice = get_main_menu_choice(
get_main_menu_choice(state.has_existing_install, &state.prerelease_marker); state.has_existing_install,
&state.prerelease_marker,
&state.no_cache_marker,
);
match menu_choice { match menu_choice {
MainMenuChoice::Quit => std::process::exit(0), MainMenuChoice::Quit => std::process::exit(0),
@ -176,6 +184,22 @@ fn main_menu_loop(state: &State) -> Result<()> {
println!(); println!();
continue; continue;
} }
MainMenuChoice::ToggleCache => {
// Toggle cache disable file
if state.no_cache_marker.exists() {
let _ = remove_file(&state.no_cache_marker);
println!("Download caching enabled.");
} else {
write_file(&state.no_cache_marker, "")?;
// Delete the cache directory and everything in it
if state.uv_cache_dir.exists() {
let _ = anki_io::remove_dir_all(&state.uv_cache_dir);
}
println!("Download caching disabled and cache cleared.");
}
println!();
continue;
}
choice @ (MainMenuChoice::Latest | MainMenuChoice::Version(_)) => { choice @ (MainMenuChoice::Latest | MainMenuChoice::Version(_)) => {
// For other choices, update project files and sync // For other choices, update project files and sync
update_pyproject_for_version( update_pyproject_for_version(
@ -191,11 +215,10 @@ fn main_menu_loop(state: &State) -> Result<()> {
// Sync the venv // Sync the venv
let mut command = Command::new(&state.uv_path); let mut command = Command::new(&state.uv_path);
command.current_dir(&state.uv_install_root).args([ command
"sync", .current_dir(&state.uv_install_root)
"--upgrade", .env("UV_CACHE_DIR", &state.uv_cache_dir)
"--managed-python", .args(["sync", "--upgrade", "--managed-python"]);
]);
// Add python version if .python-version file exists // Add python version if .python-version file exists
if state.user_python_version_path.exists() { if state.user_python_version_path.exists() {
@ -211,6 +234,10 @@ fn main_menu_loop(state: &State) -> Result<()> {
command.env("UV_PRERELEASE", "allow"); command.env("UV_PRERELEASE", "allow");
} }
if state.no_cache_marker.exists() {
command.env("UV_NO_CACHE", "1");
}
println!("\x1B[1mUpdating Anki...\x1B[0m\n"); println!("\x1B[1mUpdating Anki...\x1B[0m\n");
match command.ensure_success() { match command.ensure_success() {
@ -248,6 +275,7 @@ fn write_sync_marker(sync_complete_marker: &std::path::Path) -> Result<()> {
fn get_main_menu_choice( fn get_main_menu_choice(
has_existing_install: bool, has_existing_install: bool,
prerelease_marker: &std::path::Path, prerelease_marker: &std::path::Path,
no_cache_marker: &std::path::Path,
) -> MainMenuChoice { ) -> MainMenuChoice {
loop { loop {
println!("1) Latest Anki (just press enter)"); println!("1) Latest Anki (just press enter)");
@ -262,7 +290,12 @@ fn get_main_menu_choice(
"4) Allow betas: {}", "4) Allow betas: {}",
if betas_enabled { "on" } else { "off" } if betas_enabled { "on" } else { "off" }
); );
println!("5) Quit"); let cache_enabled = !no_cache_marker.exists();
println!(
"5) Cache downloads: {}",
if cache_enabled { "on" } else { "off" }
);
println!("6) Quit");
print!("> "); print!("> ");
let _ = stdout().flush(); let _ = stdout().flush();
@ -284,7 +317,8 @@ fn get_main_menu_choice(
} }
} }
"4" => MainMenuChoice::ToggleBetas, "4" => MainMenuChoice::ToggleBetas,
"5" => MainMenuChoice::Quit, "5" => MainMenuChoice::ToggleCache,
"6" => MainMenuChoice::Quit,
_ => { _ => {
println!("Invalid input. Please try again."); println!("Invalid input. Please try again.");
continue; continue;
@ -339,8 +373,10 @@ fn update_pyproject_for_version(
// Do nothing - keep existing pyproject.toml and .python-version // Do nothing - keep existing pyproject.toml and .python-version
} }
MainMenuChoice::ToggleBetas => { MainMenuChoice::ToggleBetas => {
// This should not be reached as ToggleBetas is handled in the loop unreachable!();
unreachable!("ToggleBetas should be handled in the main loop"); }
MainMenuChoice::ToggleCache => {
unreachable!();
} }
MainMenuChoice::Version(version_kind) => { MainMenuChoice::Version(version_kind) => {
let content = read_file(&dist_pyproject_path)?; let content = read_file(&dist_pyproject_path)?;