mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
More launcher fixes
- The pyproject copy change broke the initial run case - Avoid calling 'uv pip show' before venv created, as it causes a pop-up prompting the user to install developer tools on macOS (#4227) - Add a tip to the user about the unwanted install_name_tool pop-up (Also tracked in #4227) - Print 'Checking for updates...' prior to the potentially slow network request
This commit is contained in:
parent
78c6db2023
commit
7172b2d266
1 changed files with 39 additions and 22 deletions
|
@ -49,6 +49,7 @@ struct State {
|
||||||
pyproject_modified_by_user: bool,
|
pyproject_modified_by_user: bool,
|
||||||
previous_version: Option<String>,
|
previous_version: Option<String>,
|
||||||
resources_dir: std::path::PathBuf,
|
resources_dir: std::path::PathBuf,
|
||||||
|
venv_folder: std::path::PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -110,6 +111,7 @@ fn run() -> Result<()> {
|
||||||
pyproject_modified_by_user: false, // calculated later
|
pyproject_modified_by_user: false, // calculated later
|
||||||
previous_version: None,
|
previous_version: None,
|
||||||
resources_dir,
|
resources_dir,
|
||||||
|
venv_folder: uv_install_root.join(".venv"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for uninstall request from Windows uninstaller
|
// Check for uninstall request from Windows uninstaller
|
||||||
|
@ -122,7 +124,8 @@ fn run() -> Result<()> {
|
||||||
// Create install directory
|
// Create install directory
|
||||||
create_dir_all(&state.uv_install_root)?;
|
create_dir_all(&state.uv_install_root)?;
|
||||||
|
|
||||||
let launcher_requested = state.launcher_trigger_file.exists();
|
let launcher_requested =
|
||||||
|
state.launcher_trigger_file.exists() || !state.user_pyproject_path.exists();
|
||||||
|
|
||||||
// Calculate whether user has custom edits that need syncing
|
// Calculate whether user has custom edits that need syncing
|
||||||
let pyproject_time = file_timestamp_secs(&state.user_pyproject_path);
|
let pyproject_time = file_timestamp_secs(&state.user_pyproject_path);
|
||||||
|
@ -152,7 +155,7 @@ fn run() -> Result<()> {
|
||||||
|
|
||||||
check_versions(&mut state);
|
check_versions(&mut state);
|
||||||
|
|
||||||
let first_run = !state.uv_install_root.join(".venv").exists();
|
let first_run = !state.venv_folder.exists();
|
||||||
if first_run {
|
if first_run {
|
||||||
handle_version_install_or_update(&state, MainMenuChoice::Latest)?;
|
handle_version_install_or_update(&state, MainMenuChoice::Latest)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,7 +163,7 @@ fn run() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)?;
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
|
@ -186,13 +189,15 @@ fn run() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_aqt_version(
|
fn extract_aqt_version(state: &State) -> Option<String> {
|
||||||
uv_path: &std::path::Path,
|
// Check if .venv exists first
|
||||||
uv_install_root: &std::path::Path,
|
if !state.venv_folder.exists() {
|
||||||
) -> Option<String> {
|
return None;
|
||||||
let output = Command::new(uv_path)
|
}
|
||||||
.current_dir(uv_install_root)
|
|
||||||
.env("VIRTUAL_ENV", uv_install_root.join(".venv"))
|
let output = Command::new(&state.uv_path)
|
||||||
|
.current_dir(&state.uv_install_root)
|
||||||
|
.env("VIRTUAL_ENV", &state.venv_folder)
|
||||||
.args(["pip", "show", "aqt"])
|
.args(["pip", "show", "aqt"])
|
||||||
.output()
|
.output()
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
@ -217,7 +222,7 @@ fn check_versions(state: &mut State) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine current version by invoking uv pip show aqt
|
// Determine current version by invoking uv pip show aqt
|
||||||
match extract_aqt_version(&state.uv_path, &state.uv_install_root) {
|
match extract_aqt_version(state) {
|
||||||
Some(version) => {
|
Some(version) => {
|
||||||
state.current_version = Some(version);
|
state.current_version = Some(version);
|
||||||
}
|
}
|
||||||
|
@ -242,12 +247,12 @@ fn handle_version_install_or_update(state: &State, choice: MainMenuChoice) -> Re
|
||||||
update_pyproject_for_version(choice.clone(), state)?;
|
update_pyproject_for_version(choice.clone(), state)?;
|
||||||
|
|
||||||
// Extract current version before syncing (but don't write to file yet)
|
// 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);
|
let previous_version_to_save = extract_aqt_version(state);
|
||||||
|
|
||||||
// Remove sync marker before attempting sync
|
// Remove sync marker before attempting sync
|
||||||
let _ = remove_file(&state.sync_complete_marker);
|
let _ = remove_file(&state.sync_complete_marker);
|
||||||
|
|
||||||
println!("\x1B[1mUpdating Anki...\x1B[0m\n");
|
println!("Updating Anki...\n");
|
||||||
|
|
||||||
let python_version_trimmed = if state.user_python_version_path.exists() {
|
let python_version_trimmed = if state.user_python_version_path.exists() {
|
||||||
let python_version = read_file(&state.user_python_version_path)?;
|
let python_version = read_file(&state.user_python_version_path)?;
|
||||||
|
@ -258,6 +263,11 @@ fn handle_version_install_or_update(state: &State, choice: MainMenuChoice) -> Re
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let have_venv = state.venv_folder.exists();
|
||||||
|
if cfg!(target_os = "macos") && !have_developer_tools() && !have_venv {
|
||||||
|
println!("If you see a pop-up about 'install_name_tool', you can cancel it, and ignore the warning below.\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare to sync the venv
|
// Prepare to 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);
|
command.current_dir(&state.uv_install_root);
|
||||||
|
@ -305,7 +315,7 @@ fn handle_version_install_or_update(state: &State, choice: MainMenuChoice) -> Re
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// Sync succeeded
|
// Sync succeeded
|
||||||
if matches!(&choice, MainMenuChoice::Version(VersionKind::PyOxidizer(_))) {
|
if matches!(&choice, MainMenuChoice::Version(VersionKind::PyOxidizer(_))) {
|
||||||
inject_helper_addon(&state.uv_install_root)?;
|
inject_helper_addon()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that sync succeeded, save the previous version
|
// Now that sync succeeded, save the previous version
|
||||||
|
@ -384,12 +394,12 @@ fn main_menu_loop(state: &State) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_sync_marker(sync_complete_marker: &std::path::Path) -> Result<()> {
|
fn write_sync_marker(state: &State) -> Result<()> {
|
||||||
let timestamp = SystemTime::now()
|
let timestamp = SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.context("Failed to get system time")?
|
.context("Failed to get system time")?
|
||||||
.as_secs();
|
.as_secs();
|
||||||
write_file(sync_complete_marker, timestamp.to_string())?;
|
write_file(&state.sync_complete_marker, timestamp.to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,8 +493,6 @@ fn get_main_menu_choice(state: &State) -> Result<MainMenuChoice> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_version_kind(state: &State) -> Result<Option<VersionKind>> {
|
fn get_version_kind(state: &State) -> Result<Option<VersionKind>> {
|
||||||
println!("Please wait...");
|
|
||||||
|
|
||||||
let releases = get_releases(state)?;
|
let releases = get_releases(state)?;
|
||||||
let releases_str = releases
|
let releases_str = releases
|
||||||
.latest
|
.latest
|
||||||
|
@ -668,6 +676,7 @@ fn fetch_versions(state: &State) -> Result<Vec<String>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_releases(state: &State) -> Result<Releases> {
|
fn get_releases(state: &State) -> Result<Releases> {
|
||||||
|
println!("Checking for updates...");
|
||||||
let include_prereleases = state.prerelease_marker.exists();
|
let include_prereleases = state.prerelease_marker.exists();
|
||||||
let all_versions = fetch_versions(state)?;
|
let all_versions = fetch_versions(state)?;
|
||||||
let all_versions = filter_and_normalize_versions(all_versions, include_prereleases);
|
let all_versions = filter_and_normalize_versions(all_versions, include_prereleases);
|
||||||
|
@ -794,7 +803,7 @@ fn parse_version_kind(version: &str) -> Option<VersionKind> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_helper_addon(_uv_install_root: &std::path::Path) -> Result<()> {
|
fn inject_helper_addon() -> Result<()> {
|
||||||
let addons21_path = get_anki_addons21_path()?;
|
let addons21_path = get_anki_addons21_path()?;
|
||||||
|
|
||||||
if !addons21_path.exists() {
|
if !addons21_path.exists() {
|
||||||
|
@ -896,16 +905,24 @@ fn handle_uninstall(state: &State) -> Result<bool> {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn have_developer_tools() -> bool {
|
||||||
|
Command::new("xcode-select")
|
||||||
|
.args(["-p"])
|
||||||
|
.output()
|
||||||
|
.map(|output| output.status.success())
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
fn build_python_command(state: &State, args: &[String]) -> Result<Command> {
|
fn build_python_command(state: &State, args: &[String]) -> Result<Command> {
|
||||||
let python_exe = if cfg!(target_os = "windows") {
|
let python_exe = if cfg!(target_os = "windows") {
|
||||||
let show_console = std::env::var("ANKI_CONSOLE").is_ok();
|
let show_console = std::env::var("ANKI_CONSOLE").is_ok();
|
||||||
if show_console {
|
if show_console {
|
||||||
state.uv_install_root.join(".venv/Scripts/python.exe")
|
state.venv_folder.join("Scripts/python.exe")
|
||||||
} else {
|
} else {
|
||||||
state.uv_install_root.join(".venv/Scripts/pythonw.exe")
|
state.venv_folder.join("Scripts/pythonw.exe")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state.uv_install_root.join(".venv/bin/python")
|
state.venv_folder.join("bin/python")
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cmd = Command::new(&python_exe);
|
let mut cmd = Command::new(&python_exe);
|
||||||
|
|
Loading…
Reference in a new issue