Repository: relekang/python-semantic-release (python)

Issue:
Plain Text Changelog Section Description Setting for Emoji Parser
## Description

As a developer I really like controlling semantic versioning using emojis, however the resulting changelog is not very useful for people that are not actively involved with the project as the section descriptions are just emojis. The user would have to know that the project uses an emoji parser and what each emoji represents in the semantic versioning scheme.

## Use cases

A better experience for people reading the changelog would be to have the sections just be in plain text describing the change as patch, minor or major.

## Possible implementation

The optimal solution would be to have a setting to control whether the emoji parser should use plain text or emojis for the section descriptions. (Maybe even a combination of both)


Pull request description:
feat: add setting for enforcing ascii changlelog sections
Resolves #498

Add the 'enforce_ascii_changelog_sections' setting flag for enforcing that changelog section headings will always be regular ASCII when using the Emoji parser.

Patch:
diff --git a/docs/configuration.rst b/docs/configuration.rst
index bf4253c..b4b4a86 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -233,6 +233,17 @@ create patch releases.
 
 Default: `:ambulance:, :lock:, :bug:, :zap:, :goal_net:, :alien:, :wheelchair:, :speech_balloon:, :mag:, :apple:, :penguin:, :checkered_flag:, :robot:, :green_apple:`
 
+.. _config-use_textual_changelog_sections:
+
+``use_textual_changelog_sections``
+------------------------------------
+
+If this is set to `true` with using the :py:func:`semantic_release.history.emoji_parser`,
+semantic-release will use human readable ASCII section headings in the changelog instead of
+the configured emoji.
+
+Default: `false`
+
 .. _config-scipy-parser:
 
 ``scipy_parser``
diff --git a/semantic_release/defaults.cfg b/semantic_release/defaults.cfg
index d49e598..9e1e2aa 100644
--- a/semantic_release/defaults.cfg
+++ b/semantic_release/defaults.cfg
@@ -11,6 +11,7 @@ changelog_file=CHANGELOG.md
 changelog_placeholder=<!--next-version-placeholder-->
 changelog_scope=true
 changelog_sections=feature,fix,breaking,documentation,performance,:boom:,:sparkles:,:children_crossing:,:lipstick:,:iphone:,:egg:,:chart_with_upwards_trend:,:ambulance:,:lock:,:bug:,:zap:,:goal_net:,:alien:,:wheelchair:,:speech_balloon:,:mag:,:apple:,:penguin:,:checkered_flag:,:robot:,:green_apple:,Other
+use_textual_changelog_sections=false
 check_build_status=false
 include_additional_files=
 commit_message=Automatically generated by python-semantic-release
diff --git a/semantic_release/history/parser_emoji.py b/semantic_release/history/parser_emoji.py
index 6f244b4..4b51430 100644
--- a/semantic_release/history/parser_emoji.py
+++ b/semantic_release/history/parser_emoji.py
@@ -39,6 +39,7 @@ def parse_commit_message(
     patch = config.get("patch_emoji").split(",")
     all_emojis = major + minor + patch
 
+    use_textual_changelog_sections = config.get("use_textual_changelog_sections")
     # Loop over emojis from most important to least important
     # Therefore, we find the highest level emoji first
     primary_emoji = "Other"
@@ -52,9 +53,12 @@ def parse_commit_message(
     level_bump = 0
     if primary_emoji in major:
         level_bump = 3
+        primary_emoji = "breaking" if use_textual_changelog_sections else primary_emoji
     elif primary_emoji in minor:
+        primary_emoji = "feature" if use_textual_changelog_sections else primary_emoji
         level_bump = 2
     elif primary_emoji in patch:
+        primary_emoji = "fix" if use_textual_changelog_sections else primary_emoji
         level_bump = 1
 
     # All emojis will remain part of the returned description
diff --git a/semantic_release/settings.py b/semantic_release/settings.py
index 7f57114..726e660 100644
--- a/semantic_release/settings.py
+++ b/semantic_release/settings.py
@@ -39,6 +39,7 @@ def _config_from_ini(paths):
     flags = {
         "changelog_capitalize",
         "changelog_scope",
+        "use_textual_changelog_sections",
         "check_build_status",
         "commit_version_number",
         "ignore_token_for_push",


Test patch:
diff --git a/tests/parsers/test_emoji.py b/tests/parsers/test_emoji.py
index 80b1696..83cfbe6 100644
--- a/tests/parsers/test_emoji.py
+++ b/tests/parsers/test_emoji.py
@@ -1,5 +1,10 @@
+import mock
+import pytest
+
 from semantic_release.history import emoji_parser
 
+from .. import wrapped_config_get
+
 
 def test_major():
     commit = (
@@ -65,3 +70,35 @@ def test_emoji_in_description():
         ":boom: should not be detected",
     ]
     assert parsed_commit[4] == []
+
+
+@mock.patch(
+    "semantic_release.history.parser_emoji.config.get",
+    wrapped_config_get(use_textual_changelog_sections=True),
+)
+@pytest.mark.parametrize(
+    "level,commit,commit_type",
+    [
+        (
+            3,
+            ":boom: Breaking changes\n\n"
+            "More description\n\n"
+            "Even more description",
+            "breaking",
+        ),
+        (
+            2,
+            ":sparkles: Add a new feature\n\n" "Some description of the feature",
+            "feature",
+        ),
+        (
+            1,
+            ":bug: Fixing a bug\n\n" "The bug is finally gone!",
+            "fix",
+        ),
+    ],
+)
+def test_use_textual_changelog_sections(level, commit, commit_type):
+    parsed_commit = emoji_parser(commit)
+    assert parsed_commit[0] == level
+    assert parsed_commit[1] == commit_type