cloudsmith-cli 1.20.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.
Files changed (130) hide show
  1. cloudsmith_cli/__init__.py +10 -0
  2. cloudsmith_cli/__main__.py +8 -0
  3. cloudsmith_cli/cli/__init__.py +1 -0
  4. cloudsmith_cli/cli/command.py +160 -0
  5. cloudsmith_cli/cli/commands/__init__.py +33 -0
  6. cloudsmith_cli/cli/commands/auth.py +173 -0
  7. cloudsmith_cli/cli/commands/check.py +129 -0
  8. cloudsmith_cli/cli/commands/copy.py +98 -0
  9. cloudsmith_cli/cli/commands/credential_helper/__init__.py +39 -0
  10. cloudsmith_cli/cli/commands/credential_helper/docker.py +66 -0
  11. cloudsmith_cli/cli/commands/credential_helper/manage.py +299 -0
  12. cloudsmith_cli/cli/commands/delete.py +67 -0
  13. cloudsmith_cli/cli/commands/dependencies.py +108 -0
  14. cloudsmith_cli/cli/commands/docs.py +16 -0
  15. cloudsmith_cli/cli/commands/download.py +620 -0
  16. cloudsmith_cli/cli/commands/entitlements.py +819 -0
  17. cloudsmith_cli/cli/commands/help_.py +12 -0
  18. cloudsmith_cli/cli/commands/list_.py +317 -0
  19. cloudsmith_cli/cli/commands/login.py +99 -0
  20. cloudsmith_cli/cli/commands/logout.py +151 -0
  21. cloudsmith_cli/cli/commands/main.py +73 -0
  22. cloudsmith_cli/cli/commands/mcp.py +523 -0
  23. cloudsmith_cli/cli/commands/metadata.py +503 -0
  24. cloudsmith_cli/cli/commands/metrics/__init__.py +2 -0
  25. cloudsmith_cli/cli/commands/metrics/command.py +20 -0
  26. cloudsmith_cli/cli/commands/metrics/entitlements.py +148 -0
  27. cloudsmith_cli/cli/commands/metrics/packages.py +134 -0
  28. cloudsmith_cli/cli/commands/move.py +111 -0
  29. cloudsmith_cli/cli/commands/policy/__init__.py +3 -0
  30. cloudsmith_cli/cli/commands/policy/command.py +20 -0
  31. cloudsmith_cli/cli/commands/policy/deny.py +248 -0
  32. cloudsmith_cli/cli/commands/policy/license.py +335 -0
  33. cloudsmith_cli/cli/commands/policy/vulnerability.py +322 -0
  34. cloudsmith_cli/cli/commands/push.py +1323 -0
  35. cloudsmith_cli/cli/commands/quarantine.py +148 -0
  36. cloudsmith_cli/cli/commands/quota/__init__.py +2 -0
  37. cloudsmith_cli/cli/commands/quota/command.py +20 -0
  38. cloudsmith_cli/cli/commands/quota/history.py +122 -0
  39. cloudsmith_cli/cli/commands/quota/quota.py +107 -0
  40. cloudsmith_cli/cli/commands/repos.py +330 -0
  41. cloudsmith_cli/cli/commands/resync.py +90 -0
  42. cloudsmith_cli/cli/commands/status.py +92 -0
  43. cloudsmith_cli/cli/commands/tags.py +375 -0
  44. cloudsmith_cli/cli/commands/tokens.py +318 -0
  45. cloudsmith_cli/cli/commands/upstream.py +479 -0
  46. cloudsmith_cli/cli/commands/vulnerabilities.py +141 -0
  47. cloudsmith_cli/cli/commands/whoami.py +188 -0
  48. cloudsmith_cli/cli/config.py +635 -0
  49. cloudsmith_cli/cli/decorators.py +624 -0
  50. cloudsmith_cli/cli/exceptions.py +215 -0
  51. cloudsmith_cli/cli/metadata_common.py +146 -0
  52. cloudsmith_cli/cli/saml.py +109 -0
  53. cloudsmith_cli/cli/table.py +59 -0
  54. cloudsmith_cli/cli/types.py +14 -0
  55. cloudsmith_cli/cli/utils.py +267 -0
  56. cloudsmith_cli/cli/validators.py +378 -0
  57. cloudsmith_cli/cli/webserver.py +263 -0
  58. cloudsmith_cli/core/__init__.py +1 -0
  59. cloudsmith_cli/core/api/__init__.py +1 -0
  60. cloudsmith_cli/core/api/distros.py +31 -0
  61. cloudsmith_cli/core/api/entitlements.py +130 -0
  62. cloudsmith_cli/core/api/exceptions.py +57 -0
  63. cloudsmith_cli/core/api/files.py +131 -0
  64. cloudsmith_cli/core/api/init.py +109 -0
  65. cloudsmith_cli/core/api/metadata.py +217 -0
  66. cloudsmith_cli/core/api/metrics.py +78 -0
  67. cloudsmith_cli/core/api/orgs.py +201 -0
  68. cloudsmith_cli/core/api/packages.py +309 -0
  69. cloudsmith_cli/core/api/quota.py +64 -0
  70. cloudsmith_cli/core/api/rates.py +28 -0
  71. cloudsmith_cli/core/api/repos.py +81 -0
  72. cloudsmith_cli/core/api/status.py +27 -0
  73. cloudsmith_cli/core/api/upstreams.py +72 -0
  74. cloudsmith_cli/core/api/user.py +109 -0
  75. cloudsmith_cli/core/api/version.py +15 -0
  76. cloudsmith_cli/core/api/vulnerabilities.py +230 -0
  77. cloudsmith_cli/core/cache_utils.py +160 -0
  78. cloudsmith_cli/core/config.py +140 -0
  79. cloudsmith_cli/core/credentials/__init__.py +0 -0
  80. cloudsmith_cli/core/credentials/chain.py +69 -0
  81. cloudsmith_cli/core/credentials/models.py +44 -0
  82. cloudsmith_cli/core/credentials/oidc/__init__.py +6 -0
  83. cloudsmith_cli/core/credentials/oidc/cache.py +220 -0
  84. cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +122 -0
  85. cloudsmith_cli/core/credentials/oidc/detectors/aws.py +85 -0
  86. cloudsmith_cli/core/credentials/oidc/detectors/azure_devops.py +70 -0
  87. cloudsmith_cli/core/credentials/oidc/detectors/base.py +26 -0
  88. cloudsmith_cli/core/credentials/oidc/detectors/bitbucket_pipelines.py +35 -0
  89. cloudsmith_cli/core/credentials/oidc/detectors/circleci.py +40 -0
  90. cloudsmith_cli/core/credentials/oidc/detectors/generic.py +42 -0
  91. cloudsmith_cli/core/credentials/oidc/detectors/github_actions.py +64 -0
  92. cloudsmith_cli/core/credentials/oidc/detectors/gitlab_ci.py +49 -0
  93. cloudsmith_cli/core/credentials/oidc/exchange.py +87 -0
  94. cloudsmith_cli/core/credentials/provider.py +17 -0
  95. cloudsmith_cli/core/credentials/providers/__init__.py +15 -0
  96. cloudsmith_cli/core/credentials/providers/cli_flag.py +24 -0
  97. cloudsmith_cli/core/credentials/providers/credentials_file.py +24 -0
  98. cloudsmith_cli/core/credentials/providers/env_var.py +24 -0
  99. cloudsmith_cli/core/credentials/providers/keyring_provider.py +59 -0
  100. cloudsmith_cli/core/credentials/providers/oidc_provider.py +115 -0
  101. cloudsmith_cli/core/download.py +594 -0
  102. cloudsmith_cli/core/keyring.py +171 -0
  103. cloudsmith_cli/core/mcp/__init__.py +0 -0
  104. cloudsmith_cli/core/mcp/data.py +17 -0
  105. cloudsmith_cli/core/mcp/server.py +786 -0
  106. cloudsmith_cli/core/pagination.py +131 -0
  107. cloudsmith_cli/core/ratelimits.py +88 -0
  108. cloudsmith_cli/core/rest.py +255 -0
  109. cloudsmith_cli/core/utils.py +95 -0
  110. cloudsmith_cli/core/version.py +20 -0
  111. cloudsmith_cli/credential_helpers/__init__.py +7 -0
  112. cloudsmith_cli/credential_helpers/backends.py +41 -0
  113. cloudsmith_cli/credential_helpers/common.py +111 -0
  114. cloudsmith_cli/credential_helpers/custom_domains.py +281 -0
  115. cloudsmith_cli/credential_helpers/docker/__init__.py +4 -0
  116. cloudsmith_cli/credential_helpers/docker/installer.py +349 -0
  117. cloudsmith_cli/credential_helpers/docker/runtime.py +117 -0
  118. cloudsmith_cli/credential_helpers/launchers.py +175 -0
  119. cloudsmith_cli/data/VERSION +1 -0
  120. cloudsmith_cli/data/config.ini +23 -0
  121. cloudsmith_cli/data/credentials.ini +14 -0
  122. cloudsmith_cli/templates/__init__.py +3 -0
  123. cloudsmith_cli/templates/auth_error.html +45 -0
  124. cloudsmith_cli/templates/auth_success.html +37 -0
  125. cloudsmith_cli-1.20.0.dist-info/METADATA +610 -0
  126. cloudsmith_cli-1.20.0.dist-info/RECORD +130 -0
  127. cloudsmith_cli-1.20.0.dist-info/WHEEL +5 -0
  128. cloudsmith_cli-1.20.0.dist-info/entry_points.txt +2 -0
  129. cloudsmith_cli-1.20.0.dist-info/licenses/LICENSE +201 -0
  130. cloudsmith_cli-1.20.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,330 @@
1
+ """CLI/Commands - create, retrieve, update or delete repositories."""
2
+
3
+ import json
4
+ from operator import itemgetter
5
+
6
+ import click
7
+
8
+ from ...core.api import repos as api
9
+ from ...core.pagination import paginate_results
10
+ from .. import command, decorators, utils, validators
11
+ from ..exceptions import handle_api_exceptions
12
+ from ..utils import maybe_spinner
13
+ from .main import main
14
+
15
+
16
+ def print_repositories(opts, data, page_info=None, show_list_info=True, page_all=False):
17
+ """Print repositories as a table or output in another format."""
18
+ headers = [
19
+ "Name",
20
+ "Type",
21
+ "Packages",
22
+ "Groups",
23
+ "Downloads",
24
+ "Size",
25
+ "Owner / Repository (Identifier)",
26
+ ]
27
+
28
+ rows = []
29
+ for repo in sorted(data, key=itemgetter("namespace", "slug")):
30
+ rows.append(
31
+ [
32
+ click.style(repo["name"], fg="cyan"),
33
+ click.style(repo["repository_type_str"], fg="yellow"),
34
+ click.style(str(repo["package_count"]), fg="blue"),
35
+ click.style(str(repo["package_group_count"]), fg="blue"),
36
+ click.style(str(repo["num_downloads"]), fg="blue"),
37
+ click.style(str(repo["size_str"]), fg="blue"),
38
+ "%(owner_slug)s/%(slug)s"
39
+ % {
40
+ "owner_slug": click.style(repo["namespace"], fg="magenta"),
41
+ "slug": click.style(repo["slug"], fg="green"),
42
+ },
43
+ ]
44
+ )
45
+
46
+ if data:
47
+ click.echo()
48
+ utils.pretty_print_table(headers, rows)
49
+
50
+ click.echo()
51
+
52
+ if not show_list_info:
53
+ return
54
+
55
+ num_results = len(data)
56
+ list_suffix = "repositor%s" % ("ies" if num_results != 1 else "y")
57
+ utils.pretty_print_list_info(
58
+ num_results=num_results,
59
+ page_info=None if page_all else page_info,
60
+ suffix=f"{list_suffix} retrieved" if page_all else f"{list_suffix} visible",
61
+ page_all=page_all,
62
+ )
63
+
64
+
65
+ @main.group(cls=command.AliasGroup, name="repositories", aliases=["repos"])
66
+ @decorators.common_cli_config_options
67
+ @decorators.common_cli_output_options
68
+ @decorators.common_api_auth_options
69
+ @decorators.initialise_api
70
+ @click.pass_context
71
+ def repositories(ctx, opts): # pylink: disable=unused-argument
72
+ """
73
+ Manage Repositories.
74
+
75
+ See the help for subommands for more information on each.
76
+ """
77
+
78
+
79
+ @repositories.command(name="get", aliases=["list", "ls"])
80
+ @decorators.common_cli_config_options
81
+ @decorators.common_cli_list_options
82
+ @decorators.common_cli_output_options
83
+ @decorators.common_api_auth_options
84
+ @decorators.initialise_api
85
+ @click.argument(
86
+ "owner_repo",
87
+ metavar="OWNER/REPO",
88
+ callback=validators.validate_optional_owner_repo,
89
+ default="",
90
+ required=False,
91
+ )
92
+ @click.pass_context
93
+ def get(ctx, opts, owner_repo, page, page_size, page_all):
94
+ """
95
+ List repositories for a namespace (owner).
96
+
97
+ OWNER/REPO: Specify the OWNER namespace (i.e user or org) to list the
98
+ repositories for that namespace.
99
+
100
+ If REPO isn't specified, all repositories will be retrieved from the
101
+ OWNER namespace.
102
+
103
+ If OWNER isn't specified it'll default to the currently authenticated user
104
+ (if any). If you're unauthenticated, no results will be returned.
105
+ """
106
+ # Use stderr for messages if the output is something else (e.g. JSON)
107
+ use_stderr = utils.should_use_stderr(opts)
108
+
109
+ if isinstance(owner_repo, list):
110
+ if len(owner_repo) == 1:
111
+ owner = owner_repo[0]
112
+ repo = None
113
+ else:
114
+ owner, repo = owner_repo
115
+ elif isinstance(owner_repo, str):
116
+ repo = None
117
+ owner = owner_repo or None
118
+ else:
119
+ owner = None
120
+ repo = None
121
+
122
+ if page_all and repo:
123
+ raise click.UsageError(
124
+ "The --page-all option cannot be used when specifying a single repository (OWNER/REPO). Omit the repository slug or remove --page-all."
125
+ )
126
+
127
+ click.echo("Getting list of repositories ... ", nl=False, err=use_stderr)
128
+
129
+ context_msg = "Failed to get list of repositories!"
130
+ with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
131
+ with maybe_spinner(opts):
132
+ repos_, page_info = paginate_results(
133
+ api.list_repos, page_all, page, page_size, owner=owner, repo=repo
134
+ )
135
+
136
+ click.secho("OK", fg="green", err=use_stderr)
137
+
138
+ if utils.maybe_print_as_json(opts, repos_, page_info):
139
+ return
140
+
141
+ print_repositories(
142
+ opts=opts,
143
+ data=repos_,
144
+ show_list_info=True,
145
+ page_info=page_info,
146
+ page_all=page_all,
147
+ )
148
+
149
+
150
+ @repositories.command(aliases=["new"])
151
+ @decorators.common_cli_config_options
152
+ @decorators.common_cli_output_options
153
+ @decorators.common_api_auth_options
154
+ @decorators.initialise_api
155
+ @click.argument("owner", default=None, required=True)
156
+ @click.argument("repo_config_file", type=click.File("rb"), required=True)
157
+ @click.pass_context
158
+ def create(ctx, opts, owner, repo_config_file):
159
+ """
160
+ Create a new repository in a namespace.
161
+
162
+ - OWNER: Specify the OWNER namespace (i.e. user or org) where you want
163
+ to create a repository.
164
+
165
+ Example: 'your-org'
166
+
167
+ - REPO_CONFIG_FILE: Config file specifying the settings for the
168
+ repository to be created.
169
+
170
+ \b
171
+ Example:
172
+ {
173
+ "name": "your-repo",
174
+ "description": "your repo description",
175
+ "repository_type_str": "Private",
176
+ "slug": "your-repo-slug"
177
+ }
178
+
179
+ Full CLI example:
180
+
181
+ $ cloudsmith repos create your-org repo-config-file.json
182
+ """
183
+ # Use stderr for messages if the output is something else (e.g. JSON)
184
+ use_stderr = utils.should_use_stderr(opts)
185
+ repo_config = json.load(repo_config_file)
186
+
187
+ repo_name = repo_config.get("name", None)
188
+ if repo_name is None:
189
+ raise click.BadParameter(
190
+ "Name is a required field for creating a repository.", param="name"
191
+ )
192
+
193
+ click.secho(
194
+ "Creating %(name)s repository for the %(owner)s namespace ..."
195
+ % {
196
+ "name": click.style(repo_name, bold=True),
197
+ "owner": click.style(owner, bold=True),
198
+ },
199
+ nl=False,
200
+ err=use_stderr,
201
+ )
202
+
203
+ context_msg = "Failed to create the repository!"
204
+ with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
205
+ with maybe_spinner(opts):
206
+ repository = api.create_repo(owner, repo_config)
207
+
208
+ click.secho("OK", fg="green", err=use_stderr)
209
+
210
+ if utils.maybe_print_as_json(opts, [repository]):
211
+ return
212
+
213
+ print_repositories(opts=opts, data=[repository], show_list_info=True)
214
+
215
+
216
+ @repositories.command()
217
+ @decorators.common_cli_config_options
218
+ @decorators.common_cli_output_options
219
+ @decorators.common_api_auth_options
220
+ @decorators.initialise_api
221
+ @click.argument(
222
+ "owner_repo", metavar="OWNER/REPO", callback=validators.validate_owner_repo
223
+ )
224
+ @click.argument("repo_config_file", type=click.File("rb"), required=True)
225
+ @click.pass_context
226
+ def update(ctx, opts, owner_repo, repo_config_file):
227
+ """
228
+ Update a repository.
229
+
230
+ - OWNER/REPO: Specify the OWNER namespace (i.e. user or org),
231
+ and the REPO name to be updated. All separated by a slash.
232
+
233
+ Example: 'your-org/your-repo'
234
+
235
+ - REPO_CONFIG_FILE: Config file specifying the settings to
236
+ update on the repository.
237
+
238
+ \b
239
+ Example:
240
+ {
241
+ "description": "your updated repo description",
242
+ "repository_type_str": "Open-Source",
243
+ }
244
+
245
+ Full CLI example:
246
+
247
+ $ cloudsmith repos update your-org/your-repo repo-config-file.json
248
+
249
+ """
250
+ # Use stderr for message if the output is something else (e.g. JSON)
251
+ use_stderr = opts.output != "pretty"
252
+
253
+ owner, repo = owner_repo
254
+ repo_config = json.load(repo_config_file)
255
+
256
+ click.secho(
257
+ "Updating %(name)s repository in the %(owner)s namespace ..."
258
+ % {
259
+ "name": click.style(repo, bold=True),
260
+ "owner": click.style(owner, bold=True),
261
+ },
262
+ nl=False,
263
+ err=use_stderr,
264
+ )
265
+
266
+ context_msg = "Failed to update the repository!"
267
+ with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
268
+ with maybe_spinner(opts):
269
+ repository = api.update_repo(owner, repo, repo_config)
270
+
271
+ click.secho("OK", fg="green", err=use_stderr)
272
+
273
+ if utils.maybe_print_as_json(opts, [repository]):
274
+ return
275
+
276
+ print_repositories(opts=opts, data=[repository], show_list_info=True)
277
+
278
+
279
+ @repositories.command(aliases=["rm"])
280
+ @decorators.common_cli_config_options
281
+ @decorators.common_cli_output_options
282
+ @decorators.common_api_auth_options
283
+ @decorators.initialise_api
284
+ @click.argument(
285
+ "owner_repo", metavar="OWNER/REPO", callback=validators.validate_owner_repo
286
+ )
287
+ @click.option(
288
+ "-y",
289
+ "--yes",
290
+ default=False,
291
+ is_flag=True,
292
+ help="Assume yes as default answer to questions (this is dangerous!)",
293
+ )
294
+ @click.pass_context
295
+ def delete(ctx, opts, owner_repo, yes):
296
+ """
297
+ Delete a repository from a namespace.
298
+
299
+ - OWNER/REPO: Specify the OWNER namespace (i.e. user or org), and the name of the REPO
300
+ to be deleted, separated by a slash.
301
+
302
+ Example: 'your-org/your-repo'
303
+
304
+ Full CLI example:
305
+
306
+ $ cloudsmith repos delete your-org/your-repo
307
+ """
308
+ owner, repo = owner_repo
309
+ delete_args = {
310
+ "namespace": click.style(owner, bold=True),
311
+ "repository": click.style(repo, bold=True),
312
+ }
313
+
314
+ prompt = "delete the %(repository)s from the %(namespace)s namespace" % delete_args
315
+ # Use stderr for messages if the output is something else (e.g. JSON)
316
+ use_stderr = utils.should_use_stderr(opts)
317
+ if not utils.confirm_operation(prompt, assume_yes=yes, err=use_stderr):
318
+ return
319
+
320
+ click.secho(
321
+ "Deleting %(repository)s from the %(namespace)s namespace ... " % delete_args,
322
+ nl=False,
323
+ )
324
+
325
+ context_msg = "Failed to delete the repository!"
326
+ with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
327
+ with maybe_spinner(opts):
328
+ api.delete_repo(owner=owner, repo=repo)
329
+
330
+ click.secho("OK", fg="green")
@@ -0,0 +1,90 @@
1
+ """CLI/Commands - List objects."""
2
+
3
+ import click
4
+
5
+ from ...core.api.packages import resync_package as api_resync_package
6
+ from .. import decorators, utils, validators
7
+ from ..exceptions import handle_api_exceptions
8
+ from ..utils import maybe_spinner
9
+ from .main import main
10
+ from .push import wait_for_package_sync
11
+
12
+
13
+ @main.command()
14
+ @decorators.common_cli_config_options
15
+ @decorators.common_cli_output_options
16
+ @decorators.common_package_action_options
17
+ @decorators.common_api_auth_options
18
+ @decorators.initialise_api
19
+ @click.argument(
20
+ "owner_repo_package",
21
+ metavar="OWNER/REPO/PACKAGE",
22
+ callback=validators.validate_owner_repo_package,
23
+ )
24
+ @click.pass_context
25
+ def resync(
26
+ ctx,
27
+ opts,
28
+ owner_repo_package,
29
+ skip_errors,
30
+ wait_interval,
31
+ no_wait_for_sync,
32
+ sync_attempts,
33
+ ):
34
+ """
35
+ Resynchronise a package in a repository.
36
+
37
+ This requires appropriate permissions for package.
38
+
39
+ - OWNER/REPO/PACKAGE: Specify the OWNER namespace (i.e. user or org), the
40
+ REPO name where the package is stored, and the PACKAGE name (slug) of the
41
+ package itself. All separated by a slash.
42
+
43
+ Example: 'your-org/awesome-repo/better-pkg'.
44
+
45
+ Full CLI example:
46
+
47
+ $ cloudsmith resync your-org/awesome-repo/better-pkg
48
+ """
49
+ owner, source, slug = owner_repo_package
50
+
51
+ resync_package(
52
+ ctx=ctx, opts=opts, owner=owner, repo=source, slug=slug, skip_errors=skip_errors
53
+ )
54
+
55
+ if no_wait_for_sync:
56
+ utils.maybe_print_status_json(opts, {"slug": slug, "status": "OK"})
57
+ return
58
+
59
+ wait_for_package_sync(
60
+ ctx=ctx,
61
+ opts=opts,
62
+ owner=owner,
63
+ repo=source,
64
+ slug=slug,
65
+ wait_interval=wait_interval,
66
+ skip_errors=skip_errors,
67
+ attempts=sync_attempts,
68
+ )
69
+
70
+ utils.maybe_print_status_json(opts, {"slug": slug, "status": "OK"})
71
+
72
+
73
+ def resync_package(ctx, opts, owner, repo, slug, skip_errors):
74
+ """Resynchronise a package."""
75
+ use_stderr = utils.should_use_stderr(opts)
76
+ click.echo(
77
+ "Resynchonising the %(slug)s package ... "
78
+ % {"slug": click.style(slug, bold=True)},
79
+ nl=False,
80
+ err=use_stderr,
81
+ )
82
+
83
+ context_msg = "Failed to resynchronise package!"
84
+ with handle_api_exceptions(
85
+ ctx, opts=opts, context_msg=context_msg, reraise_on_error=skip_errors
86
+ ):
87
+ with maybe_spinner(opts):
88
+ api_resync_package(owner=owner, repo=repo, identifier=slug)
89
+
90
+ click.secho("OK", fg="green", err=use_stderr)
@@ -0,0 +1,92 @@
1
+ """CLI/Commands - Status."""
2
+
3
+ import click
4
+
5
+ from ...core.api.packages import get_package_status
6
+ from .. import decorators, utils, validators
7
+ from ..exceptions import handle_api_exceptions
8
+ from ..utils import maybe_spinner
9
+ from .main import main
10
+
11
+
12
+ @main.command()
13
+ @click.argument(
14
+ "owner_repo_package",
15
+ metavar="OWNER/REPO/PACKAGE",
16
+ callback=validators.validate_owner_repo_package,
17
+ )
18
+ @decorators.common_cli_config_options
19
+ @decorators.common_cli_output_options
20
+ @decorators.common_api_auth_options
21
+ @decorators.initialise_api
22
+ @click.pass_context
23
+ def status(ctx, opts, owner_repo_package):
24
+ """
25
+ Get the synchronisation status for a package.
26
+
27
+ - OWNER/REPO/PACKAGE: Specify the OWNER namespace (i.e. user or org), the
28
+ REPO name where the package is stored, and the PACKAGE name (slug) of the
29
+ package itself. All separated by a slash.
30
+
31
+ Example: 'your-org/awesome-repo/better-pkg'.
32
+ """
33
+ owner, repo, slug = owner_repo_package
34
+
35
+ use_stderr = utils.should_use_stderr(opts)
36
+
37
+ click.echo(
38
+ "Getting status of %(package)s in %(owner)s/%(repo)s ... "
39
+ % {
40
+ "owner": click.style(owner, bold=True),
41
+ "repo": click.style(repo, bold=True),
42
+ "package": click.style(slug, bold=True),
43
+ },
44
+ nl=False,
45
+ err=use_stderr,
46
+ )
47
+
48
+ context_msg = "Failed to get status of package!"
49
+ with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
50
+ with maybe_spinner(opts):
51
+ res = get_package_status(owner, repo, slug)
52
+ ok, failed, _, status_str, stage_str, reason = res
53
+
54
+ click.secho("OK", fg="green", err=use_stderr)
55
+
56
+ if not stage_str:
57
+ package_status = status_str
58
+ else:
59
+ package_status = f"{status_str} / {stage_str}"
60
+
61
+ if ok:
62
+ status_colour = "green"
63
+ elif failed:
64
+ status_colour = "red"
65
+ else:
66
+ status_colour = "magenta"
67
+
68
+ if utils.maybe_print_as_json(
69
+ opts,
70
+ {
71
+ "ok": ok,
72
+ "failed": failed,
73
+ "status": status_str,
74
+ "stage": stage_str,
75
+ "reason": reason,
76
+ "slug": slug,
77
+ },
78
+ ):
79
+ return
80
+
81
+ click.secho(
82
+ "The package status is: %(status)s"
83
+ % {"status": click.style(package_status, fg=status_colour)},
84
+ err=use_stderr,
85
+ )
86
+
87
+ if reason:
88
+ click.secho(
89
+ f"Reason given: {click.style(reason, fg='yellow')}",
90
+ fg=status_colour,
91
+ err=use_stderr,
92
+ )