github2gerrit 2.4.2__py3-none-any.whl → 2.4.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,15 +19,17 @@ Design goals
19
19
  ``config.py`` (host-only), ``core.py`` (host+port+project), and
20
20
  ``duplicate_detection.py`` (host+project) is supported, plus the
21
21
  ``base_path`` field used by the sister ``dependamerge`` project.
22
- * **Consistent regex** — a single set of precompiled patterns that
23
- tolerates optional whitespace around ``=`` and is case-insensitive on
24
- keys (both forms seen in the wild).
22
+ * **Consistent parsing** — a file with a ``[gerrit]`` section is read
23
+ with ``configparser``, as git-review reads it. Any other file falls
24
+ back to a single set of precompiled patterns that tolerates optional
25
+ whitespace around ``=`` and is case-insensitive on keys.
25
26
  * **Bug-free fetching** — URL-encodes branch names, deduplicates the
26
27
  branch list, and validates raw URLs before opening them.
27
28
  """
28
29
 
29
30
  from __future__ import annotations
30
31
 
32
+ import configparser
31
33
  import logging
32
34
  import os
33
35
  import re
@@ -45,9 +47,54 @@ log = logging.getLogger(__name__)
45
47
  DEFAULT_GERRIT_PORT: int = 29418
46
48
  """Default Gerrit SSH port when the ``port=`` line is absent."""
47
49
 
50
+ # Fallback scan for files configparser cannot read (see
51
+ # _read_gerrit_section): keys at the start of a line, anywhere in the file.
48
52
  _HOST_RE = re.compile(r"(?mi)^host[ \t]*=[ \t]*(.+?)[ \t\r]*$")
49
53
  _PORT_RE = re.compile(r"(?mi)^port[ \t]*=[ \t]*(\d+)[ \t\r]*$")
50
54
  _PROJECT_RE = re.compile(r"(?mi)^project[ \t]*=[ \t]*(.+?)[ \t\r]*$")
55
+ _PORT_VALUE_RE = re.compile(r"\d+")
56
+
57
+ _Fields = tuple[str | None, str | None, str | None]
58
+ """Raw ``host``, ``port`` and ``project`` values; ``None`` when absent."""
59
+
60
+
61
+ def _read_gerrit_section(text: str) -> _Fields | None:
62
+ """Read the fields as git-review does, through ``configparser``.
63
+
64
+ That settles indentation, continuation lines, other sections and
65
+ ``[DEFAULT]`` inheritance (an empty ``[gerrit]`` value included)
66
+ exactly as git-review sees them. Returns ``None`` when the text has
67
+ no ``[gerrit]`` section or ``configparser`` rejects it; git-review
68
+ cannot read such a file either, so the caller falls back to the
69
+ lenient scan.
70
+ """
71
+ parser = configparser.ConfigParser(interpolation=None)
72
+ try:
73
+ parser.read_string(text)
74
+ except configparser.Error as exc:
75
+ log.debug(".gitreview: not readable as INI (%s); scanning lines", exc)
76
+ return None
77
+ if not parser.has_section("gerrit"):
78
+ return None
79
+ section = parser["gerrit"]
80
+
81
+ def first_line(key: str) -> str | None:
82
+ # A continuation makes a multi-line value; a field is one line.
83
+ value = section.get(key)
84
+ return None if value is None else value.strip().split("\n", 1)[0]
85
+
86
+ return first_line("host"), first_line("port"), first_line("project")
87
+
88
+
89
+ def _scan_fields(text: str) -> _Fields:
90
+ """Find the fields by line pattern anywhere in *text*."""
91
+ matches = (
92
+ _HOST_RE.search(text),
93
+ _PORT_RE.search(text),
94
+ _PROJECT_RE.search(text),
95
+ )
96
+ host, port, project = (m.group(1) if m else None for m in matches)
97
+ return host, port, project
51
98
 
52
99
 
53
100
  @dataclass(frozen=True)
@@ -144,10 +191,14 @@ def parse_gitreview(text: str) -> GitReviewInfo | None:
144
191
 
145
192
  This parser is intentionally lenient:
146
193
 
147
- * Keys are matched case-insensitively.
148
- * Optional whitespace around ``=`` is tolerated.
149
- * The ``[gerrit]`` section header itself is **not** required —
150
- the parser matches the key lines directly.
194
+ * A file with a ``[gerrit]`` section is read with ``configparser``,
195
+ as git-review reads it: keys are case-insensitive and may be
196
+ indented, continuation lines and other sections are ignored, and
197
+ ``[DEFAULT]`` supplies any field ``[gerrit]`` does not set.
198
+ * The ``[gerrit]`` header itself is **not** required. A file without
199
+ one, or one ``configparser`` rejects, is scanned for ``host=``,
200
+ ``port=`` and ``project=`` lines anywhere, with optional
201
+ whitespace around ``=``.
151
202
 
152
203
  Args:
153
204
  text: Raw text content of a ``.gitreview`` file.
@@ -156,23 +207,24 @@ def parse_gitreview(text: str) -> GitReviewInfo | None:
156
207
  A :class:`GitReviewInfo` if at least ``host`` is present and
157
208
  non-empty, otherwise ``None``.
158
209
  """
159
- host_match = _HOST_RE.search(text)
160
- if not host_match:
210
+ fields = _read_gerrit_section(text)
211
+ host, port_text, project_text = (
212
+ fields if fields is not None else _scan_fields(text)
213
+ )
214
+ if host is None:
161
215
  log.debug(".gitreview: no host= line found")
162
216
  return None
163
217
 
164
- host = host_match.group(1).strip()
218
+ host = host.strip()
165
219
  if not host:
166
220
  log.debug(".gitreview: host= line is empty")
167
221
  return None
168
222
 
169
- port_match = _PORT_RE.search(text)
170
- port = int(port_match.group(1)) if port_match else DEFAULT_GERRIT_PORT
223
+ port_text = (port_text or "").strip()
224
+ port_given = _PORT_VALUE_RE.fullmatch(port_text) is not None
225
+ port = int(port_text) if port_given else DEFAULT_GERRIT_PORT
171
226
 
172
- project = ""
173
- project_match = _PROJECT_RE.search(text)
174
- if project_match:
175
- project = project_match.group(1).strip().removesuffix(".git")
227
+ project = (project_text or "").strip().removesuffix(".git")
176
228
 
177
229
  base_path = derive_base_path(host)
178
230
 
@@ -181,7 +233,7 @@ def parse_gitreview(text: str) -> GitReviewInfo | None:
181
233
  port=port,
182
234
  project=project,
183
235
  base_path=base_path,
184
- port_given=port_match is not None,
236
+ port_given=port_given,
185
237
  )
186
238
  log.debug(
187
239
  "Parsed .gitreview: host=%s, port=%d, project=%s, base_path=%s",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: github2gerrit
3
- Version: 2.4.2
3
+ Version: 2.4.3
4
4
  Summary: Submit a GitHub pull request to a Gerrit repository.
5
5
  Project-URL: Homepage, https://github.com/lfreleng-actions/github2gerrit-action
6
6
  Project-URL: Repository, https://github.com/lfreleng-actions/github2gerrit-action
@@ -16,7 +16,7 @@ github2gerrit/gerrit_rest.py,sha256=I0c6Jeag9ygmHigtvFKIzqDZwVNjLTXoQW9w4P-bG2c,
16
16
  github2gerrit/gerrit_ssh.py,sha256=UOPI6rPMxUwSrQKRrRAqxuL_tyQabxNslWXTttye70A,9132
17
17
  github2gerrit/gerrit_urls.py,sha256=BmFIOQ9ILTbNrjAo4K6shHk_-6sPnucQxqHmT_FMN_Q,13682
18
18
  github2gerrit/github_api.py,sha256=GuncFKSyd8PYlTAzc4iIZIvNnQB4sN0pXn_-Gh5s3ck,15537
19
- github2gerrit/gitreview.py,sha256=JV7wIninafcEw5bIt9KxN6ZtGWCPsQ0eq-VeOQ-R2kA,24240
19
+ github2gerrit/gitreview.py,sha256=NTAbXV_kTKx-StvNjF0NyEDZDVXtJ8UVaJ1QliT-jow,26447
20
20
  github2gerrit/gitutils.py,sha256=PtaQMpYrf4hC2TjR8fyI0OjHyCLeDnyK8rsvOac2uoE,26512
21
21
  github2gerrit/mapping_comment.py,sha256=4jpiiMnoZCT-rRd3WIdMi-afrI3HriwCfdYZ8qLZHE0,9670
22
22
  github2gerrit/models.py,sha256=t7zu3jPaZOWp8RcEu4Oa1_8WmdIjhLIldYpYd5vAExQ,8601
@@ -39,8 +39,8 @@ github2gerrit/trust.py,sha256=_1T4qRmnpQNd6dcVMBGqrP0pcZsW5QKYgpHWYsAZuoI,4275
39
39
  github2gerrit/utils.py,sha256=2izB7vvp0-Lnej4dx5eE8mW3is-PdYBWQyor8eUcyhk,6934
40
40
  github2gerrit/orchestrator/__init__.py,sha256=HAEcdCAHOFr8LsdIwAdcIcFZn_ayMbX9rdVUULp8410,864
41
41
  github2gerrit/orchestrator/reconciliation.py,sha256=TJaAsuLo0_PRnWt3e_RxwKufETKX8b1unV_U_lsZp8E,22105
42
- github2gerrit-2.4.2.dist-info/METADATA,sha256=IZBOQZPNf-t4ZGEt-ovQbu5TZXYNpjgB-4ZybPfhQp8,27590
43
- github2gerrit-2.4.2.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
44
- github2gerrit-2.4.2.dist-info/entry_points.txt,sha256=MxN2_liIKo3-xJwtAulAeS5GcOS6JS96nvwOQIkP3W8,56
45
- github2gerrit-2.4.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
46
- github2gerrit-2.4.2.dist-info/RECORD,,
42
+ github2gerrit-2.4.3.dist-info/METADATA,sha256=FT0c5xAXhg0tZtXCgqnonr-k3QhT6kllwb2rul3-QHk,27590
43
+ github2gerrit-2.4.3.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
44
+ github2gerrit-2.4.3.dist-info/entry_points.txt,sha256=MxN2_liIKo3-xJwtAulAeS5GcOS6JS96nvwOQIkP3W8,56
45
+ github2gerrit-2.4.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
46
+ github2gerrit-2.4.3.dist-info/RECORD,,