roll_util: Add commit_divider property

Add commit_divider property to be used by copybara to trim commit
messages.

Bug: 589
Change-Id: Idc636490e4f21580f2e14ff90133f4c240a6cb35
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/78540
Reviewed-by: Oliver Newman <olivernewman@google.com>
Commit-Queue: Rob Mohr <mohrr@google.com>
diff --git a/recipe_modules/roll_util/__init__.py b/recipe_modules/roll_util/__init__.py
index 5224563..83a9559 100644
--- a/recipe_modules/roll_util/__init__.py
+++ b/recipe_modules/roll_util/__init__.py
@@ -20,6 +20,7 @@
     'fuchsia/sso',
     'recipe_engine/context',
     'recipe_engine/json',
+    'recipe_engine/properties',
     'recipe_engine/raw_io',
     'recipe_engine/step',
 ]
diff --git a/recipe_modules/roll_util/api.py b/recipe_modules/roll_util/api.py
index 5145765..f28aab9 100644
--- a/recipe_modules/roll_util/api.py
+++ b/recipe_modules/roll_util/api.py
@@ -295,6 +295,7 @@
             self.labels_to_set[str(label.label)] = label.value
         self.labels_to_wait_on = sorted(str(x) for x in props.labels_to_wait_on)
         self.footer = []
+        self._commit_divider = props.commit_divider
 
     def authors(self, *roll):
         authors = set()
@@ -464,8 +465,12 @@
     def message(self, *rolls):
         with self.m.step.nest('roll message'):
             if len(rolls) > 1:
-                return self._multiple_rolls_message(*rolls)
-            return self._single_roll_message(*rolls).render()
+                result = self._multiple_rolls_message(*rolls)
+            else:
+                result = self._single_roll_message(*rolls).render()
+            if self._commit_divider:
+                result += '\n{}'.format(self._commit_divider)
+            return result
 
     Direction = _Direction
 
diff --git a/recipe_modules/roll_util/properties.proto b/recipe_modules/roll_util/properties.proto
index 598592d..6585255 100644
--- a/recipe_modules/roll_util/properties.proto
+++ b/recipe_modules/roll_util/properties.proto
@@ -30,4 +30,7 @@
 
   // Non-CQ/CR labels to wait on before attempting submission.
   repeated string labels_to_wait_on = 2;
+
+  // Line of text to divide the commit header and body from the footers.
+  string commit_divider = 3;
 }
\ No newline at end of file
diff --git a/recipe_modules/roll_util/test_api.py b/recipe_modules/roll_util/test_api.py
index 62e9921..7791891 100644
--- a/recipe_modules/roll_util/test_api.py
+++ b/recipe_modules/roll_util/test_api.py
@@ -16,6 +16,23 @@
 
 
 class RollUtilTestApi(recipe_test_api.RecipeTestApi):
+    def properties(
+        self, labels_to_set=None, labels_to_wait_on=None, commit_divider=None,
+    ):
+        props = {}
+
+        for label, value in (labels_to_set or {}).items():
+            props.setdefault('labels_to_set', [])
+            props['labels_to_set'].append({'label': label, 'value': value})
+
+        if labels_to_wait_on:
+            props['labels_to_wait_on'] = list(labels_to_wait_on)
+
+        if commit_divider:
+            props['commit_divider'] = commit_divider
+
+        return self.m.properties(**{'$pigweed/roll_util': props})
+
     def commit(
         self, commit_hash, message=None, author='author@example.com', name=None,
     ):
diff --git a/recipe_modules/roll_util/tests/labels.py b/recipe_modules/roll_util/tests/labels.py
index ff60426..8a83a5f 100644
--- a/recipe_modules/roll_util/tests/labels.py
+++ b/recipe_modules/roll_util/tests/labels.py
@@ -16,7 +16,6 @@
 DEPS = [
     'fuchsia/status_check',
     'pigweed/roll_util',
-    'recipe_engine/properties',
     'recipe_engine/step',
 ]
 
@@ -39,14 +38,10 @@
 
 
 def GenTests(api):
-    properties = {
-        '$pigweed/roll_util': {
-            'labels_to_set': [
-                {'label': 'Trigger', 'value': 1},
-                {'label': 'Foo', 'value': 123},
-            ],
-            'labels_to_wait_on': ['Verified', 'Good'],
-        },
-    }
-
-    yield api.status_check.test('labels') + api.properties(**properties)
+    yield (
+        api.status_check.test('labels')
+        + api.roll_util.properties(
+            labels_to_set={'Trigger': 1, 'Foo': 123},
+            labels_to_wait_on=['Verified', 'Good'],
+        )
+    )
diff --git a/recipe_modules/roll_util/tests/multiple_rolls.expected/mixed.json b/recipe_modules/roll_util/tests/multiple_rolls.expected/mixed.json
index a25102d..6f0cffb 100644
--- a/recipe_modules/roll_util/tests/multiple_rolls.expected/mixed.json
+++ b/recipe_modules/roll_util/tests/multiple_rolls.expected/mixed.json
@@ -805,6 +805,8 @@
       "@@@STEP_LOG_LINE@message@https://pigweed.googlesource.com/pigweed/pigweed@@@",
       "@@@STEP_LOG_LINE@message@xyz Rolled-Commits: 999999999999999..ccccccccccccccc@@@",
       "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@--divider--@@@",
       "@@@STEP_LOG_END@message@@@"
     ]
   },
diff --git a/recipe_modules/roll_util/tests/multiple_rolls.py b/recipe_modules/roll_util/tests/multiple_rolls.py
index d61a9a6..2a5cc97 100644
--- a/recipe_modules/roll_util/tests/multiple_rolls.py
+++ b/recipe_modules/roll_util/tests/multiple_rolls.py
@@ -88,6 +88,7 @@
 
     yield (
         api.status_check.test('mixed')
+        + api.roll_util.properties(commit_divider='--divider--')
         + api.roll_util.commit_data('abc', api.roll_util.commit('4' * 40))
         + api.roll_util.commit_data(
             'def',
diff --git a/recipe_modules/roll_util/tests/single_roll.expected/frombranch.json b/recipe_modules/roll_util/tests/single_roll.expected/frombranch.json
index 9ebccdc..c94df5e 100644
--- a/recipe_modules/roll_util/tests/single_roll.expected/frombranch.json
+++ b/recipe_modules/roll_util/tests/single_roll.expected/frombranch.json
@@ -613,6 +613,24 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "message",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@message@[proj] Roll multiple commits@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@555555555555555 five@@@",
+      "@@@STEP_LOG_LINE@message@444444444444444 four@@@",
+      "@@@STEP_LOG_LINE@message@333333333333333 three@@@",
+      "@@@STEP_LOG_LINE@message@222222222222222 two@@@",
+      "@@@STEP_LOG_LINE@message@111111111111111 one@@@",
+      "@@@STEP_LOG_LINE@message@...@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@https://pigweed.googlesource.com/pigweed/pigweed@@@",
+      "@@@STEP_LOG_LINE@message@proj Rolled-Commits: main..555555555555555@@@",
+      "@@@STEP_LOG_END@message@@@"
+    ]
+  },
+  {
     "cmd": [
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
       "account-query",
diff --git a/recipe_modules/roll_util/tests/single_roll.expected/multicommit.json b/recipe_modules/roll_util/tests/single_roll.expected/multicommit.json
index 2957709..f3a60ed 100644
--- a/recipe_modules/roll_util/tests/single_roll.expected/multicommit.json
+++ b/recipe_modules/roll_util/tests/single_roll.expected/multicommit.json
@@ -533,6 +533,22 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "message",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@message@[proj] Roll 4 commits@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@444444444444444 xyz@@@",
+      "@@@STEP_LOG_LINE@message@333333333333333 baz@@@",
+      "@@@STEP_LOG_LINE@message@222222222222222 00000000001111111111222222222233333333334444444444@@@",
+      "@@@STEP_LOG_LINE@message@111111111111111 foo@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@https://pigweed.googlesource.com/pigweed/pigweed@@@",
+      "@@@STEP_LOG_LINE@message@proj Rolled-Commits: 000000000000000..444444444444444@@@",
+      "@@@STEP_LOG_END@message@@@"
+    ]
+  },
+  {
     "cmd": [
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
       "account-query",
diff --git a/recipe_modules/roll_util/tests/single_roll.expected/rebase.json b/recipe_modules/roll_util/tests/single_roll.expected/rebase.json
index 6105837..05c3ab0 100644
--- a/recipe_modules/roll_util/tests/single_roll.expected/rebase.json
+++ b/recipe_modules/roll_util/tests/single_roll.expected/rebase.json
@@ -612,6 +612,23 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "message",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@message@[proj] Roll 5 commits@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@555555555555555 five@@@",
+      "@@@STEP_LOG_LINE@message@444444444444444 four@@@",
+      "@@@STEP_LOG_LINE@message@333333333333333 three@@@",
+      "@@@STEP_LOG_LINE@message@222222222222222 two@@@",
+      "@@@STEP_LOG_LINE@message@111111111111111 one@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@https://pigweed.googlesource.com/pigweed/pigweed@@@",
+      "@@@STEP_LOG_LINE@message@proj Rolled-Commits: 000000000000000..555555555555555@@@",
+      "@@@STEP_LOG_END@message@@@"
+    ]
+  },
+  {
     "cmd": [
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
       "account-query",
diff --git a/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_multiline.json b/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_multiline.json
index aca1634..6494169 100644
--- a/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_multiline.json
+++ b/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_multiline.json
@@ -302,6 +302,22 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "message",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@message@[roll proj] foo@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@bar@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@Original-Bug: 123@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@https://pigweed.googlesource.com/pigweed/pigweed@@@",
+      "@@@STEP_LOG_LINE@message@proj Rolled-Commits: 000000000000000..111111111111111@@@",
+      "@@@STEP_LOG_LINE@message@--divider--@@@",
+      "@@@STEP_LOG_END@message@@@"
+    ]
+  },
+  {
     "cmd": [
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
       "account-query",
diff --git a/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_singleline.json b/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_singleline.json
index 6a67415..aec36f6 100644
--- a/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_singleline.json
+++ b/recipe_modules/roll_util/tests/single_roll.expected/singlecommit_singleline.json
@@ -301,6 +301,21 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "message",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@message@[roll proj] foo@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@bar@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@@@@",
+      "@@@STEP_LOG_LINE@message@https://pigweed.googlesource.com/pigweed/pigweed@@@",
+      "@@@STEP_LOG_LINE@message@proj Rolled-Commits: 000000000000000..111111111111111@@@",
+      "@@@STEP_LOG_LINE@message@--divider--@@@",
+      "@@@STEP_LOG_END@message@@@"
+    ]
+  },
+  {
     "cmd": [
       "[START_DIR]/cipd_tool/path/to/gerrit/version%3Apinned-version/gerrit",
       "account-query",
diff --git a/recipe_modules/roll_util/tests/single_roll.py b/recipe_modules/roll_util/tests/single_roll.py
index fb0a574..ab9231b 100644
--- a/recipe_modules/roll_util/tests/single_roll.py
+++ b/recipe_modules/roll_util/tests/single_roll.py
@@ -66,7 +66,9 @@
                 x.email for x in api.roll_util.reviewers(roll)
             )
 
-        api.roll_util.message(roll)
+        message = api.roll_util.message(roll)
+        with api.step.nest('message') as pres:
+            pres.logs['message'] = message
 
     else:
         api.roll_util.skip_roll_step('remote', old_revision, new_revision)
@@ -104,6 +106,7 @@
         + api.properties(
             project_name='proj', old_revision='0' * 40, new_revision='1' * 40
         )
+        + api.roll_util.properties(commit_divider='--divider--')
         + api.roll_util.commit_data(
             'proj',
             api.roll_util.commit('1' * 40, 'foo\n\nbar\n\nChange-Id: I11111'),
@@ -117,6 +120,7 @@
         + api.properties(
             project_name='proj', old_revision='0' * 40, new_revision='1' * 40
         )
+        + api.roll_util.properties(commit_divider='--divider--')
         + api.roll_util.commit_data(
             'proj',
             api.roll_util.commit(
diff --git a/recipes/submodule_roller.expected/success-sso-cc-authors.json b/recipes/submodule_roller.expected/success-sso-cc-authors.json
index fe452b1..8c648e0 100644
--- a/recipes/submodule_roller.expected/success-sso-cc-authors.json
+++ b/recipes/submodule_roller.expected/success-sso-cc-authors.json
@@ -1740,7 +1740,7 @@
       "git",
       "commit",
       "-m",
-      "[roll a1] foo\nbar\n\n\nhttps://pigweed.googlesource.com/pigweed/pigweed\na1 Rolled-Commits: 111111111111111..2d72510e447ab60\nRoller-URL: https://ci.chromium.org/b/8945511751514863184\nCq-Cl-Tag: roller-builder:builder\nCq-Cl-Tag: roller-bid:8945511751514863184\nCQ-Do-Not-Cancel-Tryjobs: true\nChange-Id: I27ec3e6a65adbbeb0f5d0b74ef7036a069efcfe8",
+      "[roll a1] foo\nbar\n\n\nhttps://pigweed.googlesource.com/pigweed/pigweed\na1 Rolled-Commits: 111111111111111..2d72510e447ab60\n--divider--\nRoller-URL: https://ci.chromium.org/b/8945511751514863184\nCq-Cl-Tag: roller-builder:builder\nCq-Cl-Tag: roller-bid:8945511751514863184\nCQ-Do-Not-Cancel-Tryjobs: true\nChange-Id: I27ec3e6a65adbbeb0f5d0b74ef7036a069efcfe8",
       "-a",
       "--author",
       "author <author@pigweed.infra.roller.example.com>"
diff --git a/recipes/submodule_roller.py b/recipes/submodule_roller.py
index af35c74..2dd234f 100644
--- a/recipes/submodule_roller.py
+++ b/recipes/submodule_roller.py
@@ -386,6 +386,7 @@
     yield (
         api.status_check.test('success-sso-cc-authors')
         + properties(submodule_path='a1', cc_authors_on_rolls=True)
+        + api.roll_util.properties(commit_divider='--divider--')
         + trigger('a1')
         + commit_data('a1', prefix='')
         + gitmodules(a1='sso://foo/a1')
diff --git a/recipes/txt_roller.expected/success.json b/recipes/txt_roller.expected/success.json
index d0bed31..d2152a3 100644
--- a/recipes/txt_roller.expected/success.json
+++ b/recipes/txt_roller.expected/success.json
@@ -2367,7 +2367,7 @@
       "git",
       "commit",
       "-m",
-      "[roll foo.txt] foo\nbar\n\n\nhttps://pigweed.googlesource.com/pigweed/pigweed\nfoo.txt Rolled-Commits: 111111111111111..2d72510e447ab60\nRoller-URL: https://ci.chromium.org/b/8945511751514863184\nCq-Cl-Tag: roller-builder:builder\nCq-Cl-Tag: roller-bid:8945511751514863184\nCQ-Do-Not-Cancel-Tryjobs: true\nChange-Id: I28135185e8ac8c69d0b894c4be54ddbb0ea69d5c",
+      "[roll foo.txt] foo\nbar\n\n\nhttps://pigweed.googlesource.com/pigweed/pigweed\nfoo.txt Rolled-Commits: 111111111111111..2d72510e447ab60\n--divider--\nRoller-URL: https://ci.chromium.org/b/8945511751514863184\nCq-Cl-Tag: roller-builder:builder\nCq-Cl-Tag: roller-bid:8945511751514863184\nCQ-Do-Not-Cancel-Tryjobs: true\nChange-Id: I28135185e8ac8c69d0b894c4be54ddbb0ea69d5c",
       "-a",
       "--author",
       "author <author@pigweed.infra.roller.example.com>"
diff --git a/recipes/txt_roller.py b/recipes/txt_roller.py
index f855f0b..cf25a27 100644
--- a/recipes/txt_roller.py
+++ b/recipes/txt_roller.py
@@ -166,6 +166,7 @@
     yield (
         api.status_check.test('success')
         + properties(txt_path='foo.txt', project_remote=_url("foo"))
+        + api.roll_util.properties(commit_divider='--divider--')
         + trigger('foo')
         + api.roll_util.forward_roll()
         + commit_data('foo.txt', prefix='')