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.
- cloudsmith_cli/__init__.py +10 -0
- cloudsmith_cli/__main__.py +8 -0
- cloudsmith_cli/cli/__init__.py +1 -0
- cloudsmith_cli/cli/command.py +160 -0
- cloudsmith_cli/cli/commands/__init__.py +33 -0
- cloudsmith_cli/cli/commands/auth.py +173 -0
- cloudsmith_cli/cli/commands/check.py +129 -0
- cloudsmith_cli/cli/commands/copy.py +98 -0
- cloudsmith_cli/cli/commands/credential_helper/__init__.py +39 -0
- cloudsmith_cli/cli/commands/credential_helper/docker.py +66 -0
- cloudsmith_cli/cli/commands/credential_helper/manage.py +299 -0
- cloudsmith_cli/cli/commands/delete.py +67 -0
- cloudsmith_cli/cli/commands/dependencies.py +108 -0
- cloudsmith_cli/cli/commands/docs.py +16 -0
- cloudsmith_cli/cli/commands/download.py +620 -0
- cloudsmith_cli/cli/commands/entitlements.py +819 -0
- cloudsmith_cli/cli/commands/help_.py +12 -0
- cloudsmith_cli/cli/commands/list_.py +317 -0
- cloudsmith_cli/cli/commands/login.py +99 -0
- cloudsmith_cli/cli/commands/logout.py +151 -0
- cloudsmith_cli/cli/commands/main.py +73 -0
- cloudsmith_cli/cli/commands/mcp.py +523 -0
- cloudsmith_cli/cli/commands/metadata.py +503 -0
- cloudsmith_cli/cli/commands/metrics/__init__.py +2 -0
- cloudsmith_cli/cli/commands/metrics/command.py +20 -0
- cloudsmith_cli/cli/commands/metrics/entitlements.py +148 -0
- cloudsmith_cli/cli/commands/metrics/packages.py +134 -0
- cloudsmith_cli/cli/commands/move.py +111 -0
- cloudsmith_cli/cli/commands/policy/__init__.py +3 -0
- cloudsmith_cli/cli/commands/policy/command.py +20 -0
- cloudsmith_cli/cli/commands/policy/deny.py +248 -0
- cloudsmith_cli/cli/commands/policy/license.py +335 -0
- cloudsmith_cli/cli/commands/policy/vulnerability.py +322 -0
- cloudsmith_cli/cli/commands/push.py +1323 -0
- cloudsmith_cli/cli/commands/quarantine.py +148 -0
- cloudsmith_cli/cli/commands/quota/__init__.py +2 -0
- cloudsmith_cli/cli/commands/quota/command.py +20 -0
- cloudsmith_cli/cli/commands/quota/history.py +122 -0
- cloudsmith_cli/cli/commands/quota/quota.py +107 -0
- cloudsmith_cli/cli/commands/repos.py +330 -0
- cloudsmith_cli/cli/commands/resync.py +90 -0
- cloudsmith_cli/cli/commands/status.py +92 -0
- cloudsmith_cli/cli/commands/tags.py +375 -0
- cloudsmith_cli/cli/commands/tokens.py +318 -0
- cloudsmith_cli/cli/commands/upstream.py +479 -0
- cloudsmith_cli/cli/commands/vulnerabilities.py +141 -0
- cloudsmith_cli/cli/commands/whoami.py +188 -0
- cloudsmith_cli/cli/config.py +635 -0
- cloudsmith_cli/cli/decorators.py +624 -0
- cloudsmith_cli/cli/exceptions.py +215 -0
- cloudsmith_cli/cli/metadata_common.py +146 -0
- cloudsmith_cli/cli/saml.py +109 -0
- cloudsmith_cli/cli/table.py +59 -0
- cloudsmith_cli/cli/types.py +14 -0
- cloudsmith_cli/cli/utils.py +267 -0
- cloudsmith_cli/cli/validators.py +378 -0
- cloudsmith_cli/cli/webserver.py +263 -0
- cloudsmith_cli/core/__init__.py +1 -0
- cloudsmith_cli/core/api/__init__.py +1 -0
- cloudsmith_cli/core/api/distros.py +31 -0
- cloudsmith_cli/core/api/entitlements.py +130 -0
- cloudsmith_cli/core/api/exceptions.py +57 -0
- cloudsmith_cli/core/api/files.py +131 -0
- cloudsmith_cli/core/api/init.py +109 -0
- cloudsmith_cli/core/api/metadata.py +217 -0
- cloudsmith_cli/core/api/metrics.py +78 -0
- cloudsmith_cli/core/api/orgs.py +201 -0
- cloudsmith_cli/core/api/packages.py +309 -0
- cloudsmith_cli/core/api/quota.py +64 -0
- cloudsmith_cli/core/api/rates.py +28 -0
- cloudsmith_cli/core/api/repos.py +81 -0
- cloudsmith_cli/core/api/status.py +27 -0
- cloudsmith_cli/core/api/upstreams.py +72 -0
- cloudsmith_cli/core/api/user.py +109 -0
- cloudsmith_cli/core/api/version.py +15 -0
- cloudsmith_cli/core/api/vulnerabilities.py +230 -0
- cloudsmith_cli/core/cache_utils.py +160 -0
- cloudsmith_cli/core/config.py +140 -0
- cloudsmith_cli/core/credentials/__init__.py +0 -0
- cloudsmith_cli/core/credentials/chain.py +69 -0
- cloudsmith_cli/core/credentials/models.py +44 -0
- cloudsmith_cli/core/credentials/oidc/__init__.py +6 -0
- cloudsmith_cli/core/credentials/oidc/cache.py +220 -0
- cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +122 -0
- cloudsmith_cli/core/credentials/oidc/detectors/aws.py +85 -0
- cloudsmith_cli/core/credentials/oidc/detectors/azure_devops.py +70 -0
- cloudsmith_cli/core/credentials/oidc/detectors/base.py +26 -0
- cloudsmith_cli/core/credentials/oidc/detectors/bitbucket_pipelines.py +35 -0
- cloudsmith_cli/core/credentials/oidc/detectors/circleci.py +40 -0
- cloudsmith_cli/core/credentials/oidc/detectors/generic.py +42 -0
- cloudsmith_cli/core/credentials/oidc/detectors/github_actions.py +64 -0
- cloudsmith_cli/core/credentials/oidc/detectors/gitlab_ci.py +49 -0
- cloudsmith_cli/core/credentials/oidc/exchange.py +87 -0
- cloudsmith_cli/core/credentials/provider.py +17 -0
- cloudsmith_cli/core/credentials/providers/__init__.py +15 -0
- cloudsmith_cli/core/credentials/providers/cli_flag.py +24 -0
- cloudsmith_cli/core/credentials/providers/credentials_file.py +24 -0
- cloudsmith_cli/core/credentials/providers/env_var.py +24 -0
- cloudsmith_cli/core/credentials/providers/keyring_provider.py +59 -0
- cloudsmith_cli/core/credentials/providers/oidc_provider.py +115 -0
- cloudsmith_cli/core/download.py +594 -0
- cloudsmith_cli/core/keyring.py +171 -0
- cloudsmith_cli/core/mcp/__init__.py +0 -0
- cloudsmith_cli/core/mcp/data.py +17 -0
- cloudsmith_cli/core/mcp/server.py +786 -0
- cloudsmith_cli/core/pagination.py +131 -0
- cloudsmith_cli/core/ratelimits.py +88 -0
- cloudsmith_cli/core/rest.py +255 -0
- cloudsmith_cli/core/utils.py +95 -0
- cloudsmith_cli/core/version.py +20 -0
- cloudsmith_cli/credential_helpers/__init__.py +7 -0
- cloudsmith_cli/credential_helpers/backends.py +41 -0
- cloudsmith_cli/credential_helpers/common.py +111 -0
- cloudsmith_cli/credential_helpers/custom_domains.py +281 -0
- cloudsmith_cli/credential_helpers/docker/__init__.py +4 -0
- cloudsmith_cli/credential_helpers/docker/installer.py +349 -0
- cloudsmith_cli/credential_helpers/docker/runtime.py +117 -0
- cloudsmith_cli/credential_helpers/launchers.py +175 -0
- cloudsmith_cli/data/VERSION +1 -0
- cloudsmith_cli/data/config.ini +23 -0
- cloudsmith_cli/data/credentials.ini +14 -0
- cloudsmith_cli/templates/__init__.py +3 -0
- cloudsmith_cli/templates/auth_error.html +45 -0
- cloudsmith_cli/templates/auth_success.html +37 -0
- cloudsmith_cli-1.20.0.dist-info/METADATA +610 -0
- cloudsmith_cli-1.20.0.dist-info/RECORD +130 -0
- cloudsmith_cli-1.20.0.dist-info/WHEEL +5 -0
- cloudsmith_cli-1.20.0.dist-info/entry_points.txt +2 -0
- cloudsmith_cli-1.20.0.dist-info/licenses/LICENSE +201 -0
- 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
|
+
)
|