summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--project.py32
-rw-r--r--subcmds/upload.py6
-rw-r--r--tests/test_project.py10
3 files changed, 48 insertions, 0 deletions
diff --git a/project.py b/project.py
index 1821c354..40ca116d 100644
--- a/project.py
+++ b/project.py
@@ -21,6 +21,7 @@ import random
21import re 21import re
22import shutil 22import shutil
23import stat 23import stat
24import string
24import subprocess 25import subprocess
25import sys 26import sys
26import tarfile 27import tarfile
@@ -266,6 +267,7 @@ class ReviewableBranch:
266 dest_branch=None, 267 dest_branch=None,
267 validate_certs=True, 268 validate_certs=True,
268 push_options=None, 269 push_options=None,
270 patchset_description=None,
269 ): 271 ):
270 self.project.UploadForReview( 272 self.project.UploadForReview(
271 branch=self.name, 273 branch=self.name,
@@ -281,6 +283,7 @@ class ReviewableBranch:
281 dest_branch=dest_branch, 283 dest_branch=dest_branch,
282 validate_certs=validate_certs, 284 validate_certs=validate_certs,
283 push_options=push_options, 285 push_options=push_options,
286 patchset_description=patchset_description,
284 ) 287 )
285 288
286 def GetPublishedRefs(self): 289 def GetPublishedRefs(self):
@@ -1089,6 +1092,7 @@ class Project:
1089 dest_branch=None, 1092 dest_branch=None,
1090 validate_certs=True, 1093 validate_certs=True,
1091 push_options=None, 1094 push_options=None,
1095 patchset_description=None,
1092 ): 1096 ):
1093 """Uploads the named branch for code review.""" 1097 """Uploads the named branch for code review."""
1094 if branch is None: 1098 if branch is None:
@@ -1171,6 +1175,10 @@ class Project:
1171 opts += ["wip"] 1175 opts += ["wip"]
1172 if ready: 1176 if ready:
1173 opts += ["ready"] 1177 opts += ["ready"]
1178 if patchset_description:
1179 opts += [
1180 f"m={self._encode_patchset_description(patchset_description)}"
1181 ]
1174 if opts: 1182 if opts:
1175 ref_spec = ref_spec + "%" + ",".join(opts) 1183 ref_spec = ref_spec + "%" + ",".join(opts)
1176 cmd.append(ref_spec) 1184 cmd.append(ref_spec)
@@ -1183,6 +1191,30 @@ class Project:
1183 R_PUB + branch.name, R_HEADS + branch.name, message=msg 1191 R_PUB + branch.name, R_HEADS + branch.name, message=msg
1184 ) 1192 )
1185 1193
1194 @staticmethod
1195 def _encode_patchset_description(original):
1196 """Applies percent-encoding for strings sent as patchset description.
1197
1198 The encoding used is based on but stricter than URL encoding (Section
1199 2.1 of RFC 3986). The only non-escaped characters are alphanumerics, and
1200 'SPACE' (U+0020) can be represented as 'LOW LINE' (U+005F) or
1201 'PLUS SIGN' (U+002B).
1202
1203 For more information, see the Gerrit docs here:
1204 https://gerrit-review.googlesource.com/Documentation/user-upload.html#patch_set_description
1205 """
1206 SAFE = {ord(x) for x in string.ascii_letters + string.digits}
1207
1208 def _enc(b):
1209 if b in SAFE:
1210 return chr(b)
1211 elif b == ord(" "):
1212 return "_"
1213 else:
1214 return f"%{b:02x}"
1215
1216 return "".join(_enc(x) for x in original.encode("utf-8"))
1217
1186 def _ExtractArchive(self, tarpath, path=None): 1218 def _ExtractArchive(self, tarpath, path=None):
1187 """Extract the given tar on its current location 1219 """Extract the given tar on its current location
1188 1220
diff --git a/subcmds/upload.py b/subcmds/upload.py
index 4bcdfaf9..001453fe 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -245,6 +245,11 @@ Gerrit Code Review: https://www.gerritcodereview.com/
245 help="add a label when uploading", 245 help="add a label when uploading",
246 ) 246 )
247 p.add_option( 247 p.add_option(
248 "--pd",
249 "--patchset-description",
250 help="description for patchset",
251 )
252 p.add_option(
248 "--re", 253 "--re",
249 "--reviewers", 254 "--reviewers",
250 type="string", 255 type="string",
@@ -655,6 +660,7 @@ Gerrit Code Review: https://www.gerritcodereview.com/
655 dest_branch=destination, 660 dest_branch=destination,
656 validate_certs=opt.validate_certs, 661 validate_certs=opt.validate_certs,
657 push_options=opt.push_options, 662 push_options=opt.push_options,
663 patchset_description=opt.patchset_description,
658 ) 664 )
659 665
660 branch.uploaded = True 666 branch.uploaded = True
diff --git a/tests/test_project.py b/tests/test_project.py
index 6dc071bd..de26e91a 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -107,6 +107,16 @@ class ReviewableBranchTests(unittest.TestCase):
107 self.assertTrue(rb.date) 107 self.assertTrue(rb.date)
108 108
109 109
110class ProjectTests(unittest.TestCase):
111 """Check Project behavior."""
112
113 def test_encode_patchset_description(self):
114 self.assertEqual(
115 project.Project._encode_patchset_description("abcd00!! +"),
116 "abcd00%21%21_%2b",
117 )
118
119
110class CopyLinkTestCase(unittest.TestCase): 120class CopyLinkTestCase(unittest.TestCase):
111 """TestCase for stub repo client checkouts. 121 """TestCase for stub repo client checkouts.
112 122