From 5f125273423359d0f782aca2fcb778dad2596ab4 Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 30 Jun 2026 12:40:24 -0400 Subject: [PATCH 1/2] Fix installer option inconsistency between EXE/MSI --- constructor/briefcase.py | 3 ++- examples/scripts/post_install.bat | 22 +++++++++++++--------- examples/scripts/pre_install.bat | 5 +++-- tests/test_briefcase.py | 20 ++++++++++++++++++++ 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/constructor/briefcase.py b/constructor/briefcase.py index 831df3017..aa8891476 100644 --- a/constructor/briefcase.py +++ b/constructor/briefcase.py @@ -367,7 +367,8 @@ def create_install_options_list(info: dict) -> list[dict]: "name": f"{script_type}_install_script", "title": f"{script_type.capitalize()}-install script", "description": script_description, - "default": False, + # Mirror NSIS: default to enabled when the script exists. + "default": bool(script), } ) diff --git a/examples/scripts/post_install.bat b/examples/scripts/post_install.bat index 2c2c57af5..103d8da02 100644 --- a/examples/scripts/post_install.bat +++ b/examples/scripts/post_install.bat @@ -2,19 +2,23 @@ echo Added by post-install script > "%PREFIX%\post_install_sentinel.txt" if not "%INSTALLER_NAME%" == "Scripts" exit 1 if not "%INSTALLER_VER%" == "1.0.0" exit 1 if not "%INSTALLER_PLAT%" == "win-64" exit 1 -if not "%INSTALLER_TYPE%" == "EXE" exit 1 -if not "%INSTALLER_UNATTENDED%" == "1" exit 1 +if not "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_TYPE%" == "MSI" exit 1 +rem INSTALLER_UNATTENDED is only set by EXE installers. +if "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_UNATTENDED%" == "1" exit 1 if "%PREFIX%" == "" exit 1 if not "%CUSTOM_VARIABLE_1%" == "FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1 if not "%CUSTOM_VARIABLE_2%" == "$ECOND-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1 if not exist "%PREFIX%\pre_install_sentinel.txt" exit 1 -if not exist "%INSTALLER_PATH%" ( - echo ERROR: "INSTALLER_PATH=%INSTALLER_PATH%" points to a file that does not exist! - exit 1 -) +rem INSTALLER_PATH and INSTALLER_PLUGINSDIR are only set by EXE installers. +if "%INSTALLER_TYPE%" == "EXE" ( + if not exist "%INSTALLER_PATH%" ( + echo ERROR: "INSTALLER_PATH=%INSTALLER_PATH%" points to a file that does not exist! + exit 1 + ) -if not exist "%INSTALLER_PLUGINSDIR%" ( - echo ERROR: "INSTALLER_PLUGINSDIR=%INSTALLER_PLUGINSDIR%" points to a directory that does not exist! - exit 1 + if not exist "%INSTALLER_PLUGINSDIR%" ( + echo ERROR: "INSTALLER_PLUGINSDIR=%INSTALLER_PLUGINSDIR%" points to a directory that does not exist! + exit 1 + ) ) diff --git a/examples/scripts/pre_install.bat b/examples/scripts/pre_install.bat index 22a529daa..47fa3c9b8 100644 --- a/examples/scripts/pre_install.bat +++ b/examples/scripts/pre_install.bat @@ -1,8 +1,9 @@ if not "%INSTALLER_NAME%" == "Scripts" exit 1 if not "%INSTALLER_VER%" == "1.0.0" exit 1 if not "%INSTALLER_PLAT%" == "win-64" exit 1 -if not "%INSTALLER_TYPE%" == "EXE" exit 1 -if not "%INSTALLER_UNATTENDED%" == "1" exit 1 +if not "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_TYPE%" == "MSI" exit 1 +rem INSTALLER_UNATTENDED is only set by EXE installers. +if "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_UNATTENDED%" == "1" exit 1 if "%PREFIX%" == "" exit 1 if not "%CUSTOM_VARIABLE_1%" == "FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1 if not "%CUSTOM_VARIABLE_2%" == "$ECOND-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1 diff --git a/tests/test_briefcase.py b/tests/test_briefcase.py index 57497a94b..28c818845 100644 --- a/tests/test_briefcase.py +++ b/tests/test_briefcase.py @@ -14,6 +14,7 @@ _get_python_info, _get_script_env_variables, _setup_envs_commands, + create_install_options_list, create_uninstall_options_list, get_bundle_app_name, get_license, @@ -645,6 +646,25 @@ def test_create_uninstall_options_list(): assert "remove_config_files" in option_names +@pytest.mark.parametrize("script_type", ["pre", "post"]) +def test_install_options_script_default_enabled(tmp_path, script_type): + """Pre/post-install script options default to enabled when a script exists. + + This mirrors the NSIS installer, which checks the box by default when the + script is present (see nsis/main.nsi.tmpl). + """ + script = tmp_path / f"{script_type}_install.bat" + script.write_text("@echo script") + + info = mock_info.copy() + info[f"{script_type}_install"] = str(script) + info[f"{script_type}_install_desc"] = "Custom script description" + + options = create_install_options_list(info) + option = next(opt for opt in options if opt["name"] == f"{script_type}_install_script") + assert option["default"] is True + + def test_render_templates_with_virtual_specs(): """Test that virtual_specs check block is rendered when specs are provided.""" info = mock_info.copy() From ffc3dbc968960510e59dbf0134751a820b197b79 Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 30 Jun 2026 12:46:50 -0400 Subject: [PATCH 2/2] Update comment --- examples/scripts/post_install.bat | 2 +- examples/scripts/pre_install.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/scripts/post_install.bat b/examples/scripts/post_install.bat index 103d8da02..307f2beec 100644 --- a/examples/scripts/post_install.bat +++ b/examples/scripts/post_install.bat @@ -3,7 +3,7 @@ if not "%INSTALLER_NAME%" == "Scripts" exit 1 if not "%INSTALLER_VER%" == "1.0.0" exit 1 if not "%INSTALLER_PLAT%" == "win-64" exit 1 if not "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_TYPE%" == "MSI" exit 1 -rem INSTALLER_UNATTENDED is only set by EXE installers. +rem INSTALLER_UNATTENDED is not yet set by MSI installers (see conda/constructor#1276). if "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_UNATTENDED%" == "1" exit 1 if "%PREFIX%" == "" exit 1 if not "%CUSTOM_VARIABLE_1%" == "FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1 diff --git a/examples/scripts/pre_install.bat b/examples/scripts/pre_install.bat index 47fa3c9b8..090aea352 100644 --- a/examples/scripts/pre_install.bat +++ b/examples/scripts/pre_install.bat @@ -2,7 +2,7 @@ if not "%INSTALLER_NAME%" == "Scripts" exit 1 if not "%INSTALLER_VER%" == "1.0.0" exit 1 if not "%INSTALLER_PLAT%" == "win-64" exit 1 if not "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_TYPE%" == "MSI" exit 1 -rem INSTALLER_UNATTENDED is only set by EXE installers. +rem INSTALLER_UNATTENDED is not yet set by MSI installers (see conda/constructor#1276). if "%INSTALLER_TYPE%" == "EXE" if not "%INSTALLER_UNATTENDED%" == "1" exit 1 if "%PREFIX%" == "" exit 1 if not "%CUSTOM_VARIABLE_1%" == "FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1