cloudsmith-cli 1.18.0__tar.gz → 1.19.0__tar.gz

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.
Files changed (192) hide show
  1. {cloudsmith_cli-1.18.0/cloudsmith_cli.egg-info → cloudsmith_cli-1.19.0}/PKG-INFO +68 -3
  2. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/README.md +65 -0
  3. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/__init__.py +1 -0
  4. cloudsmith_cli-1.19.0/cloudsmith_cli/cli/commands/credential_helper/__init__.py +39 -0
  5. cloudsmith_cli-1.19.0/cloudsmith_cli/cli/commands/credential_helper/docker.py +66 -0
  6. cloudsmith_cli-1.19.0/cloudsmith_cli/cli/commands/credential_helper/manage.py +299 -0
  7. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/config.py +22 -0
  8. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/decorators.py +67 -0
  9. cloudsmith_cli-1.19.0/cloudsmith_cli/cli/tests/commands/test_credential_helper.py +564 -0
  10. cloudsmith_cli-1.19.0/cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py +718 -0
  11. cloudsmith_cli-1.19.0/cloudsmith_cli/cli/tests/test_oidc_detector_config.py +77 -0
  12. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/orgs.py +17 -0
  13. cloudsmith_cli-1.19.0/cloudsmith_cli/core/cache_utils.py +160 -0
  14. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/models.py +2 -0
  15. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/oidc/cache.py +10 -9
  16. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +122 -0
  17. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/oidc/detectors/aws.py +1 -0
  18. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/azure_devops.py +70 -0
  19. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/oidc/detectors/base.py +1 -0
  20. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/bitbucket_pipelines.py +35 -0
  21. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/circleci.py +40 -0
  22. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/generic.py +42 -0
  23. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/github_actions.py +64 -0
  24. cloudsmith_cli-1.19.0/cloudsmith_cli/core/credentials/oidc/detectors/gitlab_ci.py +49 -0
  25. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/download.py +1 -1
  26. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_azure_devops_detector.py +125 -0
  27. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_bitbucket_pipelines_detector.py +55 -0
  28. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_cache_utils.py +375 -0
  29. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_circleci_detector.py +76 -0
  30. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_detector_controls.py +153 -0
  31. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_generic_detector.py +72 -0
  32. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_github_actions_detector.py +116 -0
  33. cloudsmith_cli-1.19.0/cloudsmith_cli/core/tests/test_gitlab_ci_detector.py +74 -0
  34. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/utils.py +1 -1
  35. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/__init__.py +7 -0
  36. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/backends.py +41 -0
  37. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/common.py +111 -0
  38. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/custom_domains.py +281 -0
  39. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/docker/__init__.py +4 -0
  40. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/docker/installer.py +331 -0
  41. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/docker/runtime.py +117 -0
  42. cloudsmith_cli-1.19.0/cloudsmith_cli/credential_helpers/launchers.py +175 -0
  43. cloudsmith_cli-1.19.0/cloudsmith_cli/data/VERSION +1 -0
  44. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0/cloudsmith_cli.egg-info}/PKG-INFO +68 -3
  45. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli.egg-info/SOURCES.txt +29 -0
  46. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli.egg-info/requires.txt +2 -2
  47. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/setup.py +8 -3
  48. cloudsmith_cli-1.18.0/cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +0 -42
  49. cloudsmith_cli-1.18.0/cloudsmith_cli/data/VERSION +0 -1
  50. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/LICENSE +0 -0
  51. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/MANIFEST.in +0 -0
  52. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/__init__.py +0 -0
  53. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/__main__.py +0 -0
  54. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/__init__.py +0 -0
  55. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/command.py +0 -0
  56. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/auth.py +0 -0
  57. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/check.py +0 -0
  58. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/copy.py +0 -0
  59. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/delete.py +0 -0
  60. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/dependencies.py +0 -0
  61. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/docs.py +0 -0
  62. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/download.py +0 -0
  63. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/entitlements.py +0 -0
  64. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/help_.py +0 -0
  65. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/list_.py +0 -0
  66. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/login.py +0 -0
  67. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/logout.py +0 -0
  68. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/main.py +0 -0
  69. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/mcp.py +0 -0
  70. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/metadata.py +0 -0
  71. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/metrics/__init__.py +0 -0
  72. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/metrics/command.py +0 -0
  73. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/metrics/entitlements.py +0 -0
  74. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/metrics/packages.py +0 -0
  75. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/move.py +0 -0
  76. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/policy/__init__.py +0 -0
  77. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/policy/command.py +0 -0
  78. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/policy/deny.py +0 -0
  79. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/policy/license.py +0 -0
  80. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/policy/vulnerability.py +0 -0
  81. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/push.py +0 -0
  82. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/quarantine.py +0 -0
  83. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/quota/__init__.py +0 -0
  84. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/quota/command.py +0 -0
  85. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/quota/history.py +0 -0
  86. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/quota/quota.py +0 -0
  87. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/repos.py +0 -0
  88. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/resync.py +0 -0
  89. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/status.py +0 -0
  90. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/tags.py +0 -0
  91. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/tokens.py +0 -0
  92. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/upstream.py +0 -0
  93. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/vulnerabilities.py +0 -0
  94. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/commands/whoami.py +0 -0
  95. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/exceptions.py +0 -0
  96. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/metadata_common.py +0 -0
  97. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/saml.py +0 -0
  98. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/table.py +0 -0
  99. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/__init__.py +0 -0
  100. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/__init__.py +0 -0
  101. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/conftest.py +0 -0
  102. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/policy/__init__.py +0 -0
  103. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/policy/test_deny.py +0 -0
  104. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/policy/test_licence.py +0 -0
  105. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/policy/test_vulnerability.py +0 -0
  106. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_auth.py +0 -0
  107. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_check.py +0 -0
  108. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_download.py +0 -0
  109. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_entitlements.py +0 -0
  110. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_login.py +0 -0
  111. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_logout.py +0 -0
  112. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_main.py +0 -0
  113. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_mcp.py +0 -0
  114. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_metadata.py +0 -0
  115. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_package_commands.py +0 -0
  116. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_repos.py +0 -0
  117. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_tokens.py +0 -0
  118. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_upstream.py +0 -0
  119. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/commands/test_vulnerabilities.py +0 -0
  120. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/conftest.py +0 -0
  121. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/test_metadata_common.py +0 -0
  122. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/test_push.py +0 -0
  123. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/test_saml.py +0 -0
  124. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/test_utils.py +0 -0
  125. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/test_webserver.py +0 -0
  126. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/tests/utils.py +0 -0
  127. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/types.py +0 -0
  128. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/utils.py +0 -0
  129. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/validators.py +0 -0
  130. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/cli/webserver.py +0 -0
  131. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/__init__.py +0 -0
  132. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/__init__.py +0 -0
  133. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/distros.py +0 -0
  134. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/entitlements.py +0 -0
  135. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/exceptions.py +0 -0
  136. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/files.py +0 -0
  137. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/init.py +0 -0
  138. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/metadata.py +0 -0
  139. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/metrics.py +0 -0
  140. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/packages.py +0 -0
  141. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/quota.py +0 -0
  142. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/rates.py +0 -0
  143. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/repos.py +0 -0
  144. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/status.py +0 -0
  145. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/upstreams.py +0 -0
  146. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/user.py +0 -0
  147. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/version.py +0 -0
  148. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/api/vulnerabilities.py +0 -0
  149. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/config.py +0 -0
  150. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/__init__.py +0 -0
  151. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/chain.py +0 -0
  152. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/oidc/__init__.py +0 -0
  153. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/oidc/exchange.py +0 -0
  154. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/provider.py +0 -0
  155. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/providers/__init__.py +0 -0
  156. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/providers/cli_flag.py +0 -0
  157. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/providers/credentials_file.py +0 -0
  158. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/providers/env_var.py +0 -0
  159. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/providers/keyring_provider.py +0 -0
  160. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/credentials/providers/oidc_provider.py +0 -0
  161. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/keyring.py +0 -0
  162. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/mcp/__init__.py +0 -0
  163. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/mcp/data.py +0 -0
  164. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/mcp/server.py +0 -0
  165. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/pagination.py +0 -0
  166. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/ratelimits.py +0 -0
  167. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/rest.py +0 -0
  168. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/__init__.py +0 -0
  169. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_cli_flag_provider.py +0 -0
  170. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_credential_chain_priority.py +0 -0
  171. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_credential_context.py +0 -0
  172. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_credential_provider_chain.py +0 -0
  173. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_credentials_file_provider.py +0 -0
  174. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_download.py +0 -0
  175. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_env_var_provider.py +0 -0
  176. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_init.py +0 -0
  177. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_keyring.py +0 -0
  178. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_keyring_provider.py +0 -0
  179. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_metadata.py +0 -0
  180. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_rest.py +0 -0
  181. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/tests/test_version.py +0 -0
  182. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/core/version.py +0 -0
  183. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/data/config.ini +0 -0
  184. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/data/credentials.ini +0 -0
  185. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/templates/__init__.py +0 -0
  186. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/templates/auth_error.html +0 -0
  187. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli/templates/auth_success.html +0 -0
  188. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli.egg-info/dependency_links.txt +0 -0
  189. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli.egg-info/entry_points.txt +0 -0
  190. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli.egg-info/not-zip-safe +0 -0
  191. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/cloudsmith_cli.egg-info/top_level.txt +0 -0
  192. {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.19.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudsmith-cli
3
- Version: 1.18.0
3
+ Version: 1.19.0
4
4
  Summary: Cloudsmith Command-Line Interface (CLI)
5
5
  Home-page: https://github.com/cloudsmith-io/cloudsmith-cli
6
6
  Author: Cloudsmith Ltd
@@ -33,8 +33,8 @@ Requires-Dist: click-spinner>=0.1.7
33
33
  Requires-Dist: json5>=0.9.0
34
34
  Requires-Dist: cloudsmith-api<3.0,>=2.0.25
35
35
  Requires-Dist: keyring>=25.4.1
36
- Requires-Dist: mcp==1.9.1
37
- Requires-Dist: PyJWT>=2.0.0
36
+ Requires-Dist: mcp==1.27.2
37
+ Requires-Dist: PyJWT[crypto]>=2.0.0
38
38
  Requires-Dist: python-toon==0.1.2
39
39
  Requires-Dist: requests>=2.18.4
40
40
  Requires-Dist: requests_toolbelt>=1.0.0
@@ -227,6 +227,71 @@ pip install cloudsmith-cli[all]
227
227
 
228
228
  **Note:** If you don't install the AWS extra, the AWS OIDC detector will gracefully skip itself with no errors.
229
229
 
230
+ #### Bitbucket Pipelines OIDC Support
231
+
232
+ In Bitbucket Pipelines, OIDC credential discovery works out of the box with no extra dependencies. Set `oidc: true` on the pipeline step and the CLI reads the token from the `BITBUCKET_STEP_OIDC_TOKEN` variable that Bitbucket populates. The Cloudsmith OIDC provider must expect the workspace audience that Bitbucket mints (`ari:cloud:bitbucket::workspace/<workspace-uuid>`):
233
+
234
+ ```yaml
235
+ pipelines:
236
+ default:
237
+ - step:
238
+ oidc: true
239
+ script:
240
+ - cloudsmith push ...
241
+ ```
242
+
243
+ See the [Bitbucket Pipelines OIDC documentation](https://support.atlassian.com/bitbucket-cloud/docs/integrate-pipelines-with-resource-servers-using-oidc/).
244
+
245
+ #### CircleCI OIDC Support
246
+
247
+ In CircleCI, OIDC credential discovery works out of the box with no extra dependencies — the CLI reads the token from the `CIRCLE_OIDC_TOKEN_V2` (preferred) or `CIRCLE_OIDC_TOKEN` environment variable that CircleCI injects into every job. The Cloudsmith OIDC provider must expect the audience CircleCI mints, which is your CircleCI organization UUID. See the [Cloudsmith CircleCI integration guide](https://docs.cloudsmith.com/integrations/integrating-with-circleci).
248
+
249
+ #### Azure DevOps OIDC Support
250
+
251
+ In Azure DevOps Pipelines, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the `SYSTEM_OIDCREQUESTURI` endpoint using the pipeline's `SYSTEM_ACCESSTOKEN`. Make sure `SYSTEM_ACCESSTOKEN` is mapped into the step's environment. The Cloudsmith OIDC provider must expect the audience `api://AzureADTokenExchange`, which Azure DevOps always mints (any requested audience is ignored). See the [Cloudsmith Azure DevOps integration guide](https://docs.cloudsmith.com/integrations/integrating-with-azure-devops).
252
+
253
+ #### GitHub Actions OIDC Support
254
+
255
+ In GitHub Actions, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the Actions runtime when the workflow requests `id-token: write` permission. See the [Cloudsmith GitHub Actions OIDC guide](https://docs.cloudsmith.com/authentication/setup-cloudsmith-to-authenticate-with-oidc-in-github-actions).
256
+
257
+ #### GitLab CI OIDC Support
258
+
259
+ In GitLab CI/CD, OIDC credential discovery works out of the box with no extra dependencies. Configure an [`id_tokens`](https://docs.gitlab.com/ci/cloud_services/) entry in your `.gitlab-ci.yml` with an `aud` of `https://api.cloudsmith.io/openid/<your-org>` and expose it as `CLOUDSMITH_OIDC_TOKEN`, and the CLI will pick it up automatically:
260
+
261
+ ```yaml
262
+ job:
263
+ id_tokens:
264
+ CLOUDSMITH_OIDC_TOKEN:
265
+ aud: https://api.cloudsmith.io/openid/<your-org>
266
+ script:
267
+ - cloudsmith push ...
268
+ ```
269
+
270
+ See the [Cloudsmith GitLab CI/CD integration guide](https://docs.cloudsmith.com/integrations/integrating-with-gitlab-cicd).
271
+
272
+ #### Generic OIDC Support (Jenkins, custom CI/CD)
273
+
274
+ As a fallback for environments without a dedicated detector (for example Jenkins with the [credentials binding plugin](https://plugins.jenkins.io/credentials-binding/), or any custom CI/CD system), set the `CLOUDSMITH_OIDC_TOKEN` environment variable to an OIDC JWT and the CLI will exchange it for a Cloudsmith access token. This detector runs last, so a dedicated environment is always preferred when present. See the [Cloudsmith Jenkins OIDC guide](https://docs.cloudsmith.com/authentication/setup-jenkins-to-authenticate-to-cloudsmith-using-oidc).
275
+
276
+ #### Controlling OIDC Detector Selection
277
+
278
+ By default the CLI tries each detector in a fixed priority order and uses the first that matches. Two controls let you override this when a detector matches an environment you don't want it to (for example, the AWS detector matching ambient instance credentials):
279
+
280
+ - **Disable a detector** — set `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED=true` to skip it entirely. Only the literal value `true` (case-insensitive) disables; anything else leaves the detector enabled. For example, `CLOUDSMITH_OIDC_AWS_DISABLED=true` skips the AWS detector so an explicitly-set `CLOUDSMITH_OIDC_TOKEN` is picked up by the generic detector instead.
281
+ - **Reorder evaluation** — use `--oidc-detector-order` (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) with a comma-separated list of detector ids to control both which detectors are considered and the order they are tried in (first match wins). Ids not listed are skipped; unrecognised ids are ignored with a warning. For example, `--oidc-detector-order=generic,aws` tries the generic detector first and considers only those two.
282
+
283
+ When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `circleci`, `generic`, `github`, `gitlab`.
284
+
285
+ Both controls can also be set in `config.ini`, under `[default]` or a profile section:
286
+
287
+ ```ini
288
+ [default]
289
+ oidc_detector_order = github, aws
290
+ oidc_disabled_detectors = aws, gitlab
291
+ ```
292
+
293
+ The `--oidc-detector-order` flag (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) overrides the `oidc_detector_order` config value. The `oidc_disabled_detectors` config key is additive with the per-detector `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED` environment variables — a detector disabled by either is skipped.
294
+
230
295
  ## Configuration
231
296
 
232
297
  There are two configuration files used by the CLI:
@@ -165,6 +165,71 @@ pip install cloudsmith-cli[all]
165
165
 
166
166
  **Note:** If you don't install the AWS extra, the AWS OIDC detector will gracefully skip itself with no errors.
167
167
 
168
+ #### Bitbucket Pipelines OIDC Support
169
+
170
+ In Bitbucket Pipelines, OIDC credential discovery works out of the box with no extra dependencies. Set `oidc: true` on the pipeline step and the CLI reads the token from the `BITBUCKET_STEP_OIDC_TOKEN` variable that Bitbucket populates. The Cloudsmith OIDC provider must expect the workspace audience that Bitbucket mints (`ari:cloud:bitbucket::workspace/<workspace-uuid>`):
171
+
172
+ ```yaml
173
+ pipelines:
174
+ default:
175
+ - step:
176
+ oidc: true
177
+ script:
178
+ - cloudsmith push ...
179
+ ```
180
+
181
+ See the [Bitbucket Pipelines OIDC documentation](https://support.atlassian.com/bitbucket-cloud/docs/integrate-pipelines-with-resource-servers-using-oidc/).
182
+
183
+ #### CircleCI OIDC Support
184
+
185
+ In CircleCI, OIDC credential discovery works out of the box with no extra dependencies — the CLI reads the token from the `CIRCLE_OIDC_TOKEN_V2` (preferred) or `CIRCLE_OIDC_TOKEN` environment variable that CircleCI injects into every job. The Cloudsmith OIDC provider must expect the audience CircleCI mints, which is your CircleCI organization UUID. See the [Cloudsmith CircleCI integration guide](https://docs.cloudsmith.com/integrations/integrating-with-circleci).
186
+
187
+ #### Azure DevOps OIDC Support
188
+
189
+ In Azure DevOps Pipelines, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the `SYSTEM_OIDCREQUESTURI` endpoint using the pipeline's `SYSTEM_ACCESSTOKEN`. Make sure `SYSTEM_ACCESSTOKEN` is mapped into the step's environment. The Cloudsmith OIDC provider must expect the audience `api://AzureADTokenExchange`, which Azure DevOps always mints (any requested audience is ignored). See the [Cloudsmith Azure DevOps integration guide](https://docs.cloudsmith.com/integrations/integrating-with-azure-devops).
190
+
191
+ #### GitHub Actions OIDC Support
192
+
193
+ In GitHub Actions, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the Actions runtime when the workflow requests `id-token: write` permission. See the [Cloudsmith GitHub Actions OIDC guide](https://docs.cloudsmith.com/authentication/setup-cloudsmith-to-authenticate-with-oidc-in-github-actions).
194
+
195
+ #### GitLab CI OIDC Support
196
+
197
+ In GitLab CI/CD, OIDC credential discovery works out of the box with no extra dependencies. Configure an [`id_tokens`](https://docs.gitlab.com/ci/cloud_services/) entry in your `.gitlab-ci.yml` with an `aud` of `https://api.cloudsmith.io/openid/<your-org>` and expose it as `CLOUDSMITH_OIDC_TOKEN`, and the CLI will pick it up automatically:
198
+
199
+ ```yaml
200
+ job:
201
+ id_tokens:
202
+ CLOUDSMITH_OIDC_TOKEN:
203
+ aud: https://api.cloudsmith.io/openid/<your-org>
204
+ script:
205
+ - cloudsmith push ...
206
+ ```
207
+
208
+ See the [Cloudsmith GitLab CI/CD integration guide](https://docs.cloudsmith.com/integrations/integrating-with-gitlab-cicd).
209
+
210
+ #### Generic OIDC Support (Jenkins, custom CI/CD)
211
+
212
+ As a fallback for environments without a dedicated detector (for example Jenkins with the [credentials binding plugin](https://plugins.jenkins.io/credentials-binding/), or any custom CI/CD system), set the `CLOUDSMITH_OIDC_TOKEN` environment variable to an OIDC JWT and the CLI will exchange it for a Cloudsmith access token. This detector runs last, so a dedicated environment is always preferred when present. See the [Cloudsmith Jenkins OIDC guide](https://docs.cloudsmith.com/authentication/setup-jenkins-to-authenticate-to-cloudsmith-using-oidc).
213
+
214
+ #### Controlling OIDC Detector Selection
215
+
216
+ By default the CLI tries each detector in a fixed priority order and uses the first that matches. Two controls let you override this when a detector matches an environment you don't want it to (for example, the AWS detector matching ambient instance credentials):
217
+
218
+ - **Disable a detector** — set `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED=true` to skip it entirely. Only the literal value `true` (case-insensitive) disables; anything else leaves the detector enabled. For example, `CLOUDSMITH_OIDC_AWS_DISABLED=true` skips the AWS detector so an explicitly-set `CLOUDSMITH_OIDC_TOKEN` is picked up by the generic detector instead.
219
+ - **Reorder evaluation** — use `--oidc-detector-order` (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) with a comma-separated list of detector ids to control both which detectors are considered and the order they are tried in (first match wins). Ids not listed are skipped; unrecognised ids are ignored with a warning. For example, `--oidc-detector-order=generic,aws` tries the generic detector first and considers only those two.
220
+
221
+ When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `circleci`, `generic`, `github`, `gitlab`.
222
+
223
+ Both controls can also be set in `config.ini`, under `[default]` or a profile section:
224
+
225
+ ```ini
226
+ [default]
227
+ oidc_detector_order = github, aws
228
+ oidc_disabled_detectors = aws, gitlab
229
+ ```
230
+
231
+ The `--oidc-detector-order` flag (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) overrides the `oidc_detector_order` config value. The `oidc_disabled_detectors` config key is additive with the per-detector `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED` environment variables — a detector disabled by either is skipped.
232
+
168
233
  ## Configuration
169
234
 
170
235
  There are two configuration files used by the CLI:
@@ -4,6 +4,7 @@ from . import (
4
4
  auth,
5
5
  check,
6
6
  copy,
7
+ credential_helper,
7
8
  delete,
8
9
  dependencies,
9
10
  docs,
@@ -0,0 +1,39 @@
1
+ # Copyright 2026 Cloudsmith Ltd
2
+ """
3
+ Credential helper commands for Cloudsmith.
4
+
5
+ This module provides credential helper commands for package managers
6
+ that follow their respective credential helper protocols.
7
+ """
8
+
9
+ import click
10
+
11
+ from ..main import main
12
+ from .docker import docker as docker_cmd
13
+ from .manage import install_cmd, list_cmd, uninstall_cmd
14
+
15
+
16
+ @click.group()
17
+ def credential_helper():
18
+ """
19
+ Credential helpers for package managers.
20
+
21
+ These commands provide credentials for package managers like Docker.
22
+ Use ``install`` to set up the on-PATH launcher and configure the package
23
+ manager automatically, or run the runtime command directly for debugging.
24
+
25
+ Examples:
26
+ # Install Docker credential helper
27
+ $ cloudsmith credential-helper install docker
28
+
29
+ # Test Docker credential helper directly
30
+ $ echo "docker.cloudsmith.io" | cloudsmith credential-helper docker
31
+ """
32
+
33
+
34
+ credential_helper.add_command(docker_cmd, name="docker")
35
+ credential_helper.add_command(install_cmd, name="install")
36
+ credential_helper.add_command(uninstall_cmd, name="uninstall")
37
+ credential_helper.add_command(list_cmd, name="list")
38
+
39
+ main.add_command(credential_helper, name="credential-helper")
@@ -0,0 +1,66 @@
1
+ # Copyright 2026 Cloudsmith Ltd
2
+ """
3
+ Docker credential helper command.
4
+
5
+ Implements the Docker credential helper protocol for Cloudsmith registries.
6
+
7
+ See: https://github.com/docker/docker-credential-helpers
8
+ """
9
+
10
+ import sys
11
+
12
+ import click
13
+
14
+ from ....credential_helpers.docker import execute
15
+ from ...decorators import common_api_auth_options, resolve_credentials
16
+
17
+
18
+ @click.command()
19
+ @click.argument("operation", required=False, default="get")
20
+ @common_api_auth_options
21
+ @resolve_credentials
22
+ def docker(opts, operation):
23
+ """
24
+ Docker credential helper for Cloudsmith registries.
25
+
26
+ Reads a Docker registry server URL from stdin and returns credentials in
27
+ JSON format. Implements the full Docker credential helper protocol
28
+ (get/store/erase/list).
29
+
30
+ Provides credentials for all Cloudsmith Docker registries: ``*.cloudsmith.io``,
31
+ ``*.cloudsmith.com``, and any custom domains configured for the organisation
32
+ (requires CLOUDSMITH_ORG and a valid API key/token).
33
+
34
+ Input (stdin):
35
+ Server URL as plain text (e.g. "docker.cloudsmith.io")
36
+
37
+ Output (stdout):
38
+ JSON: {"Username": "token", "Secret": "<cloudsmith-token>"}
39
+
40
+ Exit codes:
41
+ 0: Success
42
+ 1: Error (no credentials available, not a Cloudsmith registry, etc.)
43
+
44
+ Examples:
45
+ # Manual testing
46
+ $ echo "docker.cloudsmith.io" | cloudsmith credential-helper docker
47
+
48
+ # Called by Docker via launcher
49
+ $ echo "docker.cloudsmith.io" | docker-credential-cloudsmith get
50
+
51
+ Environment variables:
52
+ CLOUDSMITH_API_KEY: API key for authentication (optional)
53
+ CLOUDSMITH_ORG: Organisation slug (required for custom domain support)
54
+ """
55
+ exit_code, stdout, stderr = execute(
56
+ operation,
57
+ sys.stdin,
58
+ credential=opts.credential,
59
+ api_host=opts.api_host,
60
+ )
61
+
62
+ if stdout is not None:
63
+ click.echo(stdout)
64
+ if stderr is not None:
65
+ click.echo(stderr, err=True)
66
+ sys.exit(exit_code)
@@ -0,0 +1,299 @@
1
+ # Copyright 2026 Cloudsmith Ltd
2
+ """Install/uninstall/list commands for credential helpers.
3
+
4
+ Provides ``credential-helper install``, ``credential-helper uninstall``, and
5
+ ``credential-helper list`` to manage the on-PATH launcher binary and the
6
+ ``config.json`` entries for each supported credential helper.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import sys
13
+
14
+ import click
15
+
16
+ from ....credential_helpers.docker.installer import DockerInstaller
17
+ from ... import utils
18
+ from ...decorators import (
19
+ common_api_auth_options,
20
+ common_cli_config_options,
21
+ common_cli_output_options,
22
+ resolve_credentials,
23
+ )
24
+
25
+ # ---------------------------------------------------------------------------
26
+ # Helper registry — extend here when new helpers are added
27
+ # ---------------------------------------------------------------------------
28
+
29
+ _INSTALLERS: dict[str, type] = {
30
+ "docker": DockerInstaller,
31
+ }
32
+
33
+
34
+ def _get_installer(name: str):
35
+ """Return an instantiated installer for *name*, or exit with a clear error.
36
+
37
+ Parameters
38
+ ----------
39
+ name:
40
+ The helper name as supplied by the user (e.g. ``"docker"``).
41
+
42
+ Returns
43
+ -------
44
+ DockerInstaller
45
+ An instance of the appropriate installer class.
46
+
47
+ Raises
48
+ ------
49
+ SystemExit
50
+ If *name* is not in :data:`_INSTALLERS`.
51
+ """
52
+ cls = _INSTALLERS.get(name)
53
+ if cls is None:
54
+ available = ", ".join(sorted(_INSTALLERS))
55
+ click.echo(
56
+ f"Error: unknown helper {name!r}. Available helpers: {available}",
57
+ err=True,
58
+ )
59
+ sys.exit(1)
60
+ return cls()
61
+
62
+
63
+ # ---------------------------------------------------------------------------
64
+ # install
65
+ # ---------------------------------------------------------------------------
66
+
67
+
68
+ @click.command("install")
69
+ @click.argument("helper")
70
+ @click.option(
71
+ "--bin-dir", default=None, help="Directory to install the launcher binary."
72
+ )
73
+ @click.option(
74
+ "--domain",
75
+ "domains",
76
+ multiple=True,
77
+ help="Additional registry hostname to configure (repeatable).",
78
+ )
79
+ @click.option(
80
+ "--dry-run",
81
+ is_flag=True,
82
+ default=False,
83
+ help="Show what would be done without making any changes.",
84
+ )
85
+ @click.option(
86
+ "--no-discover",
87
+ is_flag=True,
88
+ default=False,
89
+ help="Disable automatic discovery of custom Docker domains.",
90
+ )
91
+ @click.option(
92
+ "--refresh",
93
+ is_flag=True,
94
+ default=False,
95
+ help="Bypass the custom-domain cache and fetch fresh data from the API.",
96
+ )
97
+ @click.option(
98
+ "--org",
99
+ default=None,
100
+ help="Cloudsmith organisation slug for custom-domain discovery.",
101
+ )
102
+ @common_cli_config_options
103
+ @common_cli_output_options
104
+ @common_api_auth_options
105
+ @resolve_credentials
106
+ @click.pass_context
107
+ def install_cmd(
108
+ ctx,
109
+ opts,
110
+ helper: str,
111
+ bin_dir: str | None,
112
+ domains: tuple[str, ...],
113
+ dry_run: bool,
114
+ no_discover: bool,
115
+ refresh: bool,
116
+ org: str | None,
117
+ ) -> None:
118
+ """Install a credential helper launcher and configure the package manager.
119
+
120
+ HELPER is the name of the credential helper to install (e.g. ``docker``).
121
+
122
+ Examples:
123
+
124
+ \b
125
+ # Install Docker credential helper
126
+ $ cloudsmith credential-helper install docker
127
+
128
+ \b
129
+ # Install with a custom domain
130
+ $ cloudsmith credential-helper install docker --domain my.registry.example.com
131
+
132
+ \b
133
+ # Preview without making changes
134
+ $ cloudsmith credential-helper install docker --dry-run
135
+
136
+ \b
137
+ # Disable automatic custom-domain discovery
138
+ $ cloudsmith credential-helper install docker --no-discover
139
+ """
140
+ installer = _get_installer(helper)
141
+ org = org or os.environ.get("CLOUDSMITH_ORG", "").strip() or None
142
+ api_key = opts.credential.api_key if opts.credential else None
143
+ auth_type = (
144
+ getattr(opts.credential, "auth_type", "api_key")
145
+ if opts.credential
146
+ else "api_key"
147
+ )
148
+ try:
149
+ actions = installer.install(
150
+ bin_dir=bin_dir,
151
+ domains=domains,
152
+ dry_run=dry_run,
153
+ discover=not no_discover,
154
+ refresh=refresh,
155
+ org=org,
156
+ api_key=api_key,
157
+ auth_type=auth_type,
158
+ api_host=opts.api_host,
159
+ )
160
+ except OSError as exc:
161
+ raise click.ClickException(
162
+ f"Failed to install {helper!r} credential helper: {exc}"
163
+ )
164
+
165
+ use_stderr = utils.should_use_stderr(opts)
166
+ warnings = [a for a in actions if a.startswith("WARNING")]
167
+ normal = [a for a in actions if not a.startswith("WARNING")]
168
+ data = {
169
+ "helper": helper,
170
+ "dry_run": dry_run,
171
+ "actions": normal,
172
+ "warnings": warnings,
173
+ }
174
+ if utils.maybe_print_as_json(opts, data):
175
+ return
176
+
177
+ if dry_run:
178
+ click.echo("Dry run — no changes will be made:", err=use_stderr)
179
+ for action in normal:
180
+ click.echo(f" {action}" if dry_run else action, err=use_stderr)
181
+ for warning in warnings:
182
+ click.secho(f" {warning}" if dry_run else warning, err=True, fg="yellow")
183
+
184
+
185
+ # ---------------------------------------------------------------------------
186
+ # uninstall
187
+ # ---------------------------------------------------------------------------
188
+
189
+
190
+ @click.command("uninstall")
191
+ @click.argument("helper")
192
+ @click.option(
193
+ "--bin-dir", default=None, help="Directory where the launcher binary was installed."
194
+ )
195
+ @click.option(
196
+ "--dry-run",
197
+ is_flag=True,
198
+ default=False,
199
+ help="Show what would be done without making any changes.",
200
+ )
201
+ @common_cli_config_options
202
+ @common_cli_output_options
203
+ @click.pass_context
204
+ def uninstall_cmd(ctx, opts, helper: str, bin_dir: str | None, dry_run: bool) -> None:
205
+ """Uninstall a credential helper launcher and remove its config entries.
206
+
207
+ HELPER is the name of the credential helper to uninstall (e.g. ``docker``).
208
+
209
+ Examples:
210
+
211
+ \b
212
+ # Uninstall Docker credential helper
213
+ $ cloudsmith credential-helper uninstall docker
214
+
215
+ \b
216
+ # Preview without making changes
217
+ $ cloudsmith credential-helper uninstall docker --dry-run
218
+ """
219
+ installer = _get_installer(helper)
220
+ try:
221
+ actions = installer.uninstall(bin_dir=bin_dir, dry_run=dry_run)
222
+ except OSError as exc:
223
+ raise click.ClickException(
224
+ f"Failed to uninstall {helper!r} credential helper: {exc}"
225
+ )
226
+
227
+ use_stderr = utils.should_use_stderr(opts)
228
+ warnings = [a for a in actions if a.startswith("WARNING")]
229
+ normal = [a for a in actions if not a.startswith("WARNING")]
230
+ data = {
231
+ "helper": helper,
232
+ "dry_run": dry_run,
233
+ "actions": normal,
234
+ "warnings": warnings,
235
+ }
236
+ if utils.maybe_print_as_json(opts, data):
237
+ return
238
+
239
+ if dry_run:
240
+ click.echo("Dry run — no changes will be made:", err=use_stderr)
241
+ for action in normal:
242
+ click.echo(f" {action}" if dry_run else action, err=use_stderr)
243
+ for warning in warnings:
244
+ click.secho(f" {warning}" if dry_run else warning, err=True, fg="yellow")
245
+
246
+
247
+ # ---------------------------------------------------------------------------
248
+ # list
249
+ # ---------------------------------------------------------------------------
250
+
251
+
252
+ @click.command("list")
253
+ @common_cli_config_options
254
+ @common_cli_output_options
255
+ @click.pass_context
256
+ def list_cmd(ctx, opts) -> None:
257
+ """List available credential helpers and their installation status.
258
+
259
+ Shows which helpers are available, whether their launcher binary is
260
+ present on PATH, and which registry hosts they are configured for.
261
+
262
+ Example:
263
+
264
+ \b
265
+ $ cloudsmith credential-helper list
266
+ """
267
+ use_stderr = utils.should_use_stderr(opts)
268
+
269
+ data = []
270
+ for name, cls in sorted(_INSTALLERS.items()):
271
+ installer = cls()
272
+ st = installer.status()
273
+ data.append(
274
+ {
275
+ "helper": name,
276
+ "summary": installer.summary,
277
+ "launcher": st.get("launcher"),
278
+ "hosts": st.get("hosts", []),
279
+ }
280
+ )
281
+
282
+ if utils.maybe_print_as_json(opts, data):
283
+ return
284
+
285
+ for entry in data:
286
+ name = entry["helper"]
287
+ launcher = entry["launcher"]
288
+ hosts = entry["hosts"]
289
+ summary = entry["summary"]
290
+
291
+ click.echo(f"{name} ({summary})", err=use_stderr)
292
+ if launcher:
293
+ click.echo(f" launcher : {launcher}", err=use_stderr)
294
+ else:
295
+ click.echo(" launcher : not installed", err=use_stderr)
296
+ if hosts:
297
+ click.echo(f" hosts : {', '.join(hosts)}", err=use_stderr)
298
+ else:
299
+ click.echo(" hosts : none configured", err=use_stderr)
@@ -69,6 +69,8 @@ class ConfigSchema:
69
69
  oidc_audience = ConfigParam(name="oidc_audience", type=str)
70
70
  oidc_org = ConfigParam(name="oidc_org", type=str)
71
71
  oidc_service_slug = ConfigParam(name="oidc_service_slug", type=str)
72
+ oidc_detector_order = ConfigParam(name="oidc_detector_order", type=str)
73
+ oidc_disabled_detectors = ConfigParam(name="oidc_disabled_detectors", type=str)
72
74
  metadata_failure_mode = ConfigParam(name="metadata_failure_mode", type=str)
73
75
 
74
76
  @matches_section("profile:*")
@@ -489,6 +491,26 @@ class Options: # pylint: disable=too-many-public-methods
489
491
  "oidc_discovery_disabled", bool(value) if value is not None else False
490
492
  )
491
493
 
494
+ @property
495
+ def oidc_detector_order(self):
496
+ """Get value for the OIDC detector evaluation order."""
497
+ return self._get_option("oidc_detector_order")
498
+
499
+ @oidc_detector_order.setter
500
+ def oidc_detector_order(self, value):
501
+ """Set value for the OIDC detector evaluation order."""
502
+ self._set_option("oidc_detector_order", value)
503
+
504
+ @property
505
+ def oidc_disabled_detectors(self):
506
+ """Get the comma-separated OIDC detector ids disabled via config."""
507
+ return self._get_option("oidc_disabled_detectors")
508
+
509
+ @oidc_disabled_detectors.setter
510
+ def oidc_disabled_detectors(self, value):
511
+ """Set the comma-separated OIDC detector ids disabled via config."""
512
+ self._set_option("oidc_disabled_detectors", value)
513
+
492
514
  @property
493
515
  def metadata_failure_mode(self):
494
516
  """Get value for push-time metadata failure mode."""