Skip to content

Commit 9a989d0

Browse files
Fix deprecation warnings
1 parent 5a769f5 commit 9a989d0

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

cloudinary_cli/cli_group.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
CONTEXT_SETTINGS = dict(max_content_width=shutil.get_terminal_size()[0], terminal_width=shutil.get_terminal_size()[0])
1515

1616

17-
@click.group(context_settings=CONTEXT_SETTINGS)
17+
@click.group(context_settings=CONTEXT_SETTINGS, invoke_without_command=True)
1818
@click.help_option()
1919
@click.version_option(cli_version, prog_name="Cloudinary CLI",
2020
message=f"%(prog)s, version %(version)s\n"
@@ -24,10 +24,11 @@
2424
help="""Tell the CLI which account to run the command on by specifying an account environment variable."""
2525
)
2626
@click.option("-C", "--config_saved",
27-
help="""Tell the CLI which account to run the command on by specifying a saved configuration - see
27+
help="""Tell the CLI which account to run the command on by specifying a saved configuration - see
2828
`config` command.""")
2929
@click_log.simple_verbosity_option(logger)
30-
def cli(config, config_saved):
30+
@click.pass_context
31+
def cli(ctx, config, config_saved):
3132
if config:
3233
refresh_cloudinary_config(config)
3334
elif config_saved:
@@ -40,4 +41,9 @@ def cli(config, config_saved):
4041
if not is_valid_cloudinary_config():
4142
logger.warning("No Cloudinary configuration found.")
4243

44+
# If no subcommand was invoked, show help and exit with code 0
45+
if ctx.invoked_subcommand is None:
46+
click.echo(ctx.get_help())
47+
ctx.exit(0)
48+
4349
return True

cloudinary_cli/core/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from cloudinary_cli.core.utils import url, utils
99
from cloudinary_cli.core.overrides import resolve_command
1010

11-
setattr(click.MultiCommand, "resolve_command", resolve_command)
11+
setattr(click.Group, "resolve_command", resolve_command)
1212

1313
commands = [
1414
config,

cloudinary_cli/core/overrides.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
from click.parser import split_opt
21
from click.utils import make_str
32
from cloudinary import api, uploader
43
from cloudinary.uploader import upload as original_upload
54
from cloudinary.utils import cloudinary_url as original_cloudinary_url
5+
from cloudinary_cli.utils.utils import split_opt
66

77

88
# overrides click.MultiCommand.resolve_command
99
def resolve_command(self, ctx, args):
1010
# Patch the `resolve_command` function to enable simple commands (eg. cld resource)
1111
# Only core commands from API and modules are registered (eg. cld admin)
12+
13+
# Handle empty args (when CLI is invoked with no arguments)
14+
if not args:
15+
return None, None, []
16+
1217
cmd_name = make_str(args[0])
1318
original_cmd_name = cmd_name
1419

cloudinary_cli/modules/sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def _normalize_remote_file_names(self, remote_files, local_files):
300300

301301
def _local_candidates(self, candidate_path):
302302
filename, extension = path.splitext(candidate_path)
303-
r = re.compile(f"({candidate_path}|{filename} \(\d+\){extension})")
303+
r = re.compile(f"({candidate_path}|{filename} \\(\\d+\\){extension})")
304304
# sort local files by base name (without ext) for accurate results.
305305
return dict(sorted({f: self.local_files[f]["etag"] for f in filter(r.match, self.local_files.keys())}.items(),
306306
key=lambda f: path.splitext(f[0])[0]))

cloudinary_cli/utils/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,25 @@ def duplicate_values(items, value_key, key_of_interest=None):
379379
rev_multidict.setdefault(value[value_key], set()).add(value[key_of_interest] if key_of_interest is not None else key)
380380

381381
return {key: values for key, values in rev_multidict.items() if len(values) > 1}
382+
383+
384+
def split_opt(opt):
385+
"""
386+
Splits an option string into prefix and value parts.
387+
388+
This function replaces the deprecated click.parser.split_opt import.
389+
Returns a tuple of (prefix, value) where prefix is the option prefix
390+
(like '-' or '--') and value is the remaining part, or ('', opt)
391+
if it doesn't look like an option.
392+
393+
:param opt: The option string to parse.
394+
:type opt: str
395+
:return: Tuple of (prefix, value)
396+
:rtype: tuple
397+
"""
398+
first = opt[:1]
399+
if first.isalnum():
400+
return '', opt
401+
if opt[1:2] == first:
402+
return opt[:2], opt[2:]
403+
return first, opt[1:]

0 commit comments

Comments
 (0)