From 03acad4c27d4b1111967565dd6d5086e6185905a Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 12 May 2026 10:18:26 -0400 Subject: [PATCH 1/5] Add changes for new menuinst fix --- constructor/briefcase/run_installation.bat | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/constructor/briefcase/run_installation.bat b/constructor/briefcase/run_installation.bat index 1abdc7066..9d718ff3c 100644 --- a/constructor/briefcase/run_installation.bat +++ b/constructor/briefcase/run_installation.bat @@ -45,7 +45,8 @@ rem Set CONDA_QUIET primarily to disable the spinners set CONDA_QUIET={{ 0 if add_debug else 1 }} rem Get the name of the install directory -for %%I in ("%INSTDIR%") do set "APPNAME=%%~nxI" +for %%I in ("%INSTDIR%") do set "DISTRIBUTION_NAME=%%~nxI" +set MENUINST_DISTRIBUTION_NAME=%DISTRIBUTION_NAME% set "LOG=%INSTDIR%\install.log" {%- if script_env_variables %} @@ -128,6 +129,15 @@ if "%ALLUSERS%"=="0" ( if errorlevel 1 ( exit /b %errorlevel% ) ) +rem Persist distribution_name to menuinst.toml before installing packages. +rem This ensures the value is captured even if no packages have shortcuts. +rem Must run before conda install to avoid creating shortcuts twice. +"%CONDA_EXE%" menuinst --install -p "%BASE_PATH%" --root-prefix "%BASE_PATH%" +if errorlevel 1 ( exit /b %errorlevel% ) +if not exist "%BASE_PATH%\Menu\menuinst.toml" ( + {{ error_block('Failed to initialize shortcut configuration', 14) }} +) + {%- if has_pre_install %} rem Run user-supplied pre-install script {%- if has_pre_install_desc %} From 2dd1895540c9524b618eb1c1bf285e0c0c665dec Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 10 Jun 2026 14:05:28 -0400 Subject: [PATCH 2/5] Enable test for MSI; add temporary debug output (to be removed) --- tests/test_examples.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index 9deca5361..dbfe7c967 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1000,25 +1000,31 @@ def test_example_shortcuts(tmp_path, request): _run_installer(input_path, installer, install_dir, request=request, uninstall=False) # check that the shortcuts are created if sys.platform == "win32": - # MSI shortcut verification expected to fail due to menuinst bug - # https://github.com/conda/menuinst/issues/453 + # console_shortcut package uses hardcoded "Anaconda3" in its menu definition, + # but MSI sets MENUINST_DISTRIBUTION_NAME which overrides DISTRIBUTION_NAME if installer.suffix == ".msi": - pytest.xfail("MSI shortcut verification fails due to menuinst#453") + distribution_name = install_dir.name + else: + distribution_name = "Anaconda3" for key in ("ProgramData", "AppData"): start_menu = Path(os.environ[key]) / "Microsoft/Windows/Start Menu/Programs" package_1 = start_menu / "Package 1" - anaconda = start_menu / "Anaconda3 (64-bit)" - if package_1.is_dir() and anaconda.is_dir(): + console_shortcut_dir = start_menu / f"{distribution_name} (64-bit)" + if package_1.is_dir() and console_shortcut_dir.is_dir(): assert (package_1 / "A.lnk").is_file() assert (package_1 / "B.lnk").is_file() # The shortcut created from the 'base' env # should not exist because we filtered it out in the YAML # We do expect one shortcut from 'another_env' - assert not (anaconda / "Anaconda Prompt.lnk").is_file() - assert (anaconda / "Anaconda Prompt (another_env).lnk").is_file() + assert not (console_shortcut_dir / "Anaconda Prompt.lnk").is_file() + assert (console_shortcut_dir / "Anaconda Prompt (another_env).lnk").is_file() break else: - raise AssertionError("No shortcuts found!") + # TODO: Remove debug output after verifying test passes + for key in ("ProgramData", "AppData"): + sm = Path(os.environ[key]) / "Microsoft/Windows/Start Menu/Programs" + print(f"{sm}: {[d.name for d in sm.iterdir() if d.is_dir()]}") + raise AssertionError(f"No shortcuts found! Expected '{distribution_name} (64-bit)'") if installer.suffix == ".msi": _run_uninstaller_msi(installer, install_dir) else: From b2524ae5097d4184f060bd39b710dd7080fde650 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 10 Jun 2026 17:04:41 -0400 Subject: [PATCH 3/5] Update test --- tests/test_examples.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index dbfe7c967..f7628b0c7 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -997,15 +997,20 @@ def test_example_scripts(tmp_path, request): def test_example_shortcuts(tmp_path, request): input_path = _example_path("shortcuts") for installer, install_dir in create_installer(input_path, tmp_path): + # console_shortcut package uses hardcoded "Anaconda3" in its menu definition + distribution_name = "Anaconda3" + if sys.platform == "win32": + # Verify shortcuts don't exist before installation (not leftover from previous run (since EXE/MSI run in a loop)) + for key in ("ProgramData", "AppData"): + start_menu = Path(os.environ[key]) / "Microsoft/Windows/Start Menu/Programs" + package_1 = start_menu / "Package 1" + if package_1.is_dir(): + assert not (package_1 / "A.lnk").is_file(), "A.lnk exists before installation" + assert not (package_1 / "B.lnk").is_file(), "B.lnk exists before installation" + _run_installer(input_path, installer, install_dir, request=request, uninstall=False) # check that the shortcuts are created if sys.platform == "win32": - # console_shortcut package uses hardcoded "Anaconda3" in its menu definition, - # but MSI sets MENUINST_DISTRIBUTION_NAME which overrides DISTRIBUTION_NAME - if installer.suffix == ".msi": - distribution_name = install_dir.name - else: - distribution_name = "Anaconda3" for key in ("ProgramData", "AppData"): start_menu = Path(os.environ[key]) / "Microsoft/Windows/Start Menu/Programs" package_1 = start_menu / "Package 1" @@ -1020,10 +1025,6 @@ def test_example_shortcuts(tmp_path, request): assert (console_shortcut_dir / "Anaconda Prompt (another_env).lnk").is_file() break else: - # TODO: Remove debug output after verifying test passes - for key in ("ProgramData", "AppData"): - sm = Path(os.environ[key]) / "Microsoft/Windows/Start Menu/Programs" - print(f"{sm}: {[d.name for d in sm.iterdir() if d.is_dir()]}") raise AssertionError(f"No shortcuts found! Expected '{distribution_name} (64-bit)'") if installer.suffix == ".msi": _run_uninstaller_msi(installer, install_dir) From 5a279c55832b7587909cbc882e434bd36dd0a7d8 Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 11 Jun 2026 12:16:01 -0400 Subject: [PATCH 4/5] Remove misleading comment --- constructor/briefcase/run_installation.bat | 1 - 1 file changed, 1 deletion(-) diff --git a/constructor/briefcase/run_installation.bat b/constructor/briefcase/run_installation.bat index 9d718ff3c..d370ffda0 100644 --- a/constructor/briefcase/run_installation.bat +++ b/constructor/briefcase/run_installation.bat @@ -131,7 +131,6 @@ if "%ALLUSERS%"=="0" ( rem Persist distribution_name to menuinst.toml before installing packages. rem This ensures the value is captured even if no packages have shortcuts. -rem Must run before conda install to avoid creating shortcuts twice. "%CONDA_EXE%" menuinst --install -p "%BASE_PATH%" --root-prefix "%BASE_PATH%" if errorlevel 1 ( exit /b %errorlevel% ) if not exist "%BASE_PATH%\Menu\menuinst.toml" ( From 6b6306d95036162512033cde06eaa8dbf8128789 Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 11 Jun 2026 14:47:22 -0400 Subject: [PATCH 5/5] Update comment --- constructor/briefcase/run_installation.bat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/constructor/briefcase/run_installation.bat b/constructor/briefcase/run_installation.bat index d370ffda0..8519fb8ee 100644 --- a/constructor/briefcase/run_installation.bat +++ b/constructor/briefcase/run_installation.bat @@ -131,6 +131,8 @@ if "%ALLUSERS%"=="0" ( rem Persist distribution_name to menuinst.toml before installing packages. rem This ensures the value is captured even if no packages have shortcuts. +rem At this point %BASE_PATH%\Menu has no .json files (packages not installed yet), +rem so menuinst only writes distribution_name - no shortcuts are created here. "%CONDA_EXE%" menuinst --install -p "%BASE_PATH%" --root-prefix "%BASE_PATH%" if errorlevel 1 ( exit /b %errorlevel% ) if not exist "%BASE_PATH%\Menu\menuinst.toml" (