cycode 3.10.2.dev1__tar.gz → 3.10.3__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 (202) hide show
  1. {cycode-3.10.2.dev1 → cycode-3.10.3}/PKG-INFO +31 -11
  2. {cycode-3.10.2.dev1 → cycode-3.10.3}/README.md +32 -12
  3. cycode-3.10.3/cycode/__init__.py +1 -0
  4. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/path/path_command.py +11 -14
  5. cycode-3.10.3/cycode/cli/apps/sca_options.py +47 -0
  6. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/scan_command.py +10 -30
  7. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/cli_types.py +1 -0
  8. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/base_restore_dependencies.py +28 -4
  9. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +4 -4
  10. cycode-3.10.3/cycode/cli/files_collector/sca/npm/restore_deno_dependencies.py +46 -0
  11. cycode-3.10.3/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +67 -0
  12. cycode-3.10.3/cycode/cli/files_collector/sca/npm/restore_pnpm_dependencies.py +70 -0
  13. cycode-3.10.3/cycode/cli/files_collector/sca/npm/restore_yarn_dependencies.py +70 -0
  14. cycode-3.10.3/cycode/cli/files_collector/sca/php/restore_composer_dependencies.py +54 -0
  15. cycode-3.10.3/cycode/cli/files_collector/sca/python/restore_pipenv_dependencies.py +45 -0
  16. cycode-3.10.3/cycode/cli/files_collector/sca/python/restore_poetry_dependencies.py +62 -0
  17. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/sca_file_collector.py +13 -1
  18. cycode-3.10.3/cycode/cli/utils/__init__.py +0 -0
  19. cycode-3.10.3/cycode/cyclient/__init__.py +0 -0
  20. {cycode-3.10.2.dev1 → cycode-3.10.3}/pyproject.toml +1 -1
  21. cycode-3.10.2.dev1/cycode/__init__.py +0 -1
  22. cycode-3.10.2.dev1/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -180
  23. {cycode-3.10.2.dev1 → cycode-3.10.3}/LICENCE +0 -0
  24. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/__main__.py +0 -0
  25. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/__init__.py +0 -0
  26. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/app.py +0 -0
  27. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/__init__.py +0 -0
  28. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/__init__.py +0 -0
  29. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/command_utils.py +0 -0
  30. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/consts.py +0 -0
  31. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/hooks_manager.py +0 -0
  32. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/install_command.py +0 -0
  33. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/__init__.py +0 -0
  34. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/consts.py +0 -0
  35. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/handlers.py +0 -0
  36. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/payload.py +0 -0
  37. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/policy.py +0 -0
  38. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/response_builders.py +0 -0
  39. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/scan_command.py +0 -0
  40. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/types.py +0 -0
  41. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/scan/utils.py +0 -0
  42. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/status_command.py +0 -0
  43. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_guardrails/uninstall_command.py +0 -0
  44. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
  45. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
  46. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
  47. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
  48. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/auth/__init__.py +0 -0
  49. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/auth/auth_command.py +0 -0
  50. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/auth/auth_common.py +0 -0
  51. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/auth/auth_manager.py +0 -0
  52. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/auth/models.py +0 -0
  53. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/configure/__init__.py +0 -0
  54. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/configure/configure_command.py +0 -0
  55. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/configure/consts.py +0 -0
  56. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/configure/messages.py +0 -0
  57. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/configure/prompts.py +0 -0
  58. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ignore/__init__.py +0 -0
  59. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/ignore/ignore_command.py +0 -0
  60. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/mcp/__init__.py +0 -0
  61. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/mcp/mcp_command.py +0 -0
  62. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/__init__.py +0 -0
  63. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/report_command.py +0 -0
  64. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/__init__.py +0 -0
  65. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/common.py +0 -0
  66. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
  67. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
  68. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
  69. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
  70. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
  71. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report_import/__init__.py +0 -0
  72. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report_import/report_import_command.py +0 -0
  73. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report_import/sbom/__init__.py +0 -0
  74. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/report_import/sbom/sbom_command.py +0 -0
  75. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/__init__.py +0 -0
  76. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/aggregation_report.py +0 -0
  77. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/code_scanner.py +0 -0
  78. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
  79. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
  80. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/commit_range_scanner.py +0 -0
  81. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/detection_excluder.py +0 -0
  82. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/path/__init__.py +0 -0
  83. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/path/path_command.py +0 -0
  84. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
  85. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -0
  86. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/pre_push/__init__.py +0 -0
  87. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/pre_push/pre_push_command.py +0 -0
  88. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
  89. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
  90. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
  91. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/repository/__init__.py +0 -0
  92. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
  93. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
  94. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
  95. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
  96. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/scan_parameters.py +0 -0
  97. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/scan/scan_result.py +0 -0
  98. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/status/__init__.py +0 -0
  99. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/status/get_cli_status.py +0 -0
  100. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/status/models.py +0 -0
  101. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/status/status_command.py +0 -0
  102. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/apps/status/version_command.py +0 -0
  103. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/config.py +0 -0
  104. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/console.py +0 -0
  105. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/consts.py +0 -0
  106. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/__init__.py +0 -0
  107. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/custom_exceptions.py +0 -0
  108. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
  109. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
  110. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/handle_errors.py +0 -0
  111. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
  112. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
  113. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/__init__.py +0 -0
  114. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/commit_range_documents.py +0 -0
  115. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/documents_walk_ignore.py +0 -0
  116. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/file_excluder.py +0 -0
  117. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/iac/__init__.py +0 -0
  118. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
  119. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/models/__init__.py +0 -0
  120. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
  121. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/path_documents.py +0 -0
  122. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/repository_documents.py +0 -0
  123. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/__init__.py +0 -0
  124. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
  125. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
  126. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
  127. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
  128. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
  129. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
  130. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
  131. {cycode-3.10.2.dev1/cycode/cli/files_collector/sca/ruby → cycode-3.10.3/cycode/cli/files_collector/sca/php}/__init__.py +0 -0
  132. {cycode-3.10.2.dev1/cycode/cli/files_collector/sca/sbt → cycode-3.10.3/cycode/cli/files_collector/sca/python}/__init__.py +0 -0
  133. {cycode-3.10.2.dev1/cycode/cli/printers/tables → cycode-3.10.3/cycode/cli/files_collector/sca/ruby}/__init__.py +0 -0
  134. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
  135. {cycode-3.10.2.dev1/cycode/cli/printers/utils/detection_ordering → cycode-3.10.3/cycode/cli/files_collector/sca/sbt}/__init__.py +0 -0
  136. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
  137. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/walk_ignore.py +0 -0
  138. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/files_collector/zip_documents.py +0 -0
  139. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/logger.py +0 -0
  140. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/main.py +0 -0
  141. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/models.py +0 -0
  142. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/__init__.py +0 -0
  143. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/console_printer.py +0 -0
  144. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/json_printer.py +0 -0
  145. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/printer_base.py +0 -0
  146. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/rich_printer.py +0 -0
  147. {cycode-3.10.2.dev1/cycode/cli/user_settings → cycode-3.10.3/cycode/cli/printers/tables}/__init__.py +0 -0
  148. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
  149. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/tables/table.py +0 -0
  150. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/tables/table_models.py +0 -0
  151. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/tables/table_printer.py +0 -0
  152. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/tables/table_printer_base.py +0 -0
  153. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/text_printer.py +0 -0
  154. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/utils/__init__.py +0 -0
  155. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
  156. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/utils/detection_data.py +0 -0
  157. {cycode-3.10.2.dev1/cycode/cli/utils → cycode-3.10.3/cycode/cli/printers/utils/detection_ordering}/__init__.py +0 -0
  158. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
  159. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
  160. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/printers/utils/rich_helpers.py +0 -0
  161. {cycode-3.10.2.dev1/cycode/cyclient → cycode-3.10.3/cycode/cli/user_settings}/__init__.py +0 -0
  162. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/user_settings/base_file_manager.py +0 -0
  163. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/user_settings/config_file_manager.py +0 -0
  164. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/user_settings/configuration_manager.py +0 -0
  165. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/user_settings/credentials_manager.py +0 -0
  166. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/user_settings/jwt_creator.py +0 -0
  167. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/enum_utils.py +0 -0
  168. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/get_api_client.py +0 -0
  169. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/git_proxy.py +0 -0
  170. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/ignore_utils.py +0 -0
  171. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/jwt_utils.py +0 -0
  172. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/path_utils.py +0 -0
  173. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/progress_bar.py +0 -0
  174. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/scan_batch.py +0 -0
  175. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/scan_utils.py +0 -0
  176. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/shell_executor.py +0 -0
  177. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/string_utils.py +0 -0
  178. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/task_timer.py +0 -0
  179. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/url_utils.py +0 -0
  180. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/version_checker.py +0 -0
  181. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cli/utils/yaml_utils.py +0 -0
  182. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/config.py +0 -0
  183. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/ai_security_manager_client.py +0 -0
  184. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/ai_security_manager_service_config.py +0 -0
  185. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/auth_client.py +0 -0
  186. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/base_token_auth_client.py +0 -0
  187. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/client_creator.py +0 -0
  188. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/config.py +0 -0
  189. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/config_dev.py +0 -0
  190. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/cycode_client.py +0 -0
  191. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/cycode_client_base.py +0 -0
  192. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/cycode_dev_based_client.py +0 -0
  193. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/cycode_oidc_based_client.py +0 -0
  194. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/cycode_token_based_client.py +0 -0
  195. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/headers.py +0 -0
  196. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/import_sbom_client.py +0 -0
  197. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/logger.py +0 -0
  198. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/models.py +0 -0
  199. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/report_client.py +0 -0
  200. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/scan_client.py +0 -0
  201. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/cyclient/scan_config_base.py +0 -0
  202. {cycode-3.10.2.dev1 → cycode-3.10.3}/cycode/logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.10.2.dev1
3
+ Version: 3.10.3
4
4
  Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
5
5
  License-Expression: MIT
6
6
  License-File: LICENCE
@@ -710,15 +710,33 @@ In the previous example, if you wanted to only scan a branch named `dev`, you co
710
710
  > [!NOTE]
711
711
  > This option is only available to SCA scans.
712
712
 
713
- We use the sbt-dependency-lock plugin to restore the lock file for SBT projects.
714
- To disable lock restore in use `--no-restore` option.
713
+ When running an SCA scan, Cycode CLI automatically attempts to restore (generate) a dependency lockfile for each supported manifest file it finds. This allows scanning transitive dependencies, not just the ones listed directly in the manifest. To skip this step and scan only direct dependencies, use the `--no-restore` flag.
715
714
 
716
- Prerequisites:
717
- * `sbt-dependency-lock` plugin: Install the plugin by adding the following line to `project/plugins.sbt`:
715
+ The following ecosystems support automatic lockfile restoration:
718
716
 
719
- ```text
720
- addSbtPlugin("software.purpledragon" % "sbt-dependency-lock" % "1.5.1")
721
- ```
717
+ | Ecosystem | Manifest file | Lockfile generated | Tool invoked (when lockfile is absent) |
718
+ |---|---|---|---|
719
+ | npm | `package.json` | `package-lock.json` | `npm install --package-lock-only --ignore-scripts --no-audit` |
720
+ | Yarn | `package.json` | `yarn.lock` | `yarn install --ignore-scripts` |
721
+ | pnpm | `package.json` | `pnpm-lock.yaml` | `pnpm install --ignore-scripts` |
722
+ | Deno | `deno.json` / `deno.jsonc` | `deno.lock` | *(read existing lockfile only)* |
723
+ | Go | `go.mod` | `go.mod.graph` | `go list -m -json all` + `go mod graph` |
724
+ | Maven | `pom.xml` | `bcde.mvndeps` | `mvn dependency:tree` |
725
+ | Gradle | `build.gradle` / `build.gradle.kts` | `gradle-dependencies-generated.txt` | `gradle dependencies -q --console plain` |
726
+ | SBT | `build.sbt` | `build.sbt.lock` | `sbt dependencyLockWrite` |
727
+ | NuGet | `*.csproj` | `packages.lock.json` | `dotnet restore --use-lock-file` |
728
+ | Ruby | `Gemfile` | `Gemfile.lock` | `bundle --quiet` |
729
+ | Poetry | `pyproject.toml` | `poetry.lock` | `poetry lock` |
730
+ | Pipenv | `Pipfile` | `Pipfile.lock` | `pipenv lock` |
731
+ | PHP Composer | `composer.json` | `composer.lock` | `composer update --no-cache --no-install --no-scripts --ignore-platform-reqs` |
732
+
733
+ If a lockfile already exists alongside the manifest, Cycode reads it directly without running any install command.
734
+
735
+ **SBT prerequisite:** The `sbt-dependency-lock` plugin must be installed. Add the following line to `project/plugins.sbt`:
736
+
737
+ ```text
738
+ addSbtPlugin("software.purpledragon" % "sbt-dependency-lock" % "1.5.1")
739
+ ```
722
740
 
723
741
  ### Repository Scan
724
742
 
@@ -1351,9 +1369,11 @@ For example:\
1351
1369
 
1352
1370
  The `path` subcommand supports the following additional options:
1353
1371
 
1354
- | Option | Description |
1355
- |-------------------------|----------------------------------------------------------------------------------------------------------------------------------|
1356
- | `--maven-settings-file` | For Maven only, allows using a custom [settings.xml](https://maven.apache.org/settings.html) file when building the dependency tree |
1372
+ | Option | Description |
1373
+ |-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
1374
+ | `--no-restore` | Skip lockfile restoration and scan direct dependencies only. See [Lock Restore Option](#lock-restore-option) for details. |
1375
+ | `--gradle-all-sub-projects` | Run the Gradle restore command for all sub-projects (use from the root of a multi-project Gradle build). |
1376
+ | `--maven-settings-file` | For Maven only, allows using a custom [settings.xml](https://maven.apache.org/settings.html) file when building the dependency tree. |
1357
1377
 
1358
1378
  # Import Command
1359
1379
 
@@ -668,15 +668,33 @@ In the previous example, if you wanted to only scan a branch named `dev`, you co
668
668
  > [!NOTE]
669
669
  > This option is only available to SCA scans.
670
670
 
671
- We use the sbt-dependency-lock plugin to restore the lock file for SBT projects.
672
- To disable lock restore in use `--no-restore` option.
673
-
674
- Prerequisites:
675
- * `sbt-dependency-lock` plugin: Install the plugin by adding the following line to `project/plugins.sbt`:
676
-
677
- ```text
678
- addSbtPlugin("software.purpledragon" % "sbt-dependency-lock" % "1.5.1")
679
- ```
671
+ When running an SCA scan, Cycode CLI automatically attempts to restore (generate) a dependency lockfile for each supported manifest file it finds. This allows scanning transitive dependencies, not just the ones listed directly in the manifest. To skip this step and scan only direct dependencies, use the `--no-restore` flag.
672
+
673
+ The following ecosystems support automatic lockfile restoration:
674
+
675
+ | Ecosystem | Manifest file | Lockfile generated | Tool invoked (when lockfile is absent) |
676
+ |---|---|---|---|
677
+ | npm | `package.json` | `package-lock.json` | `npm install --package-lock-only --ignore-scripts --no-audit` |
678
+ | Yarn | `package.json` | `yarn.lock` | `yarn install --ignore-scripts` |
679
+ | pnpm | `package.json` | `pnpm-lock.yaml` | `pnpm install --ignore-scripts` |
680
+ | Deno | `deno.json` / `deno.jsonc` | `deno.lock` | *(read existing lockfile only)* |
681
+ | Go | `go.mod` | `go.mod.graph` | `go list -m -json all` + `go mod graph` |
682
+ | Maven | `pom.xml` | `bcde.mvndeps` | `mvn dependency:tree` |
683
+ | Gradle | `build.gradle` / `build.gradle.kts` | `gradle-dependencies-generated.txt` | `gradle dependencies -q --console plain` |
684
+ | SBT | `build.sbt` | `build.sbt.lock` | `sbt dependencyLockWrite` |
685
+ | NuGet | `*.csproj` | `packages.lock.json` | `dotnet restore --use-lock-file` |
686
+ | Ruby | `Gemfile` | `Gemfile.lock` | `bundle --quiet` |
687
+ | Poetry | `pyproject.toml` | `poetry.lock` | `poetry lock` |
688
+ | Pipenv | `Pipfile` | `Pipfile.lock` | `pipenv lock` |
689
+ | PHP Composer | `composer.json` | `composer.lock` | `composer update --no-cache --no-install --no-scripts --ignore-platform-reqs` |
690
+
691
+ If a lockfile already exists alongside the manifest, Cycode reads it directly without running any install command.
692
+
693
+ **SBT prerequisite:** The `sbt-dependency-lock` plugin must be installed. Add the following line to `project/plugins.sbt`:
694
+
695
+ ```text
696
+ addSbtPlugin("software.purpledragon" % "sbt-dependency-lock" % "1.5.1")
697
+ ```
680
698
 
681
699
  ### Repository Scan
682
700
 
@@ -1309,9 +1327,11 @@ For example:\
1309
1327
 
1310
1328
  The `path` subcommand supports the following additional options:
1311
1329
 
1312
- | Option | Description |
1313
- |-------------------------|----------------------------------------------------------------------------------------------------------------------------------|
1314
- | `--maven-settings-file` | For Maven only, allows using a custom [settings.xml](https://maven.apache.org/settings.html) file when building the dependency tree |
1330
+ | Option | Description |
1331
+ |-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
1332
+ | `--no-restore` | Skip lockfile restoration and scan direct dependencies only. See [Lock Restore Option](#lock-restore-option) for details. |
1333
+ | `--gradle-all-sub-projects` | Run the Gradle restore command for all sub-projects (use from the root of a multi-project Gradle build). |
1334
+ | `--maven-settings-file` | For Maven only, allows using a custom [settings.xml](https://maven.apache.org/settings.html) file when building the dependency tree. |
1315
1335
 
1316
1336
  # Import Command
1317
1337
 
@@ -0,0 +1 @@
1
+ __version__ = '3.10.3' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -1,11 +1,17 @@
1
1
  import time
2
2
  from pathlib import Path
3
- from typing import Annotated, Optional
3
+ from typing import Annotated
4
4
 
5
5
  import typer
6
6
 
7
7
  from cycode.cli import consts
8
8
  from cycode.cli.apps.report.sbom.common import create_sbom_report, send_report_feedback
9
+ from cycode.cli.apps.sca_options import (
10
+ GradleAllSubProjectsOption,
11
+ MavenSettingsFileOption,
12
+ NoRestoreOption,
13
+ apply_sca_restore_options_to_context,
14
+ )
9
15
  from cycode.cli.exceptions.handle_report_sbom_errors import handle_report_exception
10
16
  from cycode.cli.files_collector.path_documents import get_relevant_documents
11
17
  from cycode.cli.files_collector.sca.sca_file_collector import add_sca_dependencies_tree_documents_if_needed
@@ -14,8 +20,6 @@ from cycode.cli.utils.get_api_client import get_report_cycode_client
14
20
  from cycode.cli.utils.progress_bar import SbomReportProgressBarSection
15
21
  from cycode.cli.utils.scan_utils import is_cycodeignore_allowed_by_scan_config
16
22
 
17
- _SCA_RICH_HELP_PANEL = 'SCA options'
18
-
19
23
 
20
24
  def path_command(
21
25
  ctx: typer.Context,
@@ -23,18 +27,11 @@ def path_command(
23
27
  Path,
24
28
  typer.Argument(exists=True, resolve_path=True, help='Path to generate SBOM report for.', show_default=False),
25
29
  ],
26
- maven_settings_file: Annotated[
27
- Optional[Path],
28
- typer.Option(
29
- '--maven-settings-file',
30
- show_default=False,
31
- help='When specified, Cycode will use this settings.xml file when building the maven dependency tree.',
32
- dir_okay=False,
33
- rich_help_panel=_SCA_RICH_HELP_PANEL,
34
- ),
35
- ] = None,
30
+ no_restore: NoRestoreOption = False,
31
+ gradle_all_sub_projects: GradleAllSubProjectsOption = False,
32
+ maven_settings_file: MavenSettingsFileOption = None,
36
33
  ) -> None:
37
- ctx.obj['maven_settings_file'] = maven_settings_file
34
+ apply_sca_restore_options_to_context(ctx, no_restore, gradle_all_sub_projects, maven_settings_file)
38
35
 
39
36
  client = get_report_cycode_client(ctx)
40
37
  report_parameters = ctx.obj['report_parameters']
@@ -0,0 +1,47 @@
1
+ from pathlib import Path
2
+ from typing import Annotated, Optional
3
+
4
+ import typer
5
+
6
+ _SCA_RICH_HELP_PANEL = 'SCA options'
7
+
8
+ NoRestoreOption = Annotated[
9
+ bool,
10
+ typer.Option(
11
+ '--no-restore',
12
+ help='When specified, Cycode will not run restore command. Will scan direct dependencies [b]only[/]!',
13
+ rich_help_panel=_SCA_RICH_HELP_PANEL,
14
+ ),
15
+ ]
16
+
17
+ GradleAllSubProjectsOption = Annotated[
18
+ bool,
19
+ typer.Option(
20
+ '--gradle-all-sub-projects',
21
+ help='When specified, Cycode will run gradle restore command for all sub projects. '
22
+ 'Should run from root project directory [b]only[/]!',
23
+ rich_help_panel=_SCA_RICH_HELP_PANEL,
24
+ ),
25
+ ]
26
+
27
+ MavenSettingsFileOption = Annotated[
28
+ Optional[Path],
29
+ typer.Option(
30
+ '--maven-settings-file',
31
+ show_default=False,
32
+ help='When specified, Cycode will use this settings.xml file when building the maven dependency tree.',
33
+ dir_okay=False,
34
+ rich_help_panel=_SCA_RICH_HELP_PANEL,
35
+ ),
36
+ ]
37
+
38
+
39
+ def apply_sca_restore_options_to_context(
40
+ ctx: typer.Context,
41
+ no_restore: bool,
42
+ gradle_all_sub_projects: bool,
43
+ maven_settings_file: Optional[Path],
44
+ ) -> None:
45
+ ctx.obj['no_restore'] = no_restore
46
+ ctx.obj['gradle_all_sub_projects'] = gradle_all_sub_projects
47
+ ctx.obj['maven_settings_file'] = maven_settings_file
@@ -5,6 +5,12 @@ from typing import Annotated, Optional
5
5
  import click
6
6
  import typer
7
7
 
8
+ from cycode.cli.apps.sca_options import (
9
+ GradleAllSubProjectsOption,
10
+ MavenSettingsFileOption,
11
+ NoRestoreOption,
12
+ apply_sca_restore_options_to_context,
13
+ )
8
14
  from cycode.cli.apps.scan.remote_url_resolver import _try_get_git_remote_url
9
15
  from cycode.cli.cli_types import ExportTypeOption, ScanTypeOption, ScaScanTypeOption, SeverityOption
10
16
  from cycode.cli.consts import (
@@ -72,33 +78,9 @@ def scan_command(
72
78
  rich_help_panel=_SCA_RICH_HELP_PANEL,
73
79
  ),
74
80
  ] = False,
75
- no_restore: Annotated[
76
- bool,
77
- typer.Option(
78
- '--no-restore',
79
- help='When specified, Cycode will not run restore command. Will scan direct dependencies [b]only[/]!',
80
- rich_help_panel=_SCA_RICH_HELP_PANEL,
81
- ),
82
- ] = False,
83
- gradle_all_sub_projects: Annotated[
84
- bool,
85
- typer.Option(
86
- '--gradle-all-sub-projects',
87
- help='When specified, Cycode will run gradle restore command for all sub projects. '
88
- 'Should run from root project directory [b]only[/]!',
89
- rich_help_panel=_SCA_RICH_HELP_PANEL,
90
- ),
91
- ] = False,
92
- maven_settings_file: Annotated[
93
- Optional[Path],
94
- typer.Option(
95
- '--maven-settings-file',
96
- show_default=False,
97
- help='When specified, Cycode will use this settings.xml file when building the maven dependency tree.',
98
- dir_okay=False,
99
- rich_help_panel=_SCA_RICH_HELP_PANEL,
100
- ),
101
- ] = None,
81
+ no_restore: NoRestoreOption = False,
82
+ gradle_all_sub_projects: GradleAllSubProjectsOption = False,
83
+ maven_settings_file: MavenSettingsFileOption = None,
102
84
  export_type: Annotated[
103
85
  ExportTypeOption,
104
86
  typer.Option(
@@ -152,10 +134,8 @@ def scan_command(
152
134
  ctx.obj['sync'] = sync
153
135
  ctx.obj['severity_threshold'] = severity_threshold
154
136
  ctx.obj['monitor'] = monitor
155
- ctx.obj['maven_settings_file'] = maven_settings_file
156
137
  ctx.obj['report'] = report
157
- ctx.obj['gradle_all_sub_projects'] = gradle_all_sub_projects
158
- ctx.obj['no_restore'] = no_restore
138
+ apply_sca_restore_options_to_context(ctx, no_restore, gradle_all_sub_projects, maven_settings_file)
159
139
 
160
140
  scan_client = get_scan_cycode_client(ctx)
161
141
  ctx.obj['client'] = scan_client
@@ -46,6 +46,7 @@ class SbomFormatOption(StrEnum):
46
46
  SPDX_2_2 = 'spdx-2.2'
47
47
  SPDX_2_3 = 'spdx-2.3'
48
48
  CYCLONEDX_1_4 = 'cyclonedx-1.4'
49
+ CYCLONEDX_1_6 = 'cyclonedx-1.6'
49
50
 
50
51
 
51
52
  class SbomOutputFormatOption(StrEnum):
@@ -1,5 +1,5 @@
1
- import os
2
1
  from abc import ABC, abstractmethod
2
+ from pathlib import Path
3
3
  from typing import Optional
4
4
 
5
5
  import typer
@@ -32,6 +32,9 @@ def execute_commands(
32
32
  },
33
33
  )
34
34
 
35
+ if not commands:
36
+ return None
37
+
35
38
  try:
36
39
  outputs = []
37
40
 
@@ -106,22 +109,43 @@ class BaseRestoreDependencies(ABC):
106
109
  )
107
110
  return Document(relative_restore_file_path, restore_file_content, self.is_git_diff)
108
111
 
112
+ def get_manifest_dir(self, document: Document) -> Optional[str]:
113
+ """Return the directory containing the manifest file, resolving monitor-mode paths.
114
+
115
+ Uses the same path resolution as get_manifest_file_path() to ensure consistency.
116
+ Falls back to document.absolute_path when the resolved manifest path is ambiguous.
117
+ """
118
+ manifest_file_path = self.get_manifest_file_path(document)
119
+ if manifest_file_path:
120
+ parent = Path(manifest_file_path).parent
121
+ # Skip '.' (no parent) and filesystem root (its own parent)
122
+ if parent != Path('.') and parent != parent.parent:
123
+ return str(parent)
124
+
125
+ base = document.absolute_path or document.path
126
+ if base:
127
+ parent = Path(base).parent
128
+ if parent != Path('.') and parent != parent.parent:
129
+ return str(parent)
130
+
131
+ return None
132
+
109
133
  def get_working_directory(self, document: Document) -> Optional[str]:
110
- return os.path.dirname(document.absolute_path)
134
+ return str(Path(document.absolute_path).parent)
111
135
 
112
136
  def get_restored_lock_file_name(self, restore_file_path: str) -> str:
113
137
  return self.get_lock_file_name()
114
138
 
115
139
  def get_any_restore_file_already_exist(self, document: Document, restore_file_paths: list[str]) -> str:
116
140
  for restore_file_path in restore_file_paths:
117
- if os.path.isfile(restore_file_path):
141
+ if Path(restore_file_path).is_file():
118
142
  return restore_file_path
119
143
 
120
144
  return build_dep_tree_path(document.absolute_path, self.get_lock_file_name())
121
145
 
122
146
  @staticmethod
123
147
  def verify_restore_file_already_exist(restore_file_path: str) -> bool:
124
- return os.path.isfile(restore_file_path)
148
+ return Path(restore_file_path).is_file()
125
149
 
126
150
  @abstractmethod
127
151
  def is_project(self, document: Document) -> bool:
@@ -1,4 +1,4 @@
1
- import os
1
+ from pathlib import Path
2
2
  from typing import Optional
3
3
 
4
4
  import typer
@@ -20,13 +20,13 @@ class RestoreGoDependencies(BaseRestoreDependencies):
20
20
  super().__init__(ctx, is_git_diff, command_timeout, create_output_file_manually=True)
21
21
 
22
22
  def try_restore_dependencies(self, document: Document) -> Optional[Document]:
23
- manifest_exists = os.path.isfile(self.get_working_directory(document) + os.sep + BUILD_GO_FILE_NAME)
24
- lock_exists = os.path.isfile(self.get_working_directory(document) + os.sep + BUILD_GO_LOCK_FILE_NAME)
23
+ manifest_exists = (Path(self.get_working_directory(document)) / BUILD_GO_FILE_NAME).is_file()
24
+ lock_exists = (Path(self.get_working_directory(document)) / BUILD_GO_LOCK_FILE_NAME).is_file()
25
25
 
26
26
  if not manifest_exists or not lock_exists:
27
27
  logger.info('No manifest go.mod file found' if not manifest_exists else 'No manifest go.sum file found')
28
28
 
29
- manifest_files_exists = manifest_exists & lock_exists
29
+ manifest_files_exists = manifest_exists and lock_exists
30
30
 
31
31
  if not manifest_files_exists:
32
32
  return None
@@ -0,0 +1,46 @@
1
+ from pathlib import Path
2
+ from typing import Optional
3
+
4
+ import typer
5
+
6
+ from cycode.cli.files_collector.sca.base_restore_dependencies import BaseRestoreDependencies, build_dep_tree_path
7
+ from cycode.cli.models import Document
8
+ from cycode.cli.utils.path_utils import get_file_content
9
+ from cycode.logger import get_logger
10
+
11
+ logger = get_logger('Deno Restore Dependencies')
12
+
13
+ DENO_MANIFEST_FILE_NAMES = ('deno.json', 'deno.jsonc')
14
+ DENO_LOCK_FILE_NAME = 'deno.lock'
15
+
16
+
17
+ class RestoreDenoDependencies(BaseRestoreDependencies):
18
+ def __init__(self, ctx: typer.Context, is_git_diff: bool, command_timeout: int) -> None:
19
+ super().__init__(ctx, is_git_diff, command_timeout)
20
+
21
+ def is_project(self, document: Document) -> bool:
22
+ return Path(document.path).name in DENO_MANIFEST_FILE_NAMES
23
+
24
+ def try_restore_dependencies(self, document: Document) -> Optional[Document]:
25
+ manifest_dir = self.get_manifest_dir(document)
26
+ if not manifest_dir:
27
+ return None
28
+
29
+ lockfile_path = Path(manifest_dir) / DENO_LOCK_FILE_NAME
30
+ if not lockfile_path.is_file():
31
+ logger.debug('No deno.lock found alongside deno.json, skipping deno restore, %s', {'path': document.path})
32
+ return None
33
+
34
+ content = get_file_content(str(lockfile_path))
35
+ relative_path = build_dep_tree_path(document.path, DENO_LOCK_FILE_NAME)
36
+ logger.debug('Using existing deno.lock, %s', {'path': str(lockfile_path)})
37
+ return Document(relative_path, content, self.is_git_diff)
38
+
39
+ def get_commands(self, manifest_file_path: str) -> list[list[str]]:
40
+ return []
41
+
42
+ def get_lock_file_name(self) -> str:
43
+ return DENO_LOCK_FILE_NAME
44
+
45
+ def get_lock_file_names(self) -> list[str]:
46
+ return [DENO_LOCK_FILE_NAME]
@@ -0,0 +1,67 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from cycode.cli.files_collector.sca.base_restore_dependencies import BaseRestoreDependencies
6
+ from cycode.cli.models import Document
7
+ from cycode.logger import get_logger
8
+
9
+ logger = get_logger('NPM Restore Dependencies')
10
+
11
+ NPM_MANIFEST_FILE_NAME = 'package.json'
12
+ NPM_LOCK_FILE_NAME = 'package-lock.json'
13
+ # These lockfiles indicate another package manager owns the project — NPM should not run
14
+ _ALTERNATIVE_LOCK_FILES = ('yarn.lock', 'pnpm-lock.yaml', 'deno.lock')
15
+
16
+
17
+ class RestoreNpmDependencies(BaseRestoreDependencies):
18
+ def __init__(self, ctx: typer.Context, is_git_diff: bool, command_timeout: int) -> None:
19
+ super().__init__(ctx, is_git_diff, command_timeout)
20
+
21
+ def is_project(self, document: Document) -> bool:
22
+ """Match only package.json files that are not managed by Yarn or pnpm.
23
+
24
+ Yarn and pnpm projects are handled by their dedicated handlers, which run before
25
+ this one in the handler list. This handler is the npm fallback.
26
+ """
27
+ if Path(document.path).name != NPM_MANIFEST_FILE_NAME:
28
+ return False
29
+
30
+ manifest_dir = self.get_manifest_dir(document)
31
+ if manifest_dir:
32
+ for lock_file in _ALTERNATIVE_LOCK_FILES:
33
+ if (Path(manifest_dir) / lock_file).is_file():
34
+ logger.debug(
35
+ 'Skipping npm restore: alternative lockfile detected, %s',
36
+ {'path': document.path, 'lockfile': lock_file},
37
+ )
38
+ return False
39
+
40
+ return True
41
+
42
+ def get_commands(self, manifest_file_path: str) -> list[list[str]]:
43
+ return [
44
+ [
45
+ 'npm',
46
+ 'install',
47
+ '--prefix',
48
+ self.prepare_manifest_file_path_for_command(manifest_file_path),
49
+ '--package-lock-only',
50
+ '--ignore-scripts',
51
+ '--no-audit',
52
+ ]
53
+ ]
54
+
55
+ def get_lock_file_name(self) -> str:
56
+ return NPM_LOCK_FILE_NAME
57
+
58
+ def get_lock_file_names(self) -> list[str]:
59
+ return [NPM_LOCK_FILE_NAME]
60
+
61
+ @staticmethod
62
+ def prepare_manifest_file_path_for_command(manifest_file_path: str) -> str:
63
+ if manifest_file_path.endswith(NPM_MANIFEST_FILE_NAME):
64
+ parent = Path(manifest_file_path).parent
65
+ dir_path = str(parent)
66
+ return dir_path if dir_path and dir_path != '.' else ''
67
+ return manifest_file_path
@@ -0,0 +1,70 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from cycode.cli.files_collector.sca.base_restore_dependencies import BaseRestoreDependencies, build_dep_tree_path
8
+ from cycode.cli.models import Document
9
+ from cycode.cli.utils.path_utils import get_file_content
10
+ from cycode.logger import get_logger
11
+
12
+ logger = get_logger('Pnpm Restore Dependencies')
13
+
14
+ PNPM_MANIFEST_FILE_NAME = 'package.json'
15
+ PNPM_LOCK_FILE_NAME = 'pnpm-lock.yaml'
16
+
17
+
18
+ def _indicates_pnpm(package_json_content: Optional[str]) -> bool:
19
+ """Return True if package.json content signals that this project uses pnpm."""
20
+ if not package_json_content:
21
+ return False
22
+ try:
23
+ data = json.loads(package_json_content)
24
+ except (json.JSONDecodeError, ValueError):
25
+ return False
26
+
27
+ package_manager = data.get('packageManager', '')
28
+ if isinstance(package_manager, str) and package_manager.startswith('pnpm'):
29
+ return True
30
+
31
+ engines = data.get('engines', {})
32
+ return isinstance(engines, dict) and 'pnpm' in engines
33
+
34
+
35
+ class RestorePnpmDependencies(BaseRestoreDependencies):
36
+ def __init__(self, ctx: typer.Context, is_git_diff: bool, command_timeout: int) -> None:
37
+ super().__init__(ctx, is_git_diff, command_timeout)
38
+
39
+ def is_project(self, document: Document) -> bool:
40
+ if Path(document.path).name != PNPM_MANIFEST_FILE_NAME:
41
+ return False
42
+
43
+ manifest_dir = self.get_manifest_dir(document)
44
+ if manifest_dir and (Path(manifest_dir) / PNPM_LOCK_FILE_NAME).is_file():
45
+ return True
46
+
47
+ return _indicates_pnpm(document.content)
48
+
49
+ def try_restore_dependencies(self, document: Document) -> Optional[Document]:
50
+ manifest_dir = self.get_manifest_dir(document)
51
+ lockfile_path = Path(manifest_dir) / PNPM_LOCK_FILE_NAME if manifest_dir else None
52
+
53
+ if lockfile_path and lockfile_path.is_file():
54
+ # Lockfile already exists — read it directly without running pnpm
55
+ content = get_file_content(str(lockfile_path))
56
+ relative_path = build_dep_tree_path(document.path, PNPM_LOCK_FILE_NAME)
57
+ logger.debug('Using existing pnpm-lock.yaml, %s', {'path': str(lockfile_path)})
58
+ return Document(relative_path, content, self.is_git_diff)
59
+
60
+ # Lockfile absent but pnpm is indicated in package.json — generate it
61
+ return super().try_restore_dependencies(document)
62
+
63
+ def get_commands(self, manifest_file_path: str) -> list[list[str]]:
64
+ return [['pnpm', 'install', '--ignore-scripts']]
65
+
66
+ def get_lock_file_name(self) -> str:
67
+ return PNPM_LOCK_FILE_NAME
68
+
69
+ def get_lock_file_names(self) -> list[str]:
70
+ return [PNPM_LOCK_FILE_NAME]
@@ -0,0 +1,70 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from cycode.cli.files_collector.sca.base_restore_dependencies import BaseRestoreDependencies, build_dep_tree_path
8
+ from cycode.cli.models import Document
9
+ from cycode.cli.utils.path_utils import get_file_content
10
+ from cycode.logger import get_logger
11
+
12
+ logger = get_logger('Yarn Restore Dependencies')
13
+
14
+ YARN_MANIFEST_FILE_NAME = 'package.json'
15
+ YARN_LOCK_FILE_NAME = 'yarn.lock'
16
+
17
+
18
+ def _indicates_yarn(package_json_content: Optional[str]) -> bool:
19
+ """Return True if package.json content signals that this project uses Yarn."""
20
+ if not package_json_content:
21
+ return False
22
+ try:
23
+ data = json.loads(package_json_content)
24
+ except (json.JSONDecodeError, ValueError):
25
+ return False
26
+
27
+ package_manager = data.get('packageManager', '')
28
+ if isinstance(package_manager, str) and package_manager.startswith('yarn'):
29
+ return True
30
+
31
+ engines = data.get('engines', {})
32
+ return isinstance(engines, dict) and 'yarn' in engines
33
+
34
+
35
+ class RestoreYarnDependencies(BaseRestoreDependencies):
36
+ def __init__(self, ctx: typer.Context, is_git_diff: bool, command_timeout: int) -> None:
37
+ super().__init__(ctx, is_git_diff, command_timeout)
38
+
39
+ def is_project(self, document: Document) -> bool:
40
+ if Path(document.path).name != YARN_MANIFEST_FILE_NAME:
41
+ return False
42
+
43
+ manifest_dir = self.get_manifest_dir(document)
44
+ if manifest_dir and (Path(manifest_dir) / YARN_LOCK_FILE_NAME).is_file():
45
+ return True
46
+
47
+ return _indicates_yarn(document.content)
48
+
49
+ def try_restore_dependencies(self, document: Document) -> Optional[Document]:
50
+ manifest_dir = self.get_manifest_dir(document)
51
+ lockfile_path = Path(manifest_dir) / YARN_LOCK_FILE_NAME if manifest_dir else None
52
+
53
+ if lockfile_path and lockfile_path.is_file():
54
+ # Lockfile already exists — read it directly without running yarn
55
+ content = get_file_content(str(lockfile_path))
56
+ relative_path = build_dep_tree_path(document.path, YARN_LOCK_FILE_NAME)
57
+ logger.debug('Using existing yarn.lock, %s', {'path': str(lockfile_path)})
58
+ return Document(relative_path, content, self.is_git_diff)
59
+
60
+ # Lockfile absent but yarn is indicated in package.json — generate it
61
+ return super().try_restore_dependencies(document)
62
+
63
+ def get_commands(self, manifest_file_path: str) -> list[list[str]]:
64
+ return [['yarn', 'install', '--ignore-scripts']]
65
+
66
+ def get_lock_file_name(self) -> str:
67
+ return YARN_LOCK_FILE_NAME
68
+
69
+ def get_lock_file_names(self) -> list[str]:
70
+ return [YARN_LOCK_FILE_NAME]