cycode 3.4.3.dev1__tar.gz → 3.4.4.dev1__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 (166) hide show
  1. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/PKG-INFO +144 -13
  2. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/README.md +143 -12
  3. cycode-3.4.4.dev1/cycode/__init__.py +1 -0
  4. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/__init__.py +11 -2
  5. cycode-3.4.4.dev1/cycode/cli/apps/scan/pre_push/pre_push_command.py +68 -0
  6. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +1 -1
  7. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/consts.py +8 -1
  8. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/commit_range_documents.py +123 -0
  9. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/user_settings/configuration_manager.py +36 -8
  10. cycode-3.4.4.dev1/cycode/cyclient/__init__.py +0 -0
  11. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/pyproject.toml +1 -1
  12. cycode-3.4.3.dev1/cycode/__init__.py +0 -1
  13. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/LICENCE +0 -0
  14. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/__main__.py +0 -0
  15. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/__init__.py +0 -0
  16. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/app.py +0 -0
  17. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/__init__.py +0 -0
  18. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
  19. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
  20. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
  21. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
  22. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/auth/__init__.py +0 -0
  23. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/auth/auth_command.py +0 -0
  24. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/auth/auth_common.py +0 -0
  25. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/auth/auth_manager.py +0 -0
  26. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/auth/models.py +0 -0
  27. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/configure/__init__.py +0 -0
  28. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/configure/configure_command.py +0 -0
  29. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/configure/consts.py +0 -0
  30. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/configure/messages.py +0 -0
  31. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/configure/prompts.py +0 -0
  32. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/ignore/__init__.py +0 -0
  33. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/ignore/ignore_command.py +0 -0
  34. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/mcp/__init__.py +0 -0
  35. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/mcp/mcp_command.py +0 -0
  36. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/__init__.py +0 -0
  37. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/report_command.py +0 -0
  38. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/__init__.py +0 -0
  39. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/common.py +0 -0
  40. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
  41. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
  42. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
  43. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
  44. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
  45. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
  46. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/aggregation_report.py +0 -0
  47. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/code_scanner.py +0 -0
  48. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
  49. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
  50. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/commit_range_scanner.py +0 -0
  51. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/detection_excluder.py +0 -0
  52. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/path/__init__.py +0 -0
  53. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/path/path_command.py +0 -0
  54. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
  55. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -0
  56. {cycode-3.4.3.dev1/cycode/cli/apps/scan/pre_receive → cycode-3.4.4.dev1/cycode/cli/apps/scan/pre_push}/__init__.py +0 -0
  57. {cycode-3.4.3.dev1/cycode/cli/apps/scan/repository → cycode-3.4.4.dev1/cycode/cli/apps/scan/pre_receive}/__init__.py +0 -0
  58. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
  59. {cycode-3.4.3.dev1/cycode/cli/apps/scan/scan_ci → cycode-3.4.4.dev1/cycode/cli/apps/scan/repository}/__init__.py +0 -0
  60. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
  61. {cycode-3.4.3.dev1/cycode/cli/exceptions → cycode-3.4.4.dev1/cycode/cli/apps/scan/scan_ci}/__init__.py +0 -0
  62. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
  63. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
  64. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/scan_command.py +0 -0
  65. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/scan_parameters.py +0 -0
  66. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/scan/scan_result.py +0 -0
  67. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/status/__init__.py +0 -0
  68. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/status/get_cli_status.py +0 -0
  69. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/status/models.py +0 -0
  70. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/status/status_command.py +0 -0
  71. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/apps/status/version_command.py +0 -0
  72. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/cli_types.py +0 -0
  73. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/config.py +0 -0
  74. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/console.py +0 -0
  75. {cycode-3.4.3.dev1/cycode/cli/files_collector → cycode-3.4.4.dev1/cycode/cli/exceptions}/__init__.py +0 -0
  76. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/exceptions/custom_exceptions.py +0 -0
  77. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
  78. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
  79. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/exceptions/handle_errors.py +0 -0
  80. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
  81. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
  82. {cycode-3.4.3.dev1/cycode/cli/files_collector/iac → cycode-3.4.4.dev1/cycode/cli/files_collector}/__init__.py +0 -0
  83. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/file_excluder.py +0 -0
  84. {cycode-3.4.3.dev1/cycode/cli/files_collector/models → cycode-3.4.4.dev1/cycode/cli/files_collector/iac}/__init__.py +0 -0
  85. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
  86. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca → cycode-3.4.4.dev1/cycode/cli/files_collector/models}/__init__.py +0 -0
  87. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
  88. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/path_documents.py +0 -0
  89. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/repository_documents.py +0 -0
  90. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca/go → cycode-3.4.4.dev1/cycode/cli/files_collector/sca}/__init__.py +0 -0
  91. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
  92. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca/maven → cycode-3.4.4.dev1/cycode/cli/files_collector/sca/go}/__init__.py +0 -0
  93. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
  94. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca/npm → cycode-3.4.4.dev1/cycode/cli/files_collector/sca/maven}/__init__.py +0 -0
  95. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
  96. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
  97. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca/nuget → cycode-3.4.4.dev1/cycode/cli/files_collector/sca/npm}/__init__.py +0 -0
  98. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
  99. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca/ruby → cycode-3.4.4.dev1/cycode/cli/files_collector/sca/nuget}/__init__.py +0 -0
  100. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
  101. {cycode-3.4.3.dev1/cycode/cli/files_collector/sca/sbt → cycode-3.4.4.dev1/cycode/cli/files_collector/sca/ruby}/__init__.py +0 -0
  102. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
  103. {cycode-3.4.3.dev1/cycode/cli/printers/tables → cycode-3.4.4.dev1/cycode/cli/files_collector/sca/sbt}/__init__.py +0 -0
  104. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
  105. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/sca/sca_file_collector.py +0 -0
  106. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/walk_ignore.py +0 -0
  107. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/files_collector/zip_documents.py +0 -0
  108. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/logger.py +0 -0
  109. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/main.py +0 -0
  110. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/models.py +0 -0
  111. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/__init__.py +0 -0
  112. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/console_printer.py +0 -0
  113. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/json_printer.py +0 -0
  114. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/printer_base.py +0 -0
  115. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/rich_printer.py +0 -0
  116. {cycode-3.4.3.dev1/cycode/cli/printers/utils/detection_ordering → cycode-3.4.4.dev1/cycode/cli/printers/tables}/__init__.py +0 -0
  117. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
  118. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/tables/table.py +0 -0
  119. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/tables/table_models.py +0 -0
  120. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/tables/table_printer.py +0 -0
  121. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/tables/table_printer_base.py +0 -0
  122. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/text_printer.py +0 -0
  123. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/utils/__init__.py +0 -0
  124. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
  125. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/utils/detection_data.py +0 -0
  126. {cycode-3.4.3.dev1/cycode/cli/user_settings → cycode-3.4.4.dev1/cycode/cli/printers/utils/detection_ordering}/__init__.py +0 -0
  127. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
  128. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
  129. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/printers/utils/rich_helpers.py +0 -0
  130. {cycode-3.4.3.dev1/cycode/cli/utils → cycode-3.4.4.dev1/cycode/cli/user_settings}/__init__.py +0 -0
  131. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/user_settings/base_file_manager.py +0 -0
  132. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/user_settings/config_file_manager.py +0 -0
  133. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/user_settings/credentials_manager.py +0 -0
  134. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/user_settings/jwt_creator.py +0 -0
  135. {cycode-3.4.3.dev1/cycode/cyclient → cycode-3.4.4.dev1/cycode/cli/utils}/__init__.py +0 -0
  136. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/enum_utils.py +0 -0
  137. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/get_api_client.py +0 -0
  138. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/git_proxy.py +0 -0
  139. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/ignore_utils.py +0 -0
  140. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/jwt_utils.py +0 -0
  141. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/path_utils.py +0 -0
  142. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/progress_bar.py +0 -0
  143. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/scan_batch.py +0 -0
  144. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/scan_utils.py +0 -0
  145. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/sentry.py +0 -0
  146. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/shell_executor.py +0 -0
  147. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/string_utils.py +0 -0
  148. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/task_timer.py +0 -0
  149. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/version_checker.py +0 -0
  150. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cli/utils/yaml_utils.py +0 -0
  151. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/config.py +0 -0
  152. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/auth_client.py +0 -0
  153. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/client_creator.py +0 -0
  154. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/config.py +0 -0
  155. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/config_dev.py +0 -0
  156. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/cycode_client.py +0 -0
  157. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/cycode_client_base.py +0 -0
  158. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/cycode_dev_based_client.py +0 -0
  159. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/cycode_token_based_client.py +0 -0
  160. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/headers.py +0 -0
  161. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/logger.py +0 -0
  162. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/models.py +0 -0
  163. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/report_client.py +0 -0
  164. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/scan_client.py +0 -0
  165. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/cyclient/scan_config_base.py +0 -0
  166. {cycode-3.4.3.dev1 → cycode-3.4.4.dev1}/cycode/logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cycode
3
- Version: 3.4.3.dev1
3
+ Version: 3.4.4.dev1
4
4
  Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
5
5
  Home-page: https://github.com/cycodehq/cycode-cli
6
6
  License: MIT
@@ -81,6 +81,7 @@ This guide walks you through both installation and usage.
81
81
  4. [Commit History Scan](#commit-history-scan)
82
82
  1. [Commit Range Option (Diff Scanning)](#commit-range-option-diff-scanning)
83
83
  5. [Pre-Commit Scan](#pre-commit-scan)
84
+ 6. [Pre-Push Scan](#pre-push-scan)
84
85
  2. [Scan Results](#scan-results)
85
86
  1. [Show/Hide Secrets](#showhide-secrets)
86
87
  2. [Soft Fail](#soft-fail)
@@ -257,13 +258,15 @@ export CYCODE_CLIENT_SECRET={your Cycode Secret Key}
257
258
 
258
259
  ## Install Pre-Commit Hook
259
260
 
260
- Cycodes pre-commit hook can be set up within your local repository so that the Cycode CLI application will identify any issues with your code automatically before you commit it to your codebase.
261
+ Cycode's pre-commit and pre-push hooks can be set up within your local repository so that the Cycode CLI application will identify any issues with your code automatically before you commit or push it to your codebase.
261
262
 
262
263
  > [!NOTE]
263
- > pre-commit hook is not available for IaC scans.
264
+ > pre-commit and pre-push hooks are not available for IaC scans.
264
265
 
265
266
  Perform the following steps to install the pre-commit hook:
266
267
 
268
+ ### Installing Pre-Commit Hook
269
+
267
270
  1. Install the pre-commit framework (Python 3.9 or higher must be installed):
268
271
 
269
272
  ```bash
@@ -277,11 +280,10 @@ Perform the following steps to install the pre-commit hook:
277
280
  ```yaml
278
281
  repos:
279
282
  - repo: https://github.com/cycodehq/cycode-cli
280
- rev: v3.4.2
283
+ rev: v3.5.0
281
284
  hooks:
282
285
  - id: cycode
283
- stages:
284
- - pre-commit
286
+ stages: [pre-commit]
285
287
  ```
286
288
 
287
289
  4. Modify the created file for your specific needs. Use hook ID `cycode` to enable scan for Secrets. Use hook ID `cycode-sca` to enable SCA scan. Use hook ID `cycode-sast` to enable SAST scan. If you want to enable all scanning types, use this configuration:
@@ -289,17 +291,14 @@ Perform the following steps to install the pre-commit hook:
289
291
  ```yaml
290
292
  repos:
291
293
  - repo: https://github.com/cycodehq/cycode-cli
292
- rev: v3.4.2
294
+ rev: v3.5.0
293
295
  hooks:
294
296
  - id: cycode
295
- stages:
296
- - pre-commit
297
+ stages: [pre-commit]
297
298
  - id: cycode-sca
298
- stages:
299
- - pre-commit
299
+ stages: [pre-commit]
300
300
  - id: cycode-sast
301
- stages:
302
- - pre-commit
301
+ stages: [pre-commit]
303
302
  ```
304
303
 
305
304
  5. Install Cycode’s hook:
@@ -322,6 +321,37 @@ Perform the following steps to install the pre-commit hook:
322
321
  > Trigger happens on `git commit` command.
323
322
  > Hook triggers only on the files that are staged for commit.
324
323
 
324
+ ### Installing Pre-Push Hook
325
+
326
+ To install the pre-push hook in addition to or instead of the pre-commit hook:
327
+
328
+ 1. Add the pre-push hooks to your `.pre-commit-config.yaml` file:
329
+
330
+ ```yaml
331
+ repos:
332
+ - repo: https://github.com/cycodehq/cycode-cli
333
+ rev: v3.5.0
334
+ hooks:
335
+ - id: cycode-pre-push
336
+ stages: [pre-push]
337
+ ```
338
+
339
+ 2. Install the pre-push hook:
340
+
341
+ ```bash
342
+ pre-commit install --hook-type pre-push
343
+ ```
344
+
345
+ 3. For both pre-commit and pre-push hooks, use:
346
+
347
+ ```bash
348
+ pre-commit install
349
+ pre-commit install --hook-type pre-push
350
+ ```
351
+
352
+ > [!NOTE]
353
+ > Pre-push hooks trigger on `git push` command and scan only the commits about to be pushed.
354
+
325
355
  # Cycode CLI Commands
326
356
 
327
357
  The following are the options and commands available with the Cycode CLI application:
@@ -830,6 +860,107 @@ After installing the pre-commit hook, you may occasionally wish to skip scanning
830
860
  SKIP=cycode git commit -m <your commit message>`
831
861
  ```
832
862
 
863
+ ### Pre-Push Scan
864
+
865
+ A pre-push scan automatically identifies any issues before you push changes to the remote repository. This hook runs on the client side and scans only the commits that are about to be pushed, making it efficient for catching issues before they reach the remote repository.
866
+
867
+ > [!NOTE]
868
+ > Pre-push hook is not available for IaC scans.
869
+
870
+ The pre-push hook integrates with the pre-commit framework and can be configured to run before any `git push` operation.
871
+
872
+ #### Installing Pre-Push Hook
873
+
874
+ To set up the pre-push hook using the pre-commit framework:
875
+
876
+ 1. Install the pre-commit framework (if not already installed):
877
+
878
+ ```bash
879
+ pip3 install pre-commit
880
+ ```
881
+
882
+ 2. Create or update your `.pre-commit-config.yaml` file to include the pre-push hooks:
883
+
884
+ ```yaml
885
+ repos:
886
+ - repo: https://github.com/cycodehq/cycode-cli
887
+ rev: v3.5.0
888
+ hooks:
889
+ - id: cycode-pre-push
890
+ stages: [pre-push]
891
+ ```
892
+
893
+ 3. For multiple scan types, use this configuration:
894
+
895
+ ```yaml
896
+ repos:
897
+ - repo: https://github.com/cycodehq/cycode-cli
898
+ rev: v3.5.0
899
+ hooks:
900
+ - id: cycode-pre-push # Secrets scan
901
+ stages: [pre-push]
902
+ - id: cycode-sca-pre-push # SCA scan
903
+ stages: [pre-push]
904
+ - id: cycode-sast-pre-push # SAST scan
905
+ stages: [pre-push]
906
+ ```
907
+
908
+ 4. Install the pre-push hook:
909
+
910
+ ```bash
911
+ pre-commit install --hook-type pre-push
912
+ ```
913
+
914
+ A successful installation will result in the message: `Pre-push installed at .git/hooks/pre-push`.
915
+
916
+ 5. Keep the pre-push hook up to date:
917
+
918
+ ```bash
919
+ pre-commit autoupdate
920
+ ```
921
+
922
+ #### How Pre-Push Scanning Works
923
+
924
+ The pre-push hook:
925
+ - Receives information about what commits are being pushed
926
+ - Calculates the appropriate commit range to scan
927
+ - For new branches: scans all commits from the merge base with the default branch
928
+ - For existing branches: scans only the new commits since the last push
929
+ - Runs the same comprehensive scanning as other Cycode scan modes
930
+
931
+ #### Smart Default Branch Detection
932
+
933
+ The pre-push hook intelligently detects the default branch for merge base calculation using this priority order:
934
+
935
+ 1. **Environment Variable**: `CYCODE_DEFAULT_BRANCH` - allows manual override
936
+ 2. **Git Remote HEAD**: Uses `git symbolic-ref refs/remotes/origin/HEAD` to detect the actual remote default branch
937
+ 3. **Git Remote Info**: Falls back to `git remote show origin` if symbolic-ref fails
938
+ 4. **Hardcoded Fallbacks**: Uses common default branch names (origin/main, origin/master, main, master)
939
+
940
+ **Setting a Custom Default Branch:**
941
+ ```bash
942
+ export CYCODE_DEFAULT_BRANCH=origin/develop
943
+ ```
944
+
945
+ This smart detection ensures the pre-push hook works correctly regardless of whether your repository uses `main`, `master`, `develop`, or any other default branch name.
946
+
947
+ #### Skipping Pre-Push Scans
948
+
949
+ To skip the pre-push scan for a specific push operation, use:
950
+
951
+ ```bash
952
+ SKIP=cycode-pre-push git push
953
+ ```
954
+
955
+ Or to skip all pre-push hooks:
956
+
957
+ ```bash
958
+ git push --no-verify
959
+ ```
960
+
961
+ > [!TIP]
962
+ > The pre-push hook is triggered on `git push` command and scans only the commits that are about to be pushed, making it more efficient than scanning the entire repository.
963
+
833
964
  ## Scan Results
834
965
 
835
966
  Each scan will complete with a message stating if any issues were found or not.
@@ -37,6 +37,7 @@ This guide walks you through both installation and usage.
37
37
  4. [Commit History Scan](#commit-history-scan)
38
38
  1. [Commit Range Option (Diff Scanning)](#commit-range-option-diff-scanning)
39
39
  5. [Pre-Commit Scan](#pre-commit-scan)
40
+ 6. [Pre-Push Scan](#pre-push-scan)
40
41
  2. [Scan Results](#scan-results)
41
42
  1. [Show/Hide Secrets](#showhide-secrets)
42
43
  2. [Soft Fail](#soft-fail)
@@ -213,13 +214,15 @@ export CYCODE_CLIENT_SECRET={your Cycode Secret Key}
213
214
 
214
215
  ## Install Pre-Commit Hook
215
216
 
216
- Cycodes pre-commit hook can be set up within your local repository so that the Cycode CLI application will identify any issues with your code automatically before you commit it to your codebase.
217
+ Cycode's pre-commit and pre-push hooks can be set up within your local repository so that the Cycode CLI application will identify any issues with your code automatically before you commit or push it to your codebase.
217
218
 
218
219
  > [!NOTE]
219
- > pre-commit hook is not available for IaC scans.
220
+ > pre-commit and pre-push hooks are not available for IaC scans.
220
221
 
221
222
  Perform the following steps to install the pre-commit hook:
222
223
 
224
+ ### Installing Pre-Commit Hook
225
+
223
226
  1. Install the pre-commit framework (Python 3.9 or higher must be installed):
224
227
 
225
228
  ```bash
@@ -233,11 +236,10 @@ Perform the following steps to install the pre-commit hook:
233
236
  ```yaml
234
237
  repos:
235
238
  - repo: https://github.com/cycodehq/cycode-cli
236
- rev: v3.4.2
239
+ rev: v3.5.0
237
240
  hooks:
238
241
  - id: cycode
239
- stages:
240
- - pre-commit
242
+ stages: [pre-commit]
241
243
  ```
242
244
 
243
245
  4. Modify the created file for your specific needs. Use hook ID `cycode` to enable scan for Secrets. Use hook ID `cycode-sca` to enable SCA scan. Use hook ID `cycode-sast` to enable SAST scan. If you want to enable all scanning types, use this configuration:
@@ -245,17 +247,14 @@ Perform the following steps to install the pre-commit hook:
245
247
  ```yaml
246
248
  repos:
247
249
  - repo: https://github.com/cycodehq/cycode-cli
248
- rev: v3.4.2
250
+ rev: v3.5.0
249
251
  hooks:
250
252
  - id: cycode
251
- stages:
252
- - pre-commit
253
+ stages: [pre-commit]
253
254
  - id: cycode-sca
254
- stages:
255
- - pre-commit
255
+ stages: [pre-commit]
256
256
  - id: cycode-sast
257
- stages:
258
- - pre-commit
257
+ stages: [pre-commit]
259
258
  ```
260
259
 
261
260
  5. Install Cycode’s hook:
@@ -278,6 +277,37 @@ Perform the following steps to install the pre-commit hook:
278
277
  > Trigger happens on `git commit` command.
279
278
  > Hook triggers only on the files that are staged for commit.
280
279
 
280
+ ### Installing Pre-Push Hook
281
+
282
+ To install the pre-push hook in addition to or instead of the pre-commit hook:
283
+
284
+ 1. Add the pre-push hooks to your `.pre-commit-config.yaml` file:
285
+
286
+ ```yaml
287
+ repos:
288
+ - repo: https://github.com/cycodehq/cycode-cli
289
+ rev: v3.5.0
290
+ hooks:
291
+ - id: cycode-pre-push
292
+ stages: [pre-push]
293
+ ```
294
+
295
+ 2. Install the pre-push hook:
296
+
297
+ ```bash
298
+ pre-commit install --hook-type pre-push
299
+ ```
300
+
301
+ 3. For both pre-commit and pre-push hooks, use:
302
+
303
+ ```bash
304
+ pre-commit install
305
+ pre-commit install --hook-type pre-push
306
+ ```
307
+
308
+ > [!NOTE]
309
+ > Pre-push hooks trigger on `git push` command and scan only the commits about to be pushed.
310
+
281
311
  # Cycode CLI Commands
282
312
 
283
313
  The following are the options and commands available with the Cycode CLI application:
@@ -786,6 +816,107 @@ After installing the pre-commit hook, you may occasionally wish to skip scanning
786
816
  SKIP=cycode git commit -m <your commit message>`
787
817
  ```
788
818
 
819
+ ### Pre-Push Scan
820
+
821
+ A pre-push scan automatically identifies any issues before you push changes to the remote repository. This hook runs on the client side and scans only the commits that are about to be pushed, making it efficient for catching issues before they reach the remote repository.
822
+
823
+ > [!NOTE]
824
+ > Pre-push hook is not available for IaC scans.
825
+
826
+ The pre-push hook integrates with the pre-commit framework and can be configured to run before any `git push` operation.
827
+
828
+ #### Installing Pre-Push Hook
829
+
830
+ To set up the pre-push hook using the pre-commit framework:
831
+
832
+ 1. Install the pre-commit framework (if not already installed):
833
+
834
+ ```bash
835
+ pip3 install pre-commit
836
+ ```
837
+
838
+ 2. Create or update your `.pre-commit-config.yaml` file to include the pre-push hooks:
839
+
840
+ ```yaml
841
+ repos:
842
+ - repo: https://github.com/cycodehq/cycode-cli
843
+ rev: v3.5.0
844
+ hooks:
845
+ - id: cycode-pre-push
846
+ stages: [pre-push]
847
+ ```
848
+
849
+ 3. For multiple scan types, use this configuration:
850
+
851
+ ```yaml
852
+ repos:
853
+ - repo: https://github.com/cycodehq/cycode-cli
854
+ rev: v3.5.0
855
+ hooks:
856
+ - id: cycode-pre-push # Secrets scan
857
+ stages: [pre-push]
858
+ - id: cycode-sca-pre-push # SCA scan
859
+ stages: [pre-push]
860
+ - id: cycode-sast-pre-push # SAST scan
861
+ stages: [pre-push]
862
+ ```
863
+
864
+ 4. Install the pre-push hook:
865
+
866
+ ```bash
867
+ pre-commit install --hook-type pre-push
868
+ ```
869
+
870
+ A successful installation will result in the message: `Pre-push installed at .git/hooks/pre-push`.
871
+
872
+ 5. Keep the pre-push hook up to date:
873
+
874
+ ```bash
875
+ pre-commit autoupdate
876
+ ```
877
+
878
+ #### How Pre-Push Scanning Works
879
+
880
+ The pre-push hook:
881
+ - Receives information about what commits are being pushed
882
+ - Calculates the appropriate commit range to scan
883
+ - For new branches: scans all commits from the merge base with the default branch
884
+ - For existing branches: scans only the new commits since the last push
885
+ - Runs the same comprehensive scanning as other Cycode scan modes
886
+
887
+ #### Smart Default Branch Detection
888
+
889
+ The pre-push hook intelligently detects the default branch for merge base calculation using this priority order:
890
+
891
+ 1. **Environment Variable**: `CYCODE_DEFAULT_BRANCH` - allows manual override
892
+ 2. **Git Remote HEAD**: Uses `git symbolic-ref refs/remotes/origin/HEAD` to detect the actual remote default branch
893
+ 3. **Git Remote Info**: Falls back to `git remote show origin` if symbolic-ref fails
894
+ 4. **Hardcoded Fallbacks**: Uses common default branch names (origin/main, origin/master, main, master)
895
+
896
+ **Setting a Custom Default Branch:**
897
+ ```bash
898
+ export CYCODE_DEFAULT_BRANCH=origin/develop
899
+ ```
900
+
901
+ This smart detection ensures the pre-push hook works correctly regardless of whether your repository uses `main`, `master`, `develop`, or any other default branch name.
902
+
903
+ #### Skipping Pre-Push Scans
904
+
905
+ To skip the pre-push scan for a specific push operation, use:
906
+
907
+ ```bash
908
+ SKIP=cycode-pre-push git push
909
+ ```
910
+
911
+ Or to skip all pre-push hooks:
912
+
913
+ ```bash
914
+ git push --no-verify
915
+ ```
916
+
917
+ > [!TIP]
918
+ > The pre-push hook is triggered on `git push` command and scans only the commits that are about to be pushed, making it more efficient than scanning the entire repository.
919
+
789
920
  ## Scan Results
790
921
 
791
922
  Each scan will complete with a message stating if any issues were found or not.
@@ -0,0 +1 @@
1
+ __version__ = '3.4.4.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -3,12 +3,15 @@ import typer
3
3
  from cycode.cli.apps.scan.commit_history.commit_history_command import commit_history_command
4
4
  from cycode.cli.apps.scan.path.path_command import path_command
5
5
  from cycode.cli.apps.scan.pre_commit.pre_commit_command import pre_commit_command
6
+ from cycode.cli.apps.scan.pre_push.pre_push_command import pre_push_command
6
7
  from cycode.cli.apps.scan.pre_receive.pre_receive_command import pre_receive_command
7
8
  from cycode.cli.apps.scan.repository.repository_command import repository_command
8
9
  from cycode.cli.apps.scan.scan_command import scan_command, scan_command_result_callback
9
10
 
10
11
  app = typer.Typer(name='scan', no_args_is_help=True)
11
12
 
13
+ _AUTOMATION_COMMANDS_RICH_HELP_PANEL = 'Automation commands'
14
+
12
15
  _scan_command_docs = 'https://github.com/cycodehq/cycode-cli/blob/main/README.md#scan-command'
13
16
  _scan_command_epilog = f'[bold]Documentation:[/] [link={_scan_command_docs}]{_scan_command_docs}[/link]'
14
17
 
@@ -26,16 +29,22 @@ app.command(name='commit-history', short_help='Scan commit history or perform di
26
29
  app.command(
27
30
  name='pre-commit',
28
31
  short_help='Use this command in pre-commit hook to scan any content that was not committed yet.',
29
- rich_help_panel='Automation commands',
32
+ rich_help_panel=_AUTOMATION_COMMANDS_RICH_HELP_PANEL,
30
33
  )(pre_commit_command)
34
+ app.command(
35
+ name='pre-push',
36
+ short_help='Use this command in pre-push hook to scan commits before pushing them to the remote repository.',
37
+ rich_help_panel=_AUTOMATION_COMMANDS_RICH_HELP_PANEL,
38
+ )(pre_push_command)
31
39
  app.command(
32
40
  name='pre-receive',
33
41
  short_help='Use this command in pre-receive hook '
34
42
  'to scan commits on the server side before pushing them to the repository.',
35
- rich_help_panel='Automation commands',
43
+ rich_help_panel=_AUTOMATION_COMMANDS_RICH_HELP_PANEL,
36
44
  )(pre_receive_command)
37
45
 
38
46
  # backward compatibility
39
47
  app.command(hidden=True, name='commit_history')(commit_history_command)
40
48
  app.command(hidden=True, name='pre_commit')(pre_commit_command)
49
+ app.command(hidden=True, name='pre_push')(pre_push_command)
41
50
  app.command(hidden=True, name='pre_receive')(pre_receive_command)
@@ -0,0 +1,68 @@
1
+ import logging
2
+ import os
3
+ from typing import Annotated, Optional
4
+
5
+ import typer
6
+
7
+ from cycode.cli import consts
8
+ from cycode.cli.apps.scan.commit_range_scanner import (
9
+ is_verbose_mode_requested_in_pre_receive_scan,
10
+ scan_commit_range,
11
+ should_skip_pre_receive_scan,
12
+ )
13
+ from cycode.cli.config import configuration_manager
14
+ from cycode.cli.console import console
15
+ from cycode.cli.exceptions.handle_scan_errors import handle_scan_exception
16
+ from cycode.cli.files_collector.commit_range_documents import (
17
+ calculate_pre_push_commit_range,
18
+ parse_pre_push_input,
19
+ )
20
+ from cycode.cli.logger import logger
21
+ from cycode.cli.utils import scan_utils
22
+ from cycode.cli.utils.sentry import add_breadcrumb
23
+ from cycode.cli.utils.task_timer import TimeoutAfter
24
+ from cycode.logger import set_logging_level
25
+
26
+
27
+ def pre_push_command(
28
+ ctx: typer.Context,
29
+ _: Annotated[Optional[list[str]], typer.Argument(help='Ignored arguments', hidden=True)] = None,
30
+ ) -> None:
31
+ try:
32
+ add_breadcrumb('pre_push')
33
+
34
+ if should_skip_pre_receive_scan():
35
+ logger.info(
36
+ 'A scan has been skipped as per your request. '
37
+ 'Please note that this may leave your system vulnerable to secrets that have not been detected.'
38
+ )
39
+ return
40
+
41
+ if is_verbose_mode_requested_in_pre_receive_scan():
42
+ ctx.obj['verbose'] = True
43
+ set_logging_level(logging.DEBUG)
44
+ logger.debug('Verbose mode enabled: all log levels will be displayed.')
45
+
46
+ command_scan_type = ctx.info_name
47
+ timeout = configuration_manager.get_pre_push_command_timeout(command_scan_type)
48
+ with TimeoutAfter(timeout):
49
+ push_update_details = parse_pre_push_input()
50
+ commit_range = calculate_pre_push_commit_range(push_update_details)
51
+ if not commit_range:
52
+ logger.info(
53
+ 'No new commits found for pushed branch, %s',
54
+ {'push_update_details': push_update_details},
55
+ )
56
+ return
57
+
58
+ scan_commit_range(
59
+ ctx=ctx,
60
+ repo_path=os.getcwd(),
61
+ commit_range=commit_range,
62
+ max_commits_count=configuration_manager.get_pre_push_max_commits_to_scan_count(command_scan_type),
63
+ )
64
+
65
+ if scan_utils.is_scan_failed(ctx):
66
+ console.print(consts.PRE_RECEIVE_AND_PUSH_REMEDIATION_MESSAGE)
67
+ except Exception as e:
68
+ handle_scan_exception(ctx, e)
@@ -63,6 +63,6 @@ def pre_receive_command(
63
63
  )
64
64
 
65
65
  if scan_utils.is_scan_failed(ctx):
66
- console.print(consts.PRE_RECEIVE_REMEDIATION_MESSAGE)
66
+ console.print(consts.PRE_RECEIVE_AND_PUSH_REMEDIATION_MESSAGE)
67
67
  except Exception as e:
68
68
  handle_scan_exception(ctx, e)
@@ -240,7 +240,14 @@ PRE_RECEIVE_MAX_COMMITS_TO_SCAN_COUNT_ENV_VAR_NAME = 'PRE_RECEIVE_MAX_COMMITS_TO
240
240
  DEFAULT_PRE_RECEIVE_MAX_COMMITS_TO_SCAN_COUNT = 50
241
241
  PRE_RECEIVE_COMMAND_TIMEOUT_ENV_VAR_NAME = 'PRE_RECEIVE_COMMAND_TIMEOUT'
242
242
  DEFAULT_PRE_RECEIVE_COMMAND_TIMEOUT_IN_SECONDS = 60
243
- PRE_RECEIVE_REMEDIATION_MESSAGE = """
243
+ # pre push scan
244
+ PRE_PUSH_MAX_COMMITS_TO_SCAN_COUNT_ENV_VAR_NAME = 'PRE_PUSH_MAX_COMMITS_TO_SCAN_COUNT'
245
+ DEFAULT_PRE_PUSH_MAX_COMMITS_TO_SCAN_COUNT = 50
246
+ PRE_PUSH_COMMAND_TIMEOUT_ENV_VAR_NAME = 'PRE_PUSH_COMMAND_TIMEOUT'
247
+ DEFAULT_PRE_PUSH_COMMAND_TIMEOUT_IN_SECONDS = 60
248
+ CYCODE_DEFAULT_BRANCH_ENV_VAR_NAME = 'CYCODE_DEFAULT_BRANCH'
249
+ # pre push and pre receive common
250
+ PRE_RECEIVE_AND_PUSH_REMEDIATION_MESSAGE = """
244
251
  Cycode Secrets Push Protection
245
252
  ------------------------------------------------------------------------------
246
253
  Resolve the following secrets by rewriting your local commit history before pushing again.
@@ -211,6 +211,129 @@ def parse_pre_receive_input() -> str:
211
211
  return pre_receive_input.splitlines()[0]
212
212
 
213
213
 
214
+ def parse_pre_push_input() -> str:
215
+ """Parse input to pre-push hook details.
216
+
217
+ Example input:
218
+ local_ref local_object_name remote_ref remote_object_name
219
+ ---------------------------------------------------------
220
+ refs/heads/main 9cf90954ef26e7c58284f8ebf7dcd0fcf711152a refs/heads/main 973a96d3e925b65941f7c47fa16129f1577d499f
221
+ refs/heads/feature-branch 3378e52dcfa47fb11ce3a4a520bea5f85d5d0bf3 refs/heads/feature-branch 59564ef68745bca38c42fc57a7822efd519a6bd9
222
+
223
+ :return: First, push update details (input's first line)
224
+ """ # noqa: E501
225
+ pre_push_input = sys.stdin.read().strip()
226
+ if not pre_push_input:
227
+ raise ValueError(
228
+ 'Pre push input was not found. Make sure that you are using this command only in pre-push hook'
229
+ )
230
+
231
+ # each line represents a branch push request, handle the first one only
232
+ return pre_push_input.splitlines()[0]
233
+
234
+
235
+ def _get_default_branches_for_merge_base(repo: 'Repo') -> list[str]:
236
+ """Get a list of default branches to try for merge base calculation.
237
+
238
+ Priority order:
239
+ 1. Environment variable CYCODE_DEFAULT_BRANCH
240
+ 2. Git remote HEAD (git symbolic-ref refs/remotes/origin/HEAD)
241
+ 3. Fallback to common default branch names
242
+
243
+ Args:
244
+ repo: Git repository object
245
+
246
+ Returns:
247
+ List of branch names to try for merge base calculation
248
+ """
249
+ default_branches = []
250
+
251
+ # 1. Check environment variable first
252
+ env_default_branch = os.getenv(consts.CYCODE_DEFAULT_BRANCH_ENV_VAR_NAME)
253
+ if env_default_branch:
254
+ logger.debug('Using default branch from environment variable: %s', env_default_branch)
255
+ default_branches.append(env_default_branch)
256
+
257
+ # 2. Try to get the actual default branch from remote HEAD
258
+ try:
259
+ remote_head = repo.git.symbolic_ref('refs/remotes/origin/HEAD')
260
+ # symbolic-ref returns something like "refs/remotes/origin/main"
261
+ if remote_head.startswith('refs/remotes/origin/'):
262
+ default_branch = remote_head.replace('refs/remotes/origin/', '')
263
+ logger.debug('Found remote default branch: %s', default_branch)
264
+ # Add both the remote tracking branch and local branch variants
265
+ default_branches.extend([f'origin/{default_branch}', default_branch])
266
+ except Exception as e:
267
+ logger.debug('Failed to get remote HEAD via symbolic-ref: %s', exc_info=e)
268
+
269
+ # Try an alternative method: git remote show origin
270
+ try:
271
+ remote_info = repo.git.remote('show', 'origin')
272
+ for line in remote_info.splitlines():
273
+ if 'HEAD branch:' in line:
274
+ default_branch = line.split('HEAD branch:')[1].strip()
275
+ logger.debug('Found default branch via remote show: %s', default_branch)
276
+ default_branches.extend([f'origin/{default_branch}', default_branch])
277
+ break
278
+ except Exception as e2:
279
+ logger.debug('Failed to get remote info via remote show: %s', exc_info=e2)
280
+
281
+ # 3. Add fallback branches (avoiding duplicates)
282
+ fallback_branches = ['origin/main', 'origin/master', 'main', 'master']
283
+ for branch in fallback_branches:
284
+ if branch not in default_branches:
285
+ default_branches.append(branch)
286
+
287
+ logger.debug('Default branches to try: %s', default_branches)
288
+ return default_branches
289
+
290
+
291
+ def calculate_pre_push_commit_range(push_update_details: str) -> Optional[str]:
292
+ """Calculate the commit range for pre-push hook scanning.
293
+
294
+ Args:
295
+ push_update_details: String in format "local_ref local_object_name remote_ref remote_object_name"
296
+
297
+ Returns:
298
+ Commit range string for scanning, or None if no scanning is needed
299
+
300
+ Environment Variables:
301
+ CYCODE_DEFAULT_BRANCH: Override the default branch for merge base calculation
302
+ """
303
+ local_ref, local_object_name, remote_ref, remote_object_name = push_update_details.split()
304
+
305
+ if remote_object_name == consts.EMPTY_COMMIT_SHA:
306
+ try:
307
+ repo = git_proxy.get_repo(os.getcwd())
308
+ default_branches = _get_default_branches_for_merge_base(repo)
309
+
310
+ merge_base = None
311
+ for default_branch in default_branches:
312
+ try:
313
+ merge_base = repo.git.merge_base(local_object_name, default_branch)
314
+ logger.debug('Found merge base %s with branch %s', merge_base, default_branch)
315
+ break
316
+ except Exception as e:
317
+ logger.debug('Failed to find merge base with %s: %s', default_branch, exc_info=e)
318
+ continue
319
+
320
+ if merge_base:
321
+ return f'{merge_base}..{local_object_name}'
322
+
323
+ logger.debug('Failed to find merge base with any default branch')
324
+ return '--all'
325
+ except Exception as e:
326
+ logger.debug('Failed to get repo for pre-push commit range calculation: %s', exc_info=e)
327
+ return '--all'
328
+
329
+ # If deleting a branch (local_object_name is all zeros), no need to scan
330
+ if local_object_name == consts.EMPTY_COMMIT_SHA:
331
+ return None
332
+
333
+ # For updates to existing branches, scan from remote to local
334
+ return f'{remote_object_name}..{local_object_name}'
335
+
336
+
214
337
  def get_diff_file_path(diff: 'Diff', relative: bool = False, repo: Optional['Repo'] = None) -> Optional[str]:
215
338
  """Get the file path from a git Diff object.
216
339