Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/2873.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a warning when `description` exceeds 80 characters, prompting users to use `long_description` for longer text. Long descriptions can cause icon corruption in MSI installers.
16 changes: 16 additions & 0 deletions src/briefcase/commands/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,22 @@ def parse_config(self, filename, overrides):
msg=f"Configuration for '{app_name}'",
)

# Warn if the app description is longer than 80 characters.
# Long descriptions can cause MSI shortcut icon corruption
# (the description field is limited to 256 chars in Windows
# shortcuts, and the description length overflows into the
# icon path prefix). Users should use the long_description
# field for longer text.
if len(self.apps[app_name].description) > 80:
self.console.warning(
f"The description for '{app_name}' is "
f"{len(self.apps[app_name].description)} characters. "
"Briefcase descriptions should be no more than 80 "
"characters. Long descriptions may cause icon display "
"issues on some platforms (e.g., MSI installers). "
"Use the `long_description` field for longer text."
)

except OSError as e:
raise BriefcaseConfigError(
f"""\
Expand Down
60 changes: 60 additions & 0 deletions tests/commands/base/test_parse_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

from briefcase.exceptions import BriefcaseConfigError

from unittest.mock import MagicMock

import pytest
from packaging.version import Version

from briefcase.exceptions import BriefcaseConfigError

from ...utils import create_file


Expand Down Expand Up @@ -223,3 +230,56 @@ def test_parse_config_with_invalid_override(base_command):
"version": "not-a-version-number",
},
)


def test_short_description_no_warning(base_command):
"""A config with a short description (<=80 chars) does not trigger a warning."""
filename = base_command.base_path / "pyproject.toml"
create_file(
filename,
"""
[tool.briefcase]
project_name = "Sample project"
version = "1.2.3"
description = "A sample app"
bundle = "org.beeware"
license = "MIT"

[tool.briefcase.app.my-app]
sources = ['src/my_app']
""",
)

base_command.console.warning = MagicMock()
base_command.parse_config(filename, {})

base_command.console.warning.assert_not_called()


def test_long_description_warning(base_command):
"""A config with a long description (>80 chars) triggers a warning."""
long_desc = "x" * 81
filename = base_command.base_path / "pyproject.toml"
create_file(
filename,
f"""
[tool.briefcase]
project_name = "Sample project"
version = "1.2.3"
bundle = "org.beeware"
license = "MIT"

[tool.briefcase.app.my-app]
description = "{long_desc}"
sources = ['src/my_app']
""",
)

base_command.console.warning = MagicMock()
base_command.parse_config(filename, {})

base_command.console.warning.assert_called_once()
warning_msg = base_command.console.warning.call_args[0][0]
assert "my-app" in warning_msg
assert "81 characters" in warning_msg
assert "long_description" in warning_msg
Loading