Skip to content

fix(ENG-15484): accept --color on click versions before 8.2 - #582

Merged
cloudsmith-iduffy merged 2 commits into
masterfrom
iduffy/fix-color-option-old-click
Nov 2, 2026
Merged

cloudsmith-iduffy merged 2 commits into
masterfrom
iduffy/fix-color-option-old-click

Conversation

@cloudsmith-iduffy

Copy link
Copy Markdown
Collaborator

Description

Sentry CLOUDSMITH-CLI-1W and CLOUDSMITH-CLI-1Y are crashes on 1.30.1 before any command runs:

  • 1W: TypeError: sequence item 0: expected str instance, ColorMode found (Linux, from --help)
  • 1Y: AttributeError: 'ColorMode' object has no attribute 'casefold' (Windows)

--color uses click.Choice(ColorMode). Click accepts an Enum in Choice only from 8.2. Older Click calls string methods on each choice, so every command fails, --help included. The click line numbers in the two events match click 8.1.7 (types.py:256, "|".join(self.choices)) and click 8.1.8 (types.py:289, .casefold()).

The CLI requires click>=8.2,!=8.3.0, and the 1.30.1 wheel declares it. pip still lets a later install of another package downgrade click, and it only prints a warning.

The choices are now the plain strings auto, always and never. The wrapper converts the chosen one to ColorMode. The help text and the usage error are the same as before.

Linear: ENG-15484 and ENG-15483 (duplicates). Fixes CLOUDSMITH-CLI-1W. Fixes CLOUDSMITH-CLI-1Y

Type of Change

  • Bug fix

Additional Notes

I ran the CLI from this branch against click 8.1.7, 8.1.8, 8.2.0 and 8.5.0:

PYTHONPATH=<click-src>:. python -m cloudsmith_cli whoami --help      # shows --color [auto|always|never]
PYTHONPATH=<click-src>:. python -m cloudsmith_cli check --color=bogus  # Invalid value for '--color': 'bogus' is not one of 'auto', 'always', 'never'.

On master, both commands fail with the Sentry errors on 8.1.7 and 8.1.8.

CI installs click 8.2 or later, so a test cannot run the old click. The new test checks the cause instead: every --color choice is a str. It also checks that --color NEVER turns colour off.

The tickets put the conversion in a Click callback. This PR converts in the wrapper, so ctx.params["color"] stays text. #511 writes ctx.params values into launcher scripts, and a ColorMode there is CLOUDSMITH-CLI-1F.

🤖 Generated with Claude Code

click.Choice accepts an Enum only from click 8.2. Older click calls
string methods on each choice, so every command, --help included,
stopped with TypeError or AttributeError. The choices are now text,
and the wrapper converts the chosen one to ColorMode.

Fixes CLOUDSMITH-CLI-1W
Fixes CLOUDSMITH-CLI-1Y

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings November 2, 2026 01:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues remain for the Click color-parsing compatibility fix.

No open issues 🎉

What changed in this PR

Fixes --color parsing crashes with Click versions before 8.2 while preserving string values in the Click context for credential-helper launcher settings.

Changes:

  • Uses plain-string color choices and converts the selected value to ColorMode inside the wrapper.
  • Adds regression coverage for string choices and case-insensitive --color NEVER handling.
  • Documents the compatibility fix in the changelog.
File Description
cloudsmith_cli/​cli/​tests/​test_decorators.py Tests string-based choices and disabling color with uppercase input.
cloudsmith_cli/​cli/​decorators.py Replaces enum choices with strings and defers enum conversion to the wrapper.
CHANGELOG.md Documents the fix for crashes with older Click versions.

Review effort: Balanced

@cloudsmith-iduffy

Copy link
Copy Markdown
Collaborator Author

@copilot resolve the merge conflicts in this pull request

…tion-old-click

# Conflicts:
#	CHANGELOG.md

Co-authored-by: cloudsmith-iduffy <178375997+cloudsmith-iduffy@users.noreply.github.com>

Copilot AI commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved in efa1cfa by merging master and retaining both sets of changelog entries. The Click compatibility fix is preserved. All 244 targeted tests and applicable pre-commit hooks passed; secret scanning and CodeQL found no issues.

@cloudsmith-iduffy
cloudsmith-iduffy marked this pull request as ready for review November 2, 2026 15:47
@cloudsmith-iduffy
cloudsmith-iduffy requested a review from a team as a code owner November 2, 2026 15:47
@cloudsmith-iduffy
cloudsmith-iduffy merged commit dc43108 into master Nov 2, 2026
23 checks passed
@cloudsmith-iduffy
cloudsmith-iduffy deleted the iduffy/fix-color-option-old-click branch November 2, 2026 15:47
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master: (25 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  fix(no-ticket): print a skipped API error one time in copy, move and resync (#552)
  fix(no-ticket): save credentials.ini with mode 0600 (#553)
  ...

# Conflicts:
#	CHANGELOG.md
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master: (25 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  fix(no-ticket): print a skipped API error one time in copy, move and resync (#552)
  fix(no-ticket): save credentials.ini with mode 0600 (#553)
  ...

# Conflicts:
#	CHANGELOG.md
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master:
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master: (25 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  fix(no-ticket): print a skipped API error one time in copy, move and resync (#552)
  fix(no-ticket): save credentials.ini with mode 0600 (#553)
  ...

# Conflicts:
#	CHANGELOG.md
#	cloudsmith_cli/core/rest.py
#	cloudsmith_cli/core/tests/test_rest.py
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master:
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)

# Conflicts:
#	CHANGELOG.md
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master:
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)

# Conflicts:
#	CHANGELOG.md
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master:
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master: (25 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  fix(no-ticket): print a skipped API error one time in copy, move and resync (#552)
  fix(no-ticket): save credentials.ini with mode 0600 (#553)
  ...

# Conflicts:
#	CHANGELOG.md
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
* origin/master: (25 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  fix(no-ticket): print a skipped API error one time in copy, move and resync (#552)
  fix(no-ticket): save credentials.ini with mode 0600 (#553)
  ...

# Conflicts:
#	CHANGELOG.md
#	cloudsmith_cli/cli/config.py
cloudsmith-iduffy added a commit that referenced this pull request Nov 2, 2026
-docker-launcher-settings

* origin/iduffy/launcher-install-time-settings: (27 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  feat(ENG-15016): let credential-helper launchers keep install-time settings
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  ...

# Conflicts:
#	cloudsmith_cli/cli/commands/credential_helper/manage.py
#	cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py
#	cloudsmith_cli/credential_helpers/docker/installer.py
#	cloudsmith_cli/credential_helpers/launchers.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants