diff --git a/cloudsmith_cli/cli/commands/dependencies.py b/cloudsmith_cli/cli/commands/dependencies.py index b9be2131..1ac86644 100644 --- a/cloudsmith_cli/cli/commands/dependencies.py +++ b/cloudsmith_cli/cli/commands/dependencies.py @@ -74,16 +74,15 @@ def list_dependencies(ctx, opts, owner_repo_package): return headers = ["Type", "Name", "Operator", "Version"] - rows = [] - for dep in deps: - rows.append( - [ - click.style(dep["dep_type"], fg="cyan"), - click.style(dep["name"], fg="yellow"), - click.style(dep["operator"], fg="magenta"), - click.style(dep["version"] or "", fg="green"), - ] - ) + rows = [ + [ + click.style(dep["dep_type"], fg="cyan"), + click.style(dep["name"], fg="yellow"), + click.style(dep["operator"], fg="magenta"), + click.style(dep["version"] or "", fg="green"), + ] + for dep in deps + ] if deps: click.echo() diff --git a/cloudsmith_cli/cli/commands/download.py b/cloudsmith_cli/cli/commands/download.py index 1df1ee4a..5cbdedb1 100644 --- a/cloudsmith_cli/cli/commands/download.py +++ b/cloudsmith_cli/cli/commands/download.py @@ -334,22 +334,20 @@ def _resolve_all_files_items( f"Output path '{output_dir}' exists but is not a directory." ) - items = [] - for f in sub_files: - items.append( - { - "filename": f["filename"], - "url": f["cdn_url"], - "output_path": _safe_join(output_dir, f["filename"]), - "tag": f.get("tag", "file"), - "is_primary": f.get("is_primary", False), - "size": f.get("size", 0), - "package_name": pkg_name, - "package_version": pkg_version, - "status": None, - } - ) - return items + return [ + { + "filename": f["filename"], + "url": f["cdn_url"], + "output_path": _safe_join(output_dir, f["filename"]), + "tag": f.get("tag", "file"), + "is_primary": f.get("is_primary", False), + "size": f.get("size", 0), + "package_name": pkg_name, + "package_version": pkg_version, + "status": None, + } + for f in sub_files + ] def _resolve_single_file_item( diff --git a/cloudsmith_cli/cli/commands/list_.py b/cloudsmith_cli/cli/commands/list_.py index 692d4f76..2277f46a 100644 --- a/cloudsmith_cli/cli/commands/list_.py +++ b/cloudsmith_cli/cli/commands/list_.py @@ -239,20 +239,19 @@ def packages(ctx, opts, owner_repo, page, page_size, query, sort, page_all): return headers = ["Name", "Version", "Status", "Owner / Repository (Identifier)"] - rows = [] - for package in sorted(packages_, key=itemgetter("namespace", "slug")): - rows.append( - [ - click.style(_get_package_name(package), fg="cyan"), - click.style(_get_package_version(package), fg="yellow"), - click.style(_get_package_status(package), fg="blue"), - "{owner_slug}/{repo_slug}/{slug}".format( - owner_slug=click.style(package["namespace"], fg="magenta"), - repo_slug=click.style(package["repository"], fg="magenta"), - slug=click.style(package["slug"], fg="green"), - ), - ] - ) + rows = [ + [ + click.style(_get_package_name(package), fg="cyan"), + click.style(_get_package_version(package), fg="yellow"), + click.style(_get_package_status(package), fg="blue"), + "{owner_slug}/{repo_slug}/{slug}".format( + owner_slug=click.style(package["namespace"], fg="magenta"), + repo_slug=click.style(package["repository"], fg="magenta"), + slug=click.style(package["slug"], fg="green"), + ), + ] + for package in sorted(packages_, key=itemgetter("namespace", "slug")) + ] if packages_: click.echo() diff --git a/cloudsmith_cli/cli/commands/repos.py b/cloudsmith_cli/cli/commands/repos.py index de3a3b89..4308abda 100644 --- a/cloudsmith_cli/cli/commands/repos.py +++ b/cloudsmith_cli/cli/commands/repos.py @@ -25,22 +25,21 @@ def print_repositories(opts, data, page_info=None, show_list_info=True, page_all "Owner / Repository (Identifier)", ] - rows = [] - for repo in sorted(data, key=itemgetter("namespace", "slug")): - rows.append( - [ - click.style(repo["name"], fg="cyan"), - click.style(repo["repository_type_str"], fg="yellow"), - click.style(str(repo["package_count"]), fg="blue"), - click.style(str(repo["package_group_count"]), fg="blue"), - click.style(str(repo["num_downloads"]), fg="blue"), - click.style(str(repo["size_str"]), fg="blue"), - "{owner_slug}/{slug}".format( - owner_slug=click.style(repo["namespace"], fg="magenta"), - slug=click.style(repo["slug"], fg="green"), - ), - ] - ) + rows = [ + [ + click.style(repo["name"], fg="cyan"), + click.style(repo["repository_type_str"], fg="yellow"), + click.style(str(repo["package_count"]), fg="blue"), + click.style(str(repo["package_group_count"]), fg="blue"), + click.style(str(repo["num_downloads"]), fg="blue"), + click.style(str(repo["size_str"]), fg="blue"), + "{owner_slug}/{slug}".format( + owner_slug=click.style(repo["namespace"], fg="magenta"), + slug=click.style(repo["slug"], fg="green"), + ), + ] + for repo in sorted(data, key=itemgetter("namespace", "slug")) + ] if data: click.echo() diff --git a/cloudsmith_cli/cli/config.py b/cloudsmith_cli/cli/config.py index e623e421..c0b0b96f 100644 --- a/cloudsmith_cli/cli/config.py +++ b/cloudsmith_cli/cli/config.py @@ -29,11 +29,11 @@ def parse(self, text): def get_error_hint(self, ctx): if self.ctx: - files = [] - for path in self.ctx.config_searchpath: - for filename in self.ctx.config_files: - files.append(os.path.join(path, filename)) - files = " or ".join(files) + files = " or ".join( + os.path.join(path, filename) + for path in self.ctx.config_searchpath + for filename in self.ctx.config_files + ) msg = f"{self.name} in {files}" else: msg = f"{self.name} in a config file" diff --git a/cloudsmith_cli/cli/table.py b/cloudsmith_cli/cli/table.py index f077181b..b9d74f7c 100644 --- a/cloudsmith_cli/cli/table.py +++ b/cloudsmith_cli/cli/table.py @@ -22,7 +22,7 @@ def make_table(headers=None, rows=None): assert all(len(row) == len(headers) for row in rows) plain_headers = [strip_ansi(str(v)) for v in headers] - plain_rows = [row for row in [strip_ansi(str(v)) for v in rows]] + plain_rows = [strip_ansi(str(v)) for v in rows] plain_headers = [] column_widths = [] diff --git a/cloudsmith_cli/core/api/packages.py b/cloudsmith_cli/core/api/packages.py index 0b6209e6..aa0ff64b 100644 --- a/cloudsmith_cli/core/api/packages.py +++ b/cloudsmith_cli/core/api/packages.py @@ -18,13 +18,8 @@ def get_packages_api(): def make_create_payload(**kwargs): """Create payload for upload/check-upload operations.""" - payload = {} # Add non-empty arguments - for k, v in kwargs.items(): - if v is not None: - payload[k] = v - - return payload + return {k: v for k, v in kwargs.items() if v is not None} def create_package(package_format, owner, repo, **kwargs): @@ -266,7 +261,7 @@ def get_parameters(cls): # Create a dummy instance so we can check if a parameter is required. # As with the rest of this function, this is obviously hacky. We'll # figure out a way to pull this information in from the API later. - dummy_kwargs = {k: "dummy" for k in cls.swagger_types} + dummy_kwargs = dict.fromkeys(cls.swagger_types, "dummy") instance = cls(**dummy_kwargs) for k, v in cls.swagger_types.items(): diff --git a/cloudsmith_cli/core/api/vulnerabilities.py b/cloudsmith_cli/core/api/vulnerabilities.py index c755b1f6..bab4db13 100644 --- a/cloudsmith_cli/core/api/vulnerabilities.py +++ b/cloudsmith_cli/core/api/vulnerabilities.py @@ -30,8 +30,9 @@ def _print_vulnerabilities_summary_table(data, severity_filter, total_filtered_v severity_keys = {k: v for k, v in severity_keys.items() if v in allowed} headers = [{"header": "Package", "justify": "left", "style": "cyan"}] - for key in severity_keys: - headers.append({"header": key, "justify": "center", "style": "white"}) + headers.extend( + {"header": key, "justify": "center", "style": "white"} for key in severity_keys + ) # Get package name and version for the target label pkg_data = getattr(data, "package", None) @@ -40,7 +41,7 @@ def _print_vulnerabilities_summary_table(data, severity_filter, total_filtered_v target_label = f"{pkg_name}:{pkg_version}" # Initialize aggregate counts - counts = {v: 0 for v in severity_keys.values()} + counts = dict.fromkeys(severity_keys.values(), 0) # Parse the scans and aggregate results scans = getattr(data, "scans", []) @@ -55,8 +56,7 @@ def _print_vulnerabilities_summary_table(data, severity_filter, total_filtered_v # Create the single summary row row = [target_label] - for key in severity_keys.values(): - row.append(str(counts[key])) + row.extend(str(counts[key]) for key in severity_keys.values()) rows = [row] diff --git a/cloudsmith_cli/core/download.py b/cloudsmith_cli/core/download.py index 5bc49f54..344ae75d 100644 --- a/cloudsmith_cli/core/download.py +++ b/cloudsmith_cli/core/download.py @@ -375,12 +375,11 @@ def get_package_files(package: dict) -> list[dict]: ] # Filter to only downloadable files with CDN URLs - downloadable_files = [] - for file_info in files: - if file_info.get("is_downloadable") and file_info.get("cdn_url"): - downloadable_files.append(file_info) - - return downloadable_files + return [ + file_info + for file_info in files + if file_info.get("is_downloadable") and file_info.get("cdn_url") + ] def get_package_detail(owner: str, repo: str, identifier: str) -> dict: diff --git a/cloudsmith_cli/credential_helpers/docker/installer.py b/cloudsmith_cli/credential_helpers/docker/installer.py index 4431a76d..cf25b744 100644 --- a/cloudsmith_cli/credential_helpers/docker/installer.py +++ b/cloudsmith_cli/credential_helpers/docker/installer.py @@ -217,10 +217,10 @@ def mutate(config: dict) -> None: changed = merge_json_file(config_path, mutate) if changed: - for host in hosts: - actions.append( - f"set credHelpers[{host!r}]={self.HELPER_VALUE!r} in {config_path}" - ) + actions.extend( + f"set credHelpers[{host!r}]={self.HELPER_VALUE!r} in {config_path}" + for host in hosts + ) else: actions.append(f"config.json already up to date ({config_path})") diff --git a/packaging/pyinstaller/entry.py b/packaging/pyinstaller/entry.py index 0c04a90d..3fe887c3 100644 --- a/packaging/pyinstaller/entry.py +++ b/packaging/pyinstaller/entry.py @@ -40,9 +40,11 @@ class list explicitly instead of relying on an import error. import keyring.backend discovered = [type(b).__module__ for b in keyring.backend.get_all_keyring()] - for module_prefix in ("keyrings.cryptfile", "keyrings.alt"): - if not any(name.startswith(module_prefix) for name in discovered): - failed.append(f"{module_prefix}: not discovered via entry points") + failed.extend( + f"{module_prefix}: not discovered via entry points" + for module_prefix in ("keyrings.cryptfile", "keyrings.alt") + if not any(name.startswith(module_prefix) for name in discovered) + ) def _selftest() -> int: diff --git a/pyproject.toml b/pyproject.toml index 76289af2..86fe4aee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -142,8 +142,8 @@ show_missing = true directory = "reports/coverage" [tool.ruff.lint] -extend-select = ["FA", "TC", "TID253"] -ignore = ["TRY002", "BLE001"] +extend-select = ["C4", "FA", "PERF", "TC", "TID253"] +ignore = ["TRY002", "BLE001", "PERF203"] [tool.ruff.lint.flake8-tidy-imports] # These modules dominate CLI startup time. Import them inside functions,