python-gitlab 4.6.0__py3-none-any.whl → 4.7.0__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.
gitlab/_version.py CHANGED
@@ -3,4 +3,4 @@ __copyright__ = "Copyright 2013-2019 Gauvain Pocentek, 2019-2023 python-gitlab t
3
3
  __email__ = "gauvainpocentek@gmail.com"
4
4
  __license__ = "LGPL3"
5
5
  __title__ = "python-gitlab"
6
- __version__ = "4.6.0"
6
+ __version__ = "4.7.0"
gitlab/cli.py CHANGED
@@ -5,7 +5,6 @@ import os
5
5
  import pathlib
6
6
  import re
7
7
  import sys
8
- import textwrap
9
8
  from types import ModuleType
10
9
  from typing import (
11
10
  Any,
@@ -37,11 +36,12 @@ class CustomAction:
37
36
  optional: Tuple[str, ...]
38
37
  in_object: bool
39
38
  requires_id: bool # if the `_id_attr` value should be a required argument
39
+ help: Optional[str] # help text for the custom action
40
40
 
41
41
 
42
42
  # custom_actions = {
43
43
  # cls: {
44
- # action: (mandatory_args, optional_args, in_obj),
44
+ # action: CustomAction,
45
45
  # },
46
46
  # }
47
47
  custom_actions: Dict[str, Dict[str, CustomAction]] = {}
@@ -54,33 +54,6 @@ custom_actions: Dict[str, Dict[str, CustomAction]] = {}
54
54
  __F = TypeVar("__F", bound=Callable[..., Any])
55
55
 
56
56
 
57
- class VerticalHelpFormatter(argparse.HelpFormatter):
58
- def format_help(self) -> str:
59
- result = super().format_help()
60
- output = ""
61
- indent = self._indent_increment * " "
62
- for line in result.splitlines(keepends=True):
63
- # All of our resources are on one line and wrapped inside braces.
64
- # For example: {application,resource1,resource2}
65
- # except if there are fewer resources - then the line and help text
66
- # are collapsed on the same line.
67
- # For example: {list} Action to execute on the GitLab resource.
68
- # We then put each resource on its own line to make it easier to read.
69
- if line.strip().startswith("{"):
70
- choice_string, help_string = line.split("}", 1)
71
- choice_list = choice_string.strip(" {").split(",")
72
- help_string = help_string.strip()
73
-
74
- if help_string:
75
- help_indent = len(max(choice_list, key=len)) * " "
76
- choice_list.append(f"{help_indent} {help_string}")
77
-
78
- choices = "\n".join(choice_list)
79
- line = f"{textwrap.indent(choices, indent)}\n"
80
- output += line
81
- return output
82
-
83
-
84
57
  def register_custom_action(
85
58
  *,
86
59
  cls_names: Union[str, Tuple[str, ...]],
@@ -88,6 +61,7 @@ def register_custom_action(
88
61
  optional: Tuple[str, ...] = (),
89
62
  custom_action: Optional[str] = None,
90
63
  requires_id: bool = True, # if the `_id_attr` value should be a required argument
64
+ help: Optional[str] = None, # help text for the action
91
65
  ) -> Callable[[__F], __F]:
92
66
  def wrap(f: __F) -> __F:
93
67
  @functools.wraps(f)
@@ -115,6 +89,7 @@ def register_custom_action(
115
89
  optional=optional,
116
90
  in_object=in_obj,
117
91
  requires_id=requires_id,
92
+ help=help,
118
93
  )
119
94
 
120
95
  return cast(__F, wrapped_f)
@@ -308,6 +283,12 @@ def _get_base_parser(add_help: bool = True) -> argparse.ArgumentParser:
308
283
  action="store_true",
309
284
  default=os.getenv("GITLAB_SKIP_LOGIN"),
310
285
  )
286
+ parser.add_argument(
287
+ "--no-mask-credentials",
288
+ help="Don't mask credentials in debug mode",
289
+ dest="mask_credentials",
290
+ action="store_false",
291
+ )
311
292
  return parser
312
293
 
313
294
 
@@ -395,29 +376,31 @@ def main() -> None:
395
376
  gitlab_resource = args.gitlab_resource
396
377
  resource_action = args.resource_action
397
378
  skip_login = args.skip_login
379
+ mask_credentials = args.mask_credentials
398
380
 
399
381
  args_dict = vars(args)
400
382
  # Remove CLI behavior-related args
401
383
  for item in (
402
- "gitlab",
384
+ "api_version",
403
385
  "config_file",
404
- "verbose",
405
386
  "debug",
387
+ "fields",
388
+ "gitlab",
406
389
  "gitlab_resource",
407
- "resource_action",
408
- "version",
390
+ "job_token",
391
+ "mask_credentials",
392
+ "oauth_token",
409
393
  "output",
410
- "fields",
394
+ "pagination",
395
+ "private_token",
396
+ "resource_action",
411
397
  "server_url",
398
+ "skip_login",
412
399
  "ssl_verify",
413
400
  "timeout",
414
- "api_version",
415
- "pagination",
416
401
  "user_agent",
417
- "private_token",
418
- "oauth_token",
419
- "job_token",
420
- "skip_login",
402
+ "verbose",
403
+ "version",
421
404
  ):
422
405
  args_dict.pop(item)
423
406
  args_dict = {k: _parse_value(v) for k, v in args_dict.items() if v is not None}
@@ -425,7 +408,7 @@ def main() -> None:
425
408
  try:
426
409
  gl = gitlab.Gitlab.merge_config(vars(options), gitlab_id, config_files)
427
410
  if debug:
428
- gl.enable_debug()
411
+ gl.enable_debug(mask_credentials=mask_credentials)
429
412
  if not skip_login and (gl.private_token or gl.oauth_token):
430
413
  gl.auth()
431
414
  except Exception as e:
gitlab/v4/cli.py CHANGED
@@ -300,11 +300,14 @@ def _populate_sub_parser_by_class(
300
300
  if cls.__name__ in cli.custom_actions:
301
301
  name = cls.__name__
302
302
  for action_name in cli.custom_actions[name]:
303
+ custom_action = cli.custom_actions[name][action_name]
303
304
  # NOTE(jlvillal): If we put a function for the `default` value of
304
305
  # the `get` it will always get called, which will break things.
305
306
  action_parser = action_parsers.get(action_name)
306
307
  if action_parser is None:
307
- sub_parser_action = sub_parser.add_parser(action_name)
308
+ sub_parser_action = sub_parser.add_parser(
309
+ action_name, help=custom_action.help
310
+ )
308
311
  else:
309
312
  sub_parser_action = action_parser
310
313
  # Get the attributes for URL/path construction
@@ -315,7 +318,6 @@ def _populate_sub_parser_by_class(
315
318
  )
316
319
  sub_parser_action.add_argument("--sudo", required=False)
317
320
 
318
- custom_action = cli.custom_actions[name][action_name]
319
321
  # We need to get the object somehow
320
322
  if not issubclass(cls, gitlab.mixins.GetWithoutIdMixin):
321
323
  if cls._id_attr is not None and custom_action.requires_id:
@@ -386,7 +388,6 @@ def extend_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
386
388
  mgr_cls = getattr(gitlab.v4.objects, mgr_cls_name)
387
389
  object_group = subparsers.add_parser(
388
390
  arg_name,
389
- formatter_class=cli.VerticalHelpFormatter,
390
391
  help=f"API endpoint: {mgr_cls._path}",
391
392
  )
392
393
 
@@ -37,7 +37,10 @@ class ProjectKeyManager(CRUDMixin, RESTManager):
37
37
  _update_attrs = RequiredOptional(optional=("title", "can_push"))
38
38
 
39
39
  @cli.register_custom_action(
40
- cls_names="ProjectKeyManager", required=("key_id",), requires_id=False
40
+ cls_names="ProjectKeyManager",
41
+ required=("key_id",),
42
+ requires_id=False,
43
+ help="Enable a deploy key for the project",
41
44
  )
42
45
  @exc.on_http_error(exc.GitlabProjectDeployKeyError)
43
46
  def enable(
@@ -139,6 +139,27 @@ class ProjectPipelineManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManage
139
139
  ProjectPipeline, CreateMixin.create(self, data, path=path, **kwargs)
140
140
  )
141
141
 
142
+ def latest(self, ref: Optional[str] = None, lazy: bool = False) -> ProjectPipeline:
143
+ """Get the latest pipeline for the most recent commit
144
+ on a specific ref in a project
145
+
146
+ Args:
147
+ ref: The branch or tag to check for the latest pipeline.
148
+ Defaults to the default branch when not specified.
149
+ Returns:
150
+ A Pipeline instance
151
+ """
152
+ data = {}
153
+ if ref:
154
+ data = {"ref": ref}
155
+ if TYPE_CHECKING:
156
+ assert self._obj_cls is not None
157
+ assert self.path is not None
158
+ server_data = self.gitlab.http_get(self.path + "/latest", query_data=data)
159
+ if TYPE_CHECKING:
160
+ assert not isinstance(server_data, requests.Response)
161
+ return self._obj_cls(self, server_data, lazy=lazy)
162
+
142
163
 
143
164
  class ProjectPipelineJob(RESTObject):
144
165
  pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-gitlab
3
- Version: 4.6.0
3
+ Version: 4.7.0
4
4
  Summary: A python wrapper for the GitLab API
5
5
  Author-email: Gauvain Pocentek <gauvain@pocentek.net>
6
6
  Maintainer-email: John Villalovos <john@sodarock.com>, Max Wittig <max.wittig@siemens.com>, Nejc Habjan <nejc.habjan@siemens.com>, Roger Meier <r.meier@siemens.com>
@@ -1,8 +1,8 @@
1
1
  gitlab/__init__.py,sha256=bd8BSLyUUjtHMKtzmf-T5855W6FUHcuhIwx2hNu0w2o,1382
2
2
  gitlab/__main__.py,sha256=HTesNl0UAU6mPb9EXWkTKMy6Q6pAUxGi3iPnDHTE2uE,68
3
- gitlab/_version.py,sha256=JMTtJPASormHXzXDVC7oPZIMS8qox4-C3RSdjtoyR1E,249
3
+ gitlab/_version.py,sha256=2XwMSTXxEohDD4fNho1dzd8yyFVV3HBXblItCGXqEJg,249
4
4
  gitlab/base.py,sha256=5cotawlHD01Vw88aN4o7wNIhDyk_bmcwubX4mbOpnVo,13780
5
- gitlab/cli.py,sha256=PLcL8P0hhjtixHimdPRzY-hDKmLzeFyMB8YzJUIJNOw,13250
5
+ gitlab/cli.py,sha256=CdL1wVZ9npun7sj_kE717hdmf_-A0eF9LH_-PUZOwC4,12398
6
6
  gitlab/client.py,sha256=7HHsmoP4UZgznapb-0_M3Z7ZJx0NJzzoF8ChcwNDzdY,48774
7
7
  gitlab/config.py,sha256=T1DgUXD0-MN2qNszrv-SO5d4uy0FITnNN0vWJgOt2yo,9088
8
8
  gitlab/const.py,sha256=rtPU-fxVSOvgpueoQVTvZGQp6iAZ-aa3nsY4RcSs_M4,5352
@@ -15,7 +15,7 @@ gitlab/_backends/__init__.py,sha256=WalQZRIDzw19FuNxraG7fvck6ddg4cdNd3bi53QKvZM,
15
15
  gitlab/_backends/protocol.py,sha256=m5qSz1o3i0H4XJCWnqx0wIFilOIU9cKxzFsYxLL6Big,842
16
16
  gitlab/_backends/requests_backend.py,sha256=CrSDTfkvi17dT4kTU8R3qQFBNCPJqEfBJq4gJ2GXleA,5534
17
17
  gitlab/v4/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- gitlab/v4/cli.py,sha256=buPexbNJeoi5rwnMV1q7G7zwcwof3m_Xs111yIUawq8,21942
18
+ gitlab/v4/cli.py,sha256=RtD34J52T3O5CspQnuIZkY_jTTZX-Xt6ikwhifxjJGw,21950
19
19
  gitlab/v4/objects/__init__.py,sha256=F_ff0QyakRXOdUzAcIuJCdpLXFvPxW8ZTouYErBQjC4,1990
20
20
  gitlab/v4/objects/access_requests.py,sha256=pPYwB-b4fvKVdBoBRpzx2ensiMXbQwmBkN0XBh6ScaA,923
21
21
  gitlab/v4/objects/appearance.py,sha256=uMt0bjo_KlxwKHItFzGMY9vXm5e489UG_o0EcFVJE8E,1932
@@ -33,7 +33,7 @@ gitlab/v4/objects/clusters.py,sha256=Gsz5Jf2L27gzdbQvb5gKY20gxFT4jZASAofy5qL5hxQ
33
33
  gitlab/v4/objects/commits.py,sha256=ya4hglN4IFVTpa7BLAjMf-xty5E6bLbpzp5vthQdzUk,8292
34
34
  gitlab/v4/objects/container_registry.py,sha256=w-t1nbjavJ18MEPmbIrEUcaOP2mXsr3Oc1Ub_1U95Y0,3360
35
35
  gitlab/v4/objects/custom_attributes.py,sha256=48HKZ2C65UUU65FdvKrefFzRMVKRbG-rl58OE9FAuyI,1875
36
- gitlab/v4/objects/deploy_keys.py,sha256=i05JPwOOKq_h5R4WV4RmY-r78ksVEliEWTnxgqgCz8c,1878
36
+ gitlab/v4/objects/deploy_keys.py,sha256=hv9WSzbE9TqRskVSfyNfATGxSw7-urId2tH6ag1hnq4,1947
37
37
  gitlab/v4/objects/deploy_tokens.py,sha256=SEVSCr9D7LBj7qoE_D1-wK4pr2daFsVwBbhpm4m1Ey0,2110
38
38
  gitlab/v4/objects/deployments.py,sha256=xN7FXcjpHxq25OD4ywhZkbq_5EqlU5dQp-DbWYe1NR0,2889
39
39
  gitlab/v4/objects/discussions.py,sha256=LK-nyJx0ncevYXehiI4gyUQCrY3feZ5mUK6HpqhCeDU,3457
@@ -68,7 +68,7 @@ gitlab/v4/objects/notification_settings.py,sha256=zhltGjuu1HiqdON2v9-uKu7Z6TOOBO
68
68
  gitlab/v4/objects/packages.py,sha256=4tEocanjw1GlFvfOncCY0Z-jJfjiFLhZeUiBIjLz9_g,7225
69
69
  gitlab/v4/objects/pages.py,sha256=o6EHYJa-4qo8-IolppZk5Y5o64CAIlLceW2LPNR3nM4,1141
70
70
  gitlab/v4/objects/personal_access_tokens.py,sha256=vMsAytE5czai3fpyTCyV1sR3cZDZRhvI06u08L8O7mw,1315
71
- gitlab/v4/objects/pipelines.py,sha256=YfH-JN4_u1XhNmxHTFPGeuXe7Gi3aWhPiRtBwbvo7lg,9818
71
+ gitlab/v4/objects/pipelines.py,sha256=nQrzNW6WCTcDCqz_nl8i7YYGpXfRaEVGGpeRdObjeW0,10664
72
72
  gitlab/v4/objects/project_access_tokens.py,sha256=z_BCaBtXC7wzGVN6Ip0H72VwHID8XEBHDddCw0J8hO0,1043
73
73
  gitlab/v4/objects/projects.py,sha256=IS9QARQ36DU1B6S8XvmpxjqciWOygqSC9_wQRFDuoBg,44401
74
74
  gitlab/v4/objects/push_rules.py,sha256=0dKMWEzF5h1zATh0_j_SvjQ7HKx9_5M7J9hzDGB66Rc,3041
@@ -91,10 +91,10 @@ gitlab/v4/objects/triggers.py,sha256=UAERq_C-QdPBbBQPHLh5IfhpkdDeIxdnVGPHfu9Qy5Y
91
91
  gitlab/v4/objects/users.py,sha256=_gGrTwcE17jeoXIPgfFSv54jtF1_9C1R0Y0hhssTvXY,21381
92
92
  gitlab/v4/objects/variables.py,sha256=S0Vz32jEpUbo4J2js8gMPPTVpcy1ge5FYVHLiPz9c-A,2627
93
93
  gitlab/v4/objects/wikis.py,sha256=JtI1cQqZV1_PRfKVlQRMh4LZjdxEfi9T2VuFYv6PrV8,1775
94
- python_gitlab-4.6.0.dist-info/AUTHORS,sha256=Z0P61GJSVnp7iFbRcMezhx3f4zMyPkVmG--TWaRo768,526
95
- python_gitlab-4.6.0.dist-info/COPYING,sha256=2n6rt7r999OuXp8iOqW9we7ORaxWncIbOwN1ILRGR2g,7651
96
- python_gitlab-4.6.0.dist-info/METADATA,sha256=WUoK-pngHNFgI0nPSIetLjJw1vSaPwfspoZoWqDZfbM,8228
97
- python_gitlab-4.6.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
98
- python_gitlab-4.6.0.dist-info/entry_points.txt,sha256=nhpKLLP_uQPFByn8UtE9zsvQQwa402t52o_Cw9IFXMo,43
99
- python_gitlab-4.6.0.dist-info/top_level.txt,sha256=MvIaP8p_Oaf4gO_hXmHkX-5y2deHLp1pe6tJR3ukQ6o,7
100
- python_gitlab-4.6.0.dist-info/RECORD,,
94
+ python_gitlab-4.7.0.dist-info/AUTHORS,sha256=Z0P61GJSVnp7iFbRcMezhx3f4zMyPkVmG--TWaRo768,526
95
+ python_gitlab-4.7.0.dist-info/COPYING,sha256=2n6rt7r999OuXp8iOqW9we7ORaxWncIbOwN1ILRGR2g,7651
96
+ python_gitlab-4.7.0.dist-info/METADATA,sha256=DykK7oYZjqQLJO3GPX9tvurTvHEWqyE9zlGE6YlThvI,8228
97
+ python_gitlab-4.7.0.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
98
+ python_gitlab-4.7.0.dist-info/entry_points.txt,sha256=nhpKLLP_uQPFByn8UtE9zsvQQwa402t52o_Cw9IFXMo,43
99
+ python_gitlab-4.7.0.dist-info/top_level.txt,sha256=MvIaP8p_Oaf4gO_hXmHkX-5y2deHLp1pe6tJR3ukQ6o,7
100
+ python_gitlab-4.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5