cloudsmith-cli 1.10.2__py2.py3-none-any.whl → 1.10.4__py2.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/cli/command.py +66 -0
- cloudsmith_cli/cli/commands/auth.py +25 -12
- cloudsmith_cli/cli/commands/check.py +18 -4
- cloudsmith_cli/cli/commands/copy.py +8 -2
- cloudsmith_cli/cli/commands/delete.py +9 -3
- cloudsmith_cli/cli/commands/dependencies.py +1 -1
- cloudsmith_cli/cli/commands/download.py +89 -8
- cloudsmith_cli/cli/commands/entitlements.py +11 -7
- cloudsmith_cli/cli/commands/list_.py +2 -2
- cloudsmith_cli/cli/commands/login.py +21 -13
- cloudsmith_cli/cli/commands/metrics/entitlements.py +2 -2
- cloudsmith_cli/cli/commands/metrics/packages.py +1 -1
- cloudsmith_cli/cli/commands/move.py +10 -3
- cloudsmith_cli/cli/commands/policy/deny.py +8 -6
- cloudsmith_cli/cli/commands/policy/license.py +5 -3
- cloudsmith_cli/cli/commands/policy/vulnerability.py +6 -3
- cloudsmith_cli/cli/commands/push.py +146 -64
- cloudsmith_cli/cli/commands/quarantine.py +7 -4
- cloudsmith_cli/cli/commands/quota/history.py +1 -1
- cloudsmith_cli/cli/commands/quota/quota.py +1 -1
- cloudsmith_cli/cli/commands/repos.py +5 -3
- cloudsmith_cli/cli/commands/resync.py +7 -2
- cloudsmith_cli/cli/commands/status.py +21 -3
- cloudsmith_cli/cli/commands/tags.py +20 -5
- cloudsmith_cli/cli/commands/tokens.py +37 -25
- cloudsmith_cli/cli/commands/upstream.py +2 -3
- cloudsmith_cli/cli/commands/whoami.py +4 -5
- cloudsmith_cli/cli/exceptions.py +86 -49
- cloudsmith_cli/cli/utils.py +17 -2
- cloudsmith_cli/cli/webserver.py +1 -1
- cloudsmith_cli/data/VERSION +1 -1
- {cloudsmith_cli-1.10.2.dist-info → cloudsmith_cli-1.10.4.dist-info}/METADATA +1 -1
- {cloudsmith_cli-1.10.2.dist-info → cloudsmith_cli-1.10.4.dist-info}/RECORD +37 -37
- {cloudsmith_cli-1.10.2.dist-info → cloudsmith_cli-1.10.4.dist-info}/WHEEL +0 -0
- {cloudsmith_cli-1.10.2.dist-info → cloudsmith_cli-1.10.4.dist-info}/entry_points.txt +0 -0
- {cloudsmith_cli-1.10.2.dist-info → cloudsmith_cli-1.10.4.dist-info}/licenses/LICENSE +0 -0
- {cloudsmith_cli-1.10.2.dist-info → cloudsmith_cli-1.10.4.dist-info}/top_level.txt +0 -0
cloudsmith_cli/cli/command.py
CHANGED
|
@@ -6,6 +6,46 @@ import click.exceptions
|
|
|
6
6
|
from click_didyoumean import DYMGroup
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
def _is_json_output_requested(exception):
|
|
10
|
+
"""Determine if JSON output was requested, checking context and argv."""
|
|
11
|
+
# Check context if available
|
|
12
|
+
ctx = getattr(exception, "ctx", None)
|
|
13
|
+
if ctx and ctx.params:
|
|
14
|
+
fmt = ctx.params.get("output")
|
|
15
|
+
if fmt in ("json", "pretty_json"):
|
|
16
|
+
return True
|
|
17
|
+
|
|
18
|
+
# Fallback: check sys.argv for output format flags
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
argv = sys.argv
|
|
22
|
+
|
|
23
|
+
if "--output-format=json" in argv or "--output-format=pretty_json" in argv:
|
|
24
|
+
return True
|
|
25
|
+
|
|
26
|
+
for idx, arg in enumerate(argv):
|
|
27
|
+
if arg in ("-F", "--output-format") and idx + 1 < len(argv):
|
|
28
|
+
if argv[idx + 1] in ("json", "pretty_json"):
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _format_click_exception_as_json(exception):
|
|
35
|
+
"""Format a ClickException as a JSON error dict."""
|
|
36
|
+
return {
|
|
37
|
+
"detail": exception.format_message(),
|
|
38
|
+
"meta": {
|
|
39
|
+
"code": exception.exit_code,
|
|
40
|
+
"description": "Usage Error",
|
|
41
|
+
},
|
|
42
|
+
"help": {
|
|
43
|
+
"context": "Invalid usage",
|
|
44
|
+
"hint": "Check your command arguments/flags.",
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
9
49
|
class AliasGroup(DYMGroup):
|
|
10
50
|
"""A command group with DYM and alias support."""
|
|
11
51
|
|
|
@@ -92,3 +132,29 @@ class AliasGroup(DYMGroup):
|
|
|
92
132
|
def format_commands(self, ctx, formatter):
|
|
93
133
|
ctx.showing_help = True
|
|
94
134
|
return super().format_commands(ctx, formatter)
|
|
135
|
+
|
|
136
|
+
def main(self, *args, **kwargs):
|
|
137
|
+
"""Override main to intercept exceptions and format as JSON if requested."""
|
|
138
|
+
import sys
|
|
139
|
+
|
|
140
|
+
original_standalone_mode = kwargs.get("standalone_mode", True)
|
|
141
|
+
kwargs["standalone_mode"] = False
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
return super().main(*args, **kwargs)
|
|
145
|
+
except click.exceptions.Abort:
|
|
146
|
+
if not original_standalone_mode:
|
|
147
|
+
raise
|
|
148
|
+
click.echo("Aborted!", err=True)
|
|
149
|
+
sys.exit(1)
|
|
150
|
+
except click.exceptions.ClickException as e:
|
|
151
|
+
if _is_json_output_requested(e):
|
|
152
|
+
import json
|
|
153
|
+
|
|
154
|
+
click.echo(json.dumps(_format_click_exception_as_json(e), indent=4))
|
|
155
|
+
sys.exit(e.exit_code)
|
|
156
|
+
|
|
157
|
+
if not original_standalone_mode:
|
|
158
|
+
raise
|
|
159
|
+
e.show()
|
|
160
|
+
sys.exit(e.exit_code)
|
|
@@ -4,7 +4,7 @@ import webbrowser
|
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
|
-
from .. import decorators, validators
|
|
7
|
+
from .. import decorators, utils, validators
|
|
8
8
|
from ..exceptions import handle_api_exceptions
|
|
9
9
|
from ..saml import create_configured_session, get_idp_url
|
|
10
10
|
from ..webserver import AuthenticationWebRequestHandler, AuthenticationWebServer
|
|
@@ -22,14 +22,15 @@ def _perform_saml_authentication(opts, owner, enable_token_creation=False, json=
|
|
|
22
22
|
api_host = opts.api_config.host
|
|
23
23
|
|
|
24
24
|
idp_url = get_idp_url(api_host, owner, session=session)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
|
|
26
|
+
click.echo(
|
|
27
|
+
f"Opening your organization's SAML IDP URL in your browser: {click.style(idp_url, bold=True)}",
|
|
28
|
+
err=json,
|
|
29
|
+
)
|
|
30
|
+
click.echo(err=json)
|
|
30
31
|
webbrowser.open(idp_url)
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
click.echo("Starting webserver to begin authentication ... ", err=json)
|
|
33
34
|
|
|
34
35
|
auth_server = AuthenticationWebServer(
|
|
35
36
|
(AUTH_SERVER_HOST, AUTH_SERVER_PORT),
|
|
@@ -86,13 +87,25 @@ def _perform_saml_authentication(opts, owner, enable_token_creation=False, json=
|
|
|
86
87
|
@click.pass_context
|
|
87
88
|
def authenticate(ctx, opts, owner, token, force, save_config, json):
|
|
88
89
|
"""Authenticate to Cloudsmith using the org's SAML setup."""
|
|
89
|
-
|
|
90
|
+
json = json or utils.should_use_stderr(opts)
|
|
91
|
+
# If using json output, we redirect info messages to stderr
|
|
92
|
+
use_stderr = json
|
|
90
93
|
|
|
91
|
-
if not
|
|
92
|
-
click.
|
|
93
|
-
|
|
94
|
+
if json and not utils.should_use_stderr(opts):
|
|
95
|
+
click.secho(
|
|
96
|
+
"DEPRECATION WARNING: The `--json` flag is deprecated and will be removed in a future release. "
|
|
97
|
+
"Please use `--output-format json` instead.",
|
|
98
|
+
fg="yellow",
|
|
99
|
+
err=True,
|
|
94
100
|
)
|
|
95
101
|
|
|
102
|
+
owner = owner[0].strip("'[]'")
|
|
103
|
+
|
|
104
|
+
click.echo(
|
|
105
|
+
f"Beginning authentication for the {click.style(owner, bold=True)} org ... ",
|
|
106
|
+
err=use_stderr,
|
|
107
|
+
)
|
|
108
|
+
|
|
96
109
|
context_message = "Failed to authenticate via SSO!"
|
|
97
110
|
with handle_api_exceptions(ctx, opts=opts, context_msg=context_message):
|
|
98
111
|
_perform_saml_authentication(
|
|
@@ -29,14 +29,18 @@ def check(ctx, opts): # pylint: disable=unused-argument
|
|
|
29
29
|
@click.pass_context
|
|
30
30
|
def rates(ctx, opts):
|
|
31
31
|
"""Check current API rate limits."""
|
|
32
|
-
|
|
32
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
33
|
+
click.echo("Retrieving rate limits ... ", nl=False, err=use_stderr)
|
|
33
34
|
|
|
34
35
|
context_msg = "Failed to retrieve status!"
|
|
35
36
|
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
|
|
36
37
|
with maybe_spinner(opts):
|
|
37
38
|
resources_limits = get_rate_limits()
|
|
38
39
|
|
|
39
|
-
click.secho("OK", fg="green")
|
|
40
|
+
click.secho("OK", fg="green", err=use_stderr)
|
|
41
|
+
|
|
42
|
+
if utils.maybe_print_as_json(opts, resources_limits):
|
|
43
|
+
return
|
|
40
44
|
|
|
41
45
|
headers = ["Resource", "Throttled", "Remaining", "Interval (Seconds)", "Reset"]
|
|
42
46
|
|
|
@@ -77,17 +81,27 @@ def rates(ctx, opts):
|
|
|
77
81
|
@click.pass_context
|
|
78
82
|
def service(ctx, opts):
|
|
79
83
|
"""Check the status of the Cloudsmith service."""
|
|
80
|
-
|
|
84
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
85
|
+
click.echo("Retrieving service status ... ", nl=False, err=use_stderr)
|
|
81
86
|
|
|
82
87
|
context_msg = "Failed to retrieve status!"
|
|
83
88
|
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
|
|
84
89
|
with maybe_spinner(opts):
|
|
85
90
|
status, version = get_status(with_version=True)
|
|
86
91
|
|
|
87
|
-
click.secho("OK", fg="green")
|
|
92
|
+
click.secho("OK", fg="green", err=use_stderr)
|
|
88
93
|
|
|
89
94
|
config = cloudsmith_api.Configuration()
|
|
90
95
|
|
|
96
|
+
data = {
|
|
97
|
+
"endpoint": config.host,
|
|
98
|
+
"status": status,
|
|
99
|
+
"version": version,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if utils.maybe_print_as_json(opts, data):
|
|
103
|
+
return
|
|
104
|
+
|
|
91
105
|
click.echo()
|
|
92
106
|
click.echo(f"The service endpoint is: {click.style(config.host, bold=True)}")
|
|
93
107
|
click.echo(f"The service status is: {click.style(status, bold=True)}")
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import click
|
|
4
4
|
|
|
5
5
|
from ...core.api.packages import copy_package
|
|
6
|
-
from .. import decorators, validators
|
|
6
|
+
from .. import decorators, utils, validators
|
|
7
7
|
from ..exceptions import handle_api_exceptions
|
|
8
8
|
from ..utils import maybe_spinner
|
|
9
9
|
from .main import main
|
|
@@ -56,6 +56,8 @@ def copy(
|
|
|
56
56
|
"""
|
|
57
57
|
owner, source, slug = owner_repo_package
|
|
58
58
|
|
|
59
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
60
|
+
|
|
59
61
|
click.echo(
|
|
60
62
|
"Copying %(slug)s package from %(source)s to %(dest)s ... "
|
|
61
63
|
% {
|
|
@@ -64,6 +66,7 @@ def copy(
|
|
|
64
66
|
"dest": click.style(destination, bold=True),
|
|
65
67
|
},
|
|
66
68
|
nl=False,
|
|
69
|
+
err=use_stderr,
|
|
67
70
|
)
|
|
68
71
|
|
|
69
72
|
context_msg = "Failed to copy package!"
|
|
@@ -75,9 +78,10 @@ def copy(
|
|
|
75
78
|
owner=owner, repo=source, identifier=slug, destination=destination
|
|
76
79
|
)
|
|
77
80
|
|
|
78
|
-
click.secho("OK", fg="green")
|
|
81
|
+
click.secho("OK", fg="green", err=use_stderr)
|
|
79
82
|
|
|
80
83
|
if no_wait_for_sync:
|
|
84
|
+
utils.maybe_print_status_json(opts, {"slug": new_slug, "status": "OK"})
|
|
81
85
|
return
|
|
82
86
|
|
|
83
87
|
wait_for_package_sync(
|
|
@@ -90,3 +94,5 @@ def copy(
|
|
|
90
94
|
skip_errors=skip_errors,
|
|
91
95
|
attempts=sync_attempts,
|
|
92
96
|
)
|
|
97
|
+
|
|
98
|
+
utils.maybe_print_status_json(opts, {"slug": new_slug, "status": "OK"})
|
|
@@ -45,12 +45,16 @@ def delete(ctx, opts, owner_repo_package, yes):
|
|
|
45
45
|
"package": click.style(slug, bold=True),
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
49
|
+
|
|
48
50
|
prompt = "delete the %(package)s from %(owner)s/%(repo)s" % delete_args
|
|
49
|
-
if not utils.confirm_operation(prompt, assume_yes=yes):
|
|
51
|
+
if not utils.confirm_operation(prompt, assume_yes=yes, err=use_stderr):
|
|
50
52
|
return
|
|
51
53
|
|
|
52
54
|
click.echo(
|
|
53
|
-
"Deleting %(package)s from %(owner)s/%(repo)s ... " % delete_args,
|
|
55
|
+
"Deleting %(package)s from %(owner)s/%(repo)s ... " % delete_args,
|
|
56
|
+
nl=False,
|
|
57
|
+
err=use_stderr,
|
|
54
58
|
)
|
|
55
59
|
|
|
56
60
|
context_msg = "Failed to delete the package!"
|
|
@@ -58,4 +62,6 @@ def delete(ctx, opts, owner_repo_package, yes):
|
|
|
58
62
|
with maybe_spinner(opts):
|
|
59
63
|
delete_package(owner=owner, repo=repo, identifier=slug)
|
|
60
64
|
|
|
61
|
-
click.secho("OK", fg="green")
|
|
65
|
+
click.secho("OK", fg="green", err=use_stderr)
|
|
66
|
+
|
|
67
|
+
utils.maybe_print_status_json(opts, {"slug": slug, "status": "OK"})
|
|
@@ -50,7 +50,7 @@ def list_dependencies(ctx, opts, owner_repo_package):
|
|
|
50
50
|
owner, repo, identifier = owner_repo_package
|
|
51
51
|
|
|
52
52
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
53
|
-
use_stderr = opts
|
|
53
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
54
54
|
|
|
55
55
|
click.echo(
|
|
56
56
|
"Getting direct (non-transitive) dependencies of %(package)s in "
|
|
@@ -12,7 +12,7 @@ from ...core.download import (
|
|
|
12
12
|
resolve_package,
|
|
13
13
|
stream_download,
|
|
14
14
|
)
|
|
15
|
-
from .. import decorators, validators
|
|
15
|
+
from .. import decorators, utils, validators
|
|
16
16
|
from ..exceptions import handle_api_exceptions
|
|
17
17
|
from ..utils import maybe_spinner
|
|
18
18
|
from .main import main
|
|
@@ -124,7 +124,7 @@ def download( # noqa: C901
|
|
|
124
124
|
owner, repo = owner_repo
|
|
125
125
|
|
|
126
126
|
# Use stderr for messages if output is JSON
|
|
127
|
-
use_stderr = opts
|
|
127
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
128
128
|
|
|
129
129
|
if not use_stderr:
|
|
130
130
|
click.echo(
|
|
@@ -213,11 +213,13 @@ def download( # noqa: C901
|
|
|
213
213
|
return
|
|
214
214
|
|
|
215
215
|
# Download all files
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
if not use_stderr:
|
|
217
|
+
click.echo(f"\nDownloading {len(files_to_download)} files to: {output_dir}")
|
|
218
|
+
click.echo()
|
|
218
219
|
|
|
219
220
|
success_count = 0
|
|
220
221
|
failed_files = []
|
|
222
|
+
downloaded_files = []
|
|
221
223
|
|
|
222
224
|
for idx, file_info in enumerate(files_to_download, 1):
|
|
223
225
|
filename = file_info["filename"]
|
|
@@ -232,6 +234,12 @@ def download( # noqa: C901
|
|
|
232
234
|
f"[{idx}/{len(files_to_download)}] [{tag}] {filename}{primary_marker} ...",
|
|
233
235
|
nl=False,
|
|
234
236
|
)
|
|
237
|
+
else:
|
|
238
|
+
click.echo(
|
|
239
|
+
f"[{idx}/{len(files_to_download)}] [{tag}] {filename}{primary_marker} ...",
|
|
240
|
+
nl=False,
|
|
241
|
+
err=True,
|
|
242
|
+
)
|
|
235
243
|
|
|
236
244
|
try:
|
|
237
245
|
context_msg = f"Failed to download {filename}!"
|
|
@@ -246,11 +254,56 @@ def download( # noqa: C901
|
|
|
246
254
|
)
|
|
247
255
|
if not use_stderr:
|
|
248
256
|
click.secho(" OK", fg="green")
|
|
257
|
+
else:
|
|
258
|
+
click.echo(" OK", err=True)
|
|
249
259
|
success_count += 1
|
|
260
|
+
downloaded_files.append(
|
|
261
|
+
{
|
|
262
|
+
"filename": filename,
|
|
263
|
+
"path": output_path,
|
|
264
|
+
"tag": tag,
|
|
265
|
+
"is_primary": file_info.get("is_primary", False),
|
|
266
|
+
"size": file_info.get("size", 0),
|
|
267
|
+
"status": "OK",
|
|
268
|
+
}
|
|
269
|
+
)
|
|
250
270
|
except Exception as e: # pylint: disable=broad-except
|
|
251
271
|
if not use_stderr:
|
|
252
272
|
click.secho(" FAILED", fg="red")
|
|
273
|
+
else:
|
|
274
|
+
click.echo(" FAILED", err=True)
|
|
253
275
|
failed_files.append((filename, str(e)))
|
|
276
|
+
downloaded_files.append(
|
|
277
|
+
{
|
|
278
|
+
"filename": filename,
|
|
279
|
+
"path": output_path,
|
|
280
|
+
"tag": tag,
|
|
281
|
+
"is_primary": file_info.get("is_primary", False),
|
|
282
|
+
"size": file_info.get("size", 0),
|
|
283
|
+
"status": "FAILED",
|
|
284
|
+
"error": str(e),
|
|
285
|
+
}
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Build JSON output for all-files download
|
|
289
|
+
json_output = {
|
|
290
|
+
"package": {
|
|
291
|
+
"name": package.get("name"),
|
|
292
|
+
"version": package.get("version"),
|
|
293
|
+
"format": package.get("format"),
|
|
294
|
+
"slug": package.get("slug"),
|
|
295
|
+
},
|
|
296
|
+
"output_directory": output_dir,
|
|
297
|
+
"files": downloaded_files,
|
|
298
|
+
"summary": {
|
|
299
|
+
"total": len(files_to_download),
|
|
300
|
+
"success": success_count,
|
|
301
|
+
"failed": len(failed_files),
|
|
302
|
+
},
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if utils.maybe_print_as_json(opts, json_output):
|
|
306
|
+
return
|
|
254
307
|
|
|
255
308
|
click.echo()
|
|
256
309
|
if success_count == len(files_to_download):
|
|
@@ -321,12 +374,40 @@ def download( # noqa: C901
|
|
|
321
374
|
session=session,
|
|
322
375
|
headers=auth_headers,
|
|
323
376
|
overwrite=overwrite,
|
|
324
|
-
quiet=opts
|
|
377
|
+
quiet=utils.should_use_stderr(opts),
|
|
325
378
|
)
|
|
326
379
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
380
|
+
# Build JSON output for single-file download
|
|
381
|
+
json_output = {
|
|
382
|
+
"package": {
|
|
383
|
+
"name": package.get("name"),
|
|
384
|
+
"version": package.get("version"),
|
|
385
|
+
"format": package.get("format"),
|
|
386
|
+
"slug": package.get("slug"),
|
|
387
|
+
},
|
|
388
|
+
"output_directory": os.path.dirname(outfile),
|
|
389
|
+
"files": [
|
|
390
|
+
{
|
|
391
|
+
"filename": os.path.basename(outfile),
|
|
392
|
+
"path": outfile,
|
|
393
|
+
"tag": "file",
|
|
394
|
+
"is_primary": True,
|
|
395
|
+
"size": package.get("size", 0),
|
|
396
|
+
"status": "OK",
|
|
397
|
+
}
|
|
398
|
+
],
|
|
399
|
+
"summary": {
|
|
400
|
+
"total": 1,
|
|
401
|
+
"success": 1,
|
|
402
|
+
"failed": 0,
|
|
403
|
+
},
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if utils.maybe_print_as_json(opts, json_output):
|
|
407
|
+
return
|
|
408
|
+
|
|
409
|
+
click.echo()
|
|
410
|
+
click.secho("Download completed successfully!", fg="green")
|
|
330
411
|
|
|
331
412
|
|
|
332
413
|
def _get_extension_for_format(pkg_format: str) -> str:
|
|
@@ -89,7 +89,7 @@ def list_entitlements(ctx, opts, owner_repo, page, page_size, show_tokens, page_
|
|
|
89
89
|
owner, repo = owner_repo
|
|
90
90
|
|
|
91
91
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
92
|
-
use_stderr = opts
|
|
92
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
93
93
|
|
|
94
94
|
click.echo(
|
|
95
95
|
"Getting list of entitlements for the %(repository)s "
|
|
@@ -323,7 +323,7 @@ def create(ctx, opts, owner_repo, show_tokens, name, token):
|
|
|
323
323
|
owner, repo = owner_repo
|
|
324
324
|
|
|
325
325
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
326
|
-
use_stderr = opts
|
|
326
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
327
327
|
|
|
328
328
|
click.secho(
|
|
329
329
|
"Creating %(name)s entitlement for the %(repository)s "
|
|
@@ -391,13 +391,17 @@ def delete(ctx, opts, owner_repo_identifier, yes):
|
|
|
391
391
|
"delete the %(identifier)s entitlement from the %(repository)s "
|
|
392
392
|
"repository" % delete_args
|
|
393
393
|
)
|
|
394
|
-
|
|
394
|
+
|
|
395
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
396
|
+
|
|
397
|
+
if not utils.confirm_operation(prompt, assume_yes=yes, err=use_stderr):
|
|
395
398
|
return
|
|
396
399
|
|
|
397
400
|
click.secho(
|
|
398
401
|
"Deleting %(identifier)s entitlement from the %(repository)s "
|
|
399
402
|
"repository ... " % delete_args,
|
|
400
403
|
nl=False,
|
|
404
|
+
err=use_stderr,
|
|
401
405
|
)
|
|
402
406
|
|
|
403
407
|
context_msg = "Failed to delete the entitlement!"
|
|
@@ -454,7 +458,7 @@ def update(ctx, opts, owner_repo_identifier, show_tokens, name, token):
|
|
|
454
458
|
owner, repo, identifier = owner_repo_identifier
|
|
455
459
|
|
|
456
460
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
457
|
-
use_stderr = opts
|
|
461
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
458
462
|
|
|
459
463
|
click.secho(
|
|
460
464
|
"Updating %(identifier)s entitlement for the %(repository)s "
|
|
@@ -527,7 +531,7 @@ def refresh(ctx, opts, owner_repo_identifier, show_tokens, yes):
|
|
|
527
531
|
}
|
|
528
532
|
|
|
529
533
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
530
|
-
use_stderr = opts
|
|
534
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
531
535
|
|
|
532
536
|
prompt = (
|
|
533
537
|
"refresh the %(identifier)s entitlement for the %(repository)s "
|
|
@@ -603,7 +607,7 @@ def sync(ctx, opts, owner_repo, show_tokens, source, yes):
|
|
|
603
607
|
}
|
|
604
608
|
|
|
605
609
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
606
|
-
use_stderr = opts
|
|
610
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
607
611
|
|
|
608
612
|
if not yes:
|
|
609
613
|
click.secho(
|
|
@@ -768,7 +772,7 @@ def restrict(
|
|
|
768
772
|
owner, repo, identifier = owner_repo_identifier
|
|
769
773
|
|
|
770
774
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
771
|
-
use_stderr = opts
|
|
775
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
772
776
|
|
|
773
777
|
click.secho(
|
|
774
778
|
"Updating %(identifier)s entitlement for the %(repository)s "
|
|
@@ -53,7 +53,7 @@ def dependencies_(*args, **kwargs): # pylint: disable=missing-docstring
|
|
|
53
53
|
def distros(ctx, opts, package_format):
|
|
54
54
|
"""List available distributions."""
|
|
55
55
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
56
|
-
use_stderr = opts
|
|
56
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
57
57
|
|
|
58
58
|
if not use_stderr:
|
|
59
59
|
click.echo("Getting list of distributions ... ", nl=False, err=use_stderr)
|
|
@@ -210,7 +210,7 @@ def packages(ctx, opts, owner_repo, page, page_size, query, sort, page_all):
|
|
|
210
210
|
owner, repo = owner_repo
|
|
211
211
|
|
|
212
212
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
213
|
-
use_stderr = opts
|
|
213
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
214
214
|
|
|
215
215
|
if not use_stderr:
|
|
216
216
|
click.echo("Getting list of packages ... ", nl=False, err=use_stderr)
|
|
@@ -6,7 +6,7 @@ import cloudsmith_api
|
|
|
6
6
|
from ...core.api.exceptions import TwoFactorRequiredException
|
|
7
7
|
from ...core.api.user import get_user_token
|
|
8
8
|
from ...core.config import create_config_files, new_config_messaging
|
|
9
|
-
from .. import decorators
|
|
9
|
+
from .. import decorators, utils
|
|
10
10
|
from ..exceptions import handle_api_exceptions
|
|
11
11
|
from ..utils import maybe_spinner
|
|
12
12
|
from .main import main
|
|
@@ -37,10 +37,12 @@ def validate_login(ctx, param, value):
|
|
|
37
37
|
@click.pass_context
|
|
38
38
|
def login(ctx, opts, login, password): # pylint: disable=redefined-outer-name
|
|
39
39
|
"""Retrieve your API authentication token/key via login."""
|
|
40
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
40
41
|
click.echo(
|
|
41
42
|
"Retrieving API token for %(login)s ... "
|
|
42
43
|
% {"login": click.style(login, bold=True)},
|
|
43
44
|
nl=False,
|
|
45
|
+
err=use_stderr,
|
|
44
46
|
)
|
|
45
47
|
|
|
46
48
|
context_msg = "Failed to retrieve the API token!"
|
|
@@ -49,14 +51,17 @@ def login(ctx, opts, login, password): # pylint: disable=redefined-outer-name
|
|
|
49
51
|
with maybe_spinner(opts):
|
|
50
52
|
api_key = get_user_token(login=login, password=password)
|
|
51
53
|
except TwoFactorRequiredException as e:
|
|
52
|
-
click.echo("\r\033[K", nl=False)
|
|
53
|
-
click.echo("Two-factor authentication is required.")
|
|
54
|
+
click.echo("\r\033[K", nl=False, err=use_stderr)
|
|
55
|
+
click.echo("Two-factor authentication is required.", err=use_stderr)
|
|
54
56
|
|
|
55
|
-
totp_token = click.prompt(
|
|
57
|
+
totp_token = click.prompt(
|
|
58
|
+
"Enter your two-factor authentication code", type=str, err=use_stderr
|
|
59
|
+
)
|
|
56
60
|
click.echo(
|
|
57
61
|
"Verifying two-factor code for %(login)s ... "
|
|
58
62
|
% {"login": click.style(login, bold=True)},
|
|
59
63
|
nl=False,
|
|
64
|
+
err=use_stderr,
|
|
60
65
|
)
|
|
61
66
|
|
|
62
67
|
try:
|
|
@@ -69,23 +74,26 @@ def login(ctx, opts, login, password): # pylint: disable=redefined-outer-name
|
|
|
69
74
|
two_factor_token=e.two_factor_token,
|
|
70
75
|
)
|
|
71
76
|
except cloudsmith_api.rest.ApiException:
|
|
72
|
-
click.echo("\r\033[K", nl=False)
|
|
77
|
+
click.echo("\r\033[K", nl=False, err=use_stderr)
|
|
73
78
|
click.secho(
|
|
74
|
-
"Authentication failed: The entered TOTP token is not valid.",
|
|
79
|
+
"Authentication failed: The entered TOTP token is not valid.",
|
|
80
|
+
fg="red",
|
|
81
|
+
err=use_stderr,
|
|
75
82
|
)
|
|
76
83
|
ctx.exit(1)
|
|
77
84
|
|
|
78
85
|
except cloudsmith_api.rest.ApiException as e:
|
|
79
|
-
click.echo("\r\033[K", nl=False)
|
|
80
|
-
click.secho(f"Authentication failed: {str(e)}", fg="red")
|
|
86
|
+
click.echo("\r\033[K", nl=False, err=use_stderr)
|
|
87
|
+
click.secho(f"Authentication failed: {str(e)}", fg="red", err=use_stderr)
|
|
81
88
|
ctx.exit(1)
|
|
82
89
|
|
|
83
|
-
click.secho("OK", fg="green")
|
|
90
|
+
click.secho("OK", fg="green", err=use_stderr)
|
|
84
91
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
if not utils.maybe_print_as_json(opts, {"token": api_key, "login": login}):
|
|
93
|
+
click.echo(
|
|
94
|
+
"Your API key/token is: %(token)s"
|
|
95
|
+
% {"token": click.style(api_key, fg="magenta")}
|
|
96
|
+
)
|
|
89
97
|
|
|
90
98
|
create, has_errors = create_config_files(ctx, opts, api_key=api_key)
|
|
91
99
|
new_config_messaging(has_errors, opts, create, api_key=api_key)
|
|
@@ -109,8 +109,8 @@ def usage(ctx, opts, owner_repo, tokens, start, finish):
|
|
|
109
109
|
If REPO isn't specified, all repositories will be included from the
|
|
110
110
|
OWNER namespace.
|
|
111
111
|
"""
|
|
112
|
-
|
|
113
|
-
use_stderr = opts
|
|
112
|
+
|
|
113
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
114
114
|
|
|
115
115
|
click.echo("Getting usage metrics ... ", nl=False, err=use_stderr)
|
|
116
116
|
|
|
@@ -106,7 +106,7 @@ def usage(ctx, opts, owner_repo, packages, start, finish):
|
|
|
106
106
|
metrics for that namespace/repository combination.
|
|
107
107
|
"""
|
|
108
108
|
# Use stderr for messages if the output is something else (e.g. # JSON)
|
|
109
|
-
use_stderr = opts
|
|
109
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
110
110
|
|
|
111
111
|
click.echo("Getting usage metrics ... ", nl=False, err=use_stderr)
|
|
112
112
|
|
|
@@ -70,12 +70,16 @@ def move(
|
|
|
70
70
|
"dest": click.style(destination, bold=True),
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
74
|
+
|
|
73
75
|
prompt = "move the %(slug)s from %(source)s to %(dest)s" % move_args
|
|
74
|
-
if not utils.confirm_operation(prompt, assume_yes=yes):
|
|
76
|
+
if not utils.confirm_operation(prompt, assume_yes=yes, err=use_stderr):
|
|
75
77
|
return
|
|
76
78
|
|
|
77
79
|
click.echo(
|
|
78
|
-
"Moving %(slug)s package from %(source)s to %(dest)s ... " % move_args,
|
|
80
|
+
"Moving %(slug)s package from %(source)s to %(dest)s ... " % move_args,
|
|
81
|
+
nl=False,
|
|
82
|
+
err=use_stderr,
|
|
79
83
|
)
|
|
80
84
|
|
|
81
85
|
context_msg = "Failed to move package!"
|
|
@@ -87,9 +91,10 @@ def move(
|
|
|
87
91
|
owner=owner, repo=source, identifier=slug, destination=destination
|
|
88
92
|
)
|
|
89
93
|
|
|
90
|
-
click.secho("OK", fg="green")
|
|
94
|
+
click.secho("OK", fg="green", err=use_stderr)
|
|
91
95
|
|
|
92
96
|
if no_wait_for_sync:
|
|
97
|
+
utils.maybe_print_status_json(opts, {"slug": new_slug, "status": "OK"})
|
|
93
98
|
return
|
|
94
99
|
|
|
95
100
|
wait_for_package_sync(
|
|
@@ -102,3 +107,5 @@ def move(
|
|
|
102
107
|
skip_errors=skip_errors,
|
|
103
108
|
attempts=sync_attempts,
|
|
104
109
|
)
|
|
110
|
+
|
|
111
|
+
utils.maybe_print_status_json(opts, {"slug": new_slug, "status": "OK"})
|