mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
On first run, automatically download the latest version
This commit is contained in:
parent
2e74101ca4
commit
436a1d78bc
1 changed files with 100 additions and 96 deletions
|
@ -113,7 +113,6 @@ fn run() -> Result<()> {
|
||||||
|
|
||||||
// Create install directory and copy project files in
|
// Create install directory and copy project files in
|
||||||
create_dir_all(&state.uv_install_root)?;
|
create_dir_all(&state.uv_install_root)?;
|
||||||
|
|
||||||
copy_if_newer(&state.dist_pyproject_path, &state.user_pyproject_path)?;
|
copy_if_newer(&state.dist_pyproject_path, &state.user_pyproject_path)?;
|
||||||
copy_if_newer(
|
copy_if_newer(
|
||||||
&state.dist_python_version_path,
|
&state.dist_python_version_path,
|
||||||
|
@ -145,7 +144,12 @@ fn run() -> Result<()> {
|
||||||
|
|
||||||
check_versions(&mut state);
|
check_versions(&mut state);
|
||||||
|
|
||||||
main_menu_loop(&state)?;
|
let first_run = !state.uv_install_root.join(".venv").exists();
|
||||||
|
if first_run {
|
||||||
|
handle_version_install_or_update(&state, MainMenuChoice::Latest)?;
|
||||||
|
} else {
|
||||||
|
main_menu_loop(&state)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Write marker file to indicate we've completed the sync process
|
// Write marker file to indicate we've completed the sync process
|
||||||
write_sync_marker(&state.sync_complete_marker)?;
|
write_sync_marker(&state.sync_complete_marker)?;
|
||||||
|
@ -225,6 +229,98 @@ fn check_versions(state: &mut State) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_version_install_or_update(state: &State, choice: MainMenuChoice) -> Result<()> {
|
||||||
|
update_pyproject_for_version(
|
||||||
|
choice.clone(),
|
||||||
|
state.dist_pyproject_path.clone(),
|
||||||
|
state.user_pyproject_path.clone(),
|
||||||
|
state.dist_python_version_path.clone(),
|
||||||
|
state.user_python_version_path.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Extract current version before syncing (but don't write to file yet)
|
||||||
|
let previous_version_to_save = extract_aqt_version(&state.uv_path, &state.uv_install_root);
|
||||||
|
|
||||||
|
// Remove sync marker before attempting sync
|
||||||
|
let _ = remove_file(&state.sync_complete_marker);
|
||||||
|
|
||||||
|
println!("\x1B[1mUpdating Anki...\x1B[0m\n");
|
||||||
|
|
||||||
|
let python_version_trimmed = if state.user_python_version_path.exists() {
|
||||||
|
let python_version = read_file(&state.user_python_version_path)?;
|
||||||
|
let python_version_str =
|
||||||
|
String::from_utf8(python_version).context("Invalid UTF-8 in .python-version")?;
|
||||||
|
Some(python_version_str.trim().to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// `uv sync` sometimes does not pull in Python automatically
|
||||||
|
// This might be system/platform specific and/or a uv bug.
|
||||||
|
let mut command = Command::new(&state.uv_path);
|
||||||
|
command
|
||||||
|
.current_dir(&state.uv_install_root)
|
||||||
|
.env("UV_CACHE_DIR", &state.uv_cache_dir)
|
||||||
|
.env("UV_PYTHON_INSTALL_DIR", &state.uv_python_install_dir)
|
||||||
|
.args(["python", "install", "--managed-python"]);
|
||||||
|
|
||||||
|
// Add python version if .python-version file exists
|
||||||
|
if let Some(version) = &python_version_trimmed {
|
||||||
|
command.args([version]);
|
||||||
|
}
|
||||||
|
|
||||||
|
command.ensure_success().context("Python install failed")?;
|
||||||
|
|
||||||
|
// Sync the venv
|
||||||
|
let mut command = Command::new(&state.uv_path);
|
||||||
|
command
|
||||||
|
.current_dir(&state.uv_install_root)
|
||||||
|
.env("UV_CACHE_DIR", &state.uv_cache_dir)
|
||||||
|
.env("UV_PYTHON_INSTALL_DIR", &state.uv_python_install_dir)
|
||||||
|
.args(["sync", "--upgrade", "--managed-python"]);
|
||||||
|
|
||||||
|
// Add python version if .python-version file exists
|
||||||
|
if let Some(version) = &python_version_trimmed {
|
||||||
|
command.args(["--python", version]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set UV_PRERELEASE=allow if beta mode is enabled
|
||||||
|
if state.prerelease_marker.exists() {
|
||||||
|
command.env("UV_PRERELEASE", "allow");
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.no_cache_marker.exists() {
|
||||||
|
command.env("UV_NO_CACHE", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
match command.ensure_success() {
|
||||||
|
Ok(_) => {
|
||||||
|
// Sync succeeded
|
||||||
|
if matches!(&choice, MainMenuChoice::Version(VersionKind::PyOxidizer(_))) {
|
||||||
|
inject_helper_addon(&state.uv_install_root)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that sync succeeded, save the previous version
|
||||||
|
if let Some(current_version) = previous_version_to_save {
|
||||||
|
let previous_version_path = state.uv_install_root.join("previous-version");
|
||||||
|
if let Err(e) = write_file(&previous_version_path, ¤t_version) {
|
||||||
|
println!("Warning: Could not save previous version: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
// If sync fails due to things like a missing wheel on pypi,
|
||||||
|
// we need to remove the lockfile or uv will cache the bad result.
|
||||||
|
let _ = remove_file(&state.uv_lock_path);
|
||||||
|
println!("Install failed: {e:#}");
|
||||||
|
println!();
|
||||||
|
Err(e.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main_menu_loop(state: &State) -> Result<()> {
|
fn main_menu_loop(state: &State) -> Result<()> {
|
||||||
loop {
|
loop {
|
||||||
let menu_choice = get_main_menu_choice(state)?;
|
let menu_choice = get_main_menu_choice(state)?;
|
||||||
|
@ -270,102 +366,10 @@ fn main_menu_loop(state: &State) -> Result<()> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
choice @ (MainMenuChoice::Latest | MainMenuChoice::Version(_)) => {
|
choice @ (MainMenuChoice::Latest | MainMenuChoice::Version(_)) => {
|
||||||
// For other choices, update project files and sync
|
if handle_version_install_or_update(state, choice.clone()).is_err() {
|
||||||
update_pyproject_for_version(
|
|
||||||
choice.clone(),
|
|
||||||
state.dist_pyproject_path.clone(),
|
|
||||||
state.user_pyproject_path.clone(),
|
|
||||||
state.dist_python_version_path.clone(),
|
|
||||||
state.user_python_version_path.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Extract current version before syncing (but don't write to file yet)
|
|
||||||
let previous_version_to_save =
|
|
||||||
extract_aqt_version(&state.uv_path, &state.uv_install_root);
|
|
||||||
|
|
||||||
// Remove sync marker before attempting sync
|
|
||||||
let _ = remove_file(&state.sync_complete_marker);
|
|
||||||
|
|
||||||
println!("\x1B[1mUpdating Anki...\x1B[0m\n");
|
|
||||||
|
|
||||||
let python_version_trimmed = if state.user_python_version_path.exists() {
|
|
||||||
let python_version = read_file(&state.user_python_version_path)?;
|
|
||||||
let python_version_str = String::from_utf8(python_version)
|
|
||||||
.context("Invalid UTF-8 in .python-version")?;
|
|
||||||
Some(python_version_str.trim().to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// `uv sync` does not pull in Python automatically, unlike `uv run`.
|
|
||||||
// This might be system/platform specific and/or a uv bug.
|
|
||||||
let mut command = Command::new(&state.uv_path);
|
|
||||||
command
|
|
||||||
.current_dir(&state.uv_install_root)
|
|
||||||
.env("UV_CACHE_DIR", &state.uv_cache_dir)
|
|
||||||
.env("UV_PYTHON_INSTALL_DIR", &state.uv_python_install_dir)
|
|
||||||
.args(["python", "install", "--managed-python"]);
|
|
||||||
|
|
||||||
// Add python version if .python-version file exists
|
|
||||||
if let Some(version) = &python_version_trimmed {
|
|
||||||
command.args([version]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(e) = command.ensure_success() {
|
|
||||||
println!("Python install failed: {e:#}");
|
|
||||||
println!();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
// Sync the venv
|
|
||||||
let mut command = Command::new(&state.uv_path);
|
|
||||||
command
|
|
||||||
.current_dir(&state.uv_install_root)
|
|
||||||
.env("UV_CACHE_DIR", &state.uv_cache_dir)
|
|
||||||
.env("UV_PYTHON_INSTALL_DIR", &state.uv_python_install_dir)
|
|
||||||
.args(["sync", "--upgrade", "--managed-python"]);
|
|
||||||
|
|
||||||
// Add python version if .python-version file exists
|
|
||||||
if let Some(version) = &python_version_trimmed {
|
|
||||||
command.args(["--python", version]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set UV_PRERELEASE=allow if beta mode is enabled
|
|
||||||
if state.prerelease_marker.exists() {
|
|
||||||
command.env("UV_PRERELEASE", "allow");
|
|
||||||
}
|
|
||||||
|
|
||||||
if state.no_cache_marker.exists() {
|
|
||||||
command.env("UV_NO_CACHE", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
match command.ensure_success() {
|
|
||||||
Ok(_) => {
|
|
||||||
// Sync succeeded
|
|
||||||
if matches!(&choice, MainMenuChoice::Version(VersionKind::PyOxidizer(_))) {
|
|
||||||
inject_helper_addon(&state.uv_install_root)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that sync succeeded, save the previous version
|
|
||||||
if let Some(current_version) = previous_version_to_save {
|
|
||||||
let previous_version_path =
|
|
||||||
state.uv_install_root.join("previous-version");
|
|
||||||
if let Err(e) = write_file(&previous_version_path, ¤t_version) {
|
|
||||||
println!("Warning: Could not save previous version: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
// If sync fails due to things like a missing wheel on pypi,
|
|
||||||
// we need to remove the lockfile or uv will cache the bad result.
|
|
||||||
let _ = remove_file(&state.uv_lock_path);
|
|
||||||
println!("Install failed: {e:#}");
|
|
||||||
println!();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue