entrygraph 0.1.45__tar.gz → 0.1.47__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 (204) hide show
  1. {entrygraph-0.1.45 → entrygraph-0.1.47}/PKG-INFO +1 -1
  2. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/_version.py +2 -2
  3. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/csharp.py +79 -28
  4. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/rust.py +32 -2
  5. entrygraph-0.1.47/tests/test_entrypoints_csharp.py +75 -0
  6. entrygraph-0.1.47/tests/test_entrypoints_rust.py +53 -0
  7. {entrygraph-0.1.45 → entrygraph-0.1.47}/.github/workflows/ci.yml +0 -0
  8. {entrygraph-0.1.45 → entrygraph-0.1.47}/.github/workflows/release.yml +0 -0
  9. {entrygraph-0.1.45 → entrygraph-0.1.47}/.gitignore +0 -0
  10. {entrygraph-0.1.45 → entrygraph-0.1.47}/LICENSE +0 -0
  11. {entrygraph-0.1.45 → entrygraph-0.1.47}/README.md +0 -0
  12. {entrygraph-0.1.45 → entrygraph-0.1.47}/RELEASING.md +0 -0
  13. {entrygraph-0.1.45 → entrygraph-0.1.47}/pyproject.toml +0 -0
  14. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/__init__.py +0 -0
  15. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/__main__.py +0 -0
  16. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/api.py +0 -0
  17. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/cli/__init__.py +0 -0
  18. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/cli/main.py +0 -0
  19. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/cli/render.py +0 -0
  20. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/csharp.toml +0 -0
  21. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/go.toml +0 -0
  22. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/java.toml +0 -0
  23. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/javascript.toml +0 -0
  24. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/lib_javascript.toml +0 -0
  25. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/lib_python.toml +0 -0
  26. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/php.toml +0 -0
  27. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/python.toml +0 -0
  28. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/ruby.toml +0 -0
  29. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/data/sinks/rust.toml +0 -0
  30. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/db/__init__.py +0 -0
  31. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/db/engine.py +0 -0
  32. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/db/meta.py +0 -0
  33. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/db/models.py +0 -0
  34. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/db/queries.py +0 -0
  35. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/__init__.py +0 -0
  36. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/__init__.py +0 -0
  37. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/base.py +0 -0
  38. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/configs.py +0 -0
  39. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/golang.py +0 -0
  40. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/java.py +0 -0
  41. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/javascript.py +0 -0
  42. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/php.py +0 -0
  43. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/python.py +0 -0
  44. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/entrypoints/ruby.py +0 -0
  45. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/frameworks.py +0 -0
  46. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/manifests.py +0 -0
  47. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/detect/taint.py +0 -0
  48. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/errors.py +0 -0
  49. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/__init__.py +0 -0
  50. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/base.py +0 -0
  51. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/csharp.py +0 -0
  52. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/golang.py +0 -0
  53. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/ir.py +0 -0
  54. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/java.py +0 -0
  55. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/javascript.py +0 -0
  56. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/php.py +0 -0
  57. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/python.py +0 -0
  58. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/registry.py +0 -0
  59. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/ruby.py +0 -0
  60. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/extract/rust.py +0 -0
  61. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/fs/__init__.py +0 -0
  62. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/fs/hashing.py +0 -0
  63. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/fs/lang.py +0 -0
  64. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/fs/walker.py +0 -0
  65. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/graph/__init__.py +0 -0
  66. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/graph/adjacency.py +0 -0
  67. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/graph/cte.py +0 -0
  68. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/graph/scoring.py +0 -0
  69. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/kinds.py +0 -0
  70. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/parsing/__init__.py +0 -0
  71. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/parsing/parsers.py +0 -0
  72. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/parsing/queries.py +0 -0
  73. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/pipeline/__init__.py +0 -0
  74. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/pipeline/scanner.py +0 -0
  75. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/pipeline/worker.py +0 -0
  76. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/pipeline/writer.py +0 -0
  77. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/py.typed +0 -0
  78. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/csharp/calls.scm +0 -0
  79. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/csharp/definitions.scm +0 -0
  80. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/csharp/imports.scm +0 -0
  81. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/go/calls.scm +0 -0
  82. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/go/definitions.scm +0 -0
  83. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/go/imports.scm +0 -0
  84. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/java/calls.scm +0 -0
  85. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/java/definitions.scm +0 -0
  86. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/java/imports.scm +0 -0
  87. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/javascript/calls.scm +0 -0
  88. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/javascript/definitions.scm +0 -0
  89. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/javascript/imports.scm +0 -0
  90. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/php/calls.scm +0 -0
  91. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/php/definitions.scm +0 -0
  92. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/php/imports.scm +0 -0
  93. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/python/calls.scm +0 -0
  94. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/python/definitions.scm +0 -0
  95. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/python/imports.scm +0 -0
  96. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/ruby/calls.scm +0 -0
  97. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/ruby/definitions.scm +0 -0
  98. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/ruby/imports.scm +0 -0
  99. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/rust/calls.scm +0 -0
  100. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/rust/definitions.scm +0 -0
  101. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/queries/rust/imports.scm +0 -0
  102. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/resolve/__init__.py +0 -0
  103. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/resolve/externals.py +0 -0
  104. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/resolve/hierarchy.py +0 -0
  105. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/resolve/resolver.py +0 -0
  106. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/resolve/symbol_table.py +0 -0
  107. {entrygraph-0.1.45 → entrygraph-0.1.47}/src/entrygraph/results.py +0 -0
  108. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/conftest.py +0 -0
  109. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/csharp/aspnet_app/Controllers/ReportsController.cs +0 -0
  110. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/csharp/aspnet_app/Program.cs +0 -0
  111. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/csharp/aspnet_app/Services/ReportService.cs +0 -0
  112. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/csharp/aspnet_app/app.csproj +0 -0
  113. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/csharp/minimalapi_app/Program.cs +0 -0
  114. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/csharp/minimalapi_app/app.csproj +0 -0
  115. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/go/gin_app/go.mod +0 -0
  116. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/go/gin_app/main.go +0 -0
  117. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/go/gin_app/service.go +0 -0
  118. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/go/nethttp_app/go.mod +0 -0
  119. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/go/nethttp_app/main.go +0 -0
  120. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/methodref_app/pom.xml +0 -0
  121. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/methodref_app/src/main/java/com/example/App.java +0 -0
  122. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/spring_app/pom.xml +0 -0
  123. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/spring_app/src/main/java/com/example/Application.java +0 -0
  124. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportRunner.java +0 -0
  125. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportService.java +0 -0
  126. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/java/spring_app/src/main/java/com/example/UserController.java +0 -0
  127. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/javascript/commonjs_app/server.js +0 -0
  128. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/javascript/express_app/package.json +0 -0
  129. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/javascript/express_app/src/routes.js +0 -0
  130. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/javascript/express_app/src/services.js +0 -0
  131. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/php/laravel_app/app/Http/Controllers/ReportController.php +0 -0
  132. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/php/laravel_app/artisan +0 -0
  133. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/php/laravel_app/composer.json +0 -0
  134. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/php/laravel_app/routes/web.php +0 -0
  135. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/chained_sinks/app.py +0 -0
  136. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/flask_app/app/__init__.py +0 -0
  137. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/flask_app/app/db.py +0 -0
  138. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/flask_app/app/routes.py +0 -0
  139. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/flask_app/app/services.py +0 -0
  140. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/flask_app/cli.py +0 -0
  141. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/flask_app/requirements.txt +0 -0
  142. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/fuzzy_sink/app.py +0 -0
  143. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/heal_fidelity/caller.py +0 -0
  144. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/heal_fidelity/worker.py +0 -0
  145. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/may_continue/app.py +0 -0
  146. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/sanitizer/app.py +0 -0
  147. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/python/taint_source/handler.py +0 -0
  148. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/ruby/sinatra_app/Gemfile +0 -0
  149. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/ruby/sinatra_app/app.rb +0 -0
  150. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/ruby/sinatra_app/services/runner.rb +0 -0
  151. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/axum_app/Cargo.toml +0 -0
  152. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/axum_app/src/handlers.rs +0 -0
  153. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/axum_app/src/main.rs +0 -0
  154. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/axum_callback_app/Cargo.toml +0 -0
  155. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/axum_callback_app/src/main.rs +0 -0
  156. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/scoped_sink_app/Cargo.toml +0 -0
  157. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/fixtures/rust/scoped_sink_app/src/main.rs +0 -0
  158. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_api.py +0 -0
  159. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_cli.py +0 -0
  160. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_commonjs.py +0 -0
  161. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_csharp_callbacks.py +0 -0
  162. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_cte_bounds.py +0 -0
  163. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_engine_pragmas.py +0 -0
  164. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_entrypoint_expansion.py +0 -0
  165. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_entrypoints.py +0 -0
  166. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_entrypoints_go.py +0 -0
  167. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_entrypoints_javascript.py +0 -0
  168. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_entrypoints_php.py +0 -0
  169. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_entrypoints_ruby.py +0 -0
  170. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_csharp.py +0 -0
  171. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_go.py +0 -0
  172. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_java.py +0 -0
  173. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_javascript.py +0 -0
  174. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_php.py +0 -0
  175. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_python.py +0 -0
  176. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_ruby.py +0 -0
  177. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_extract_rust.py +0 -0
  178. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_frameworks.py +0 -0
  179. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_fuzzy_sink.py +0 -0
  180. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_go_callbacks.py +0 -0
  181. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_hardening.py +0 -0
  182. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_heal_fidelity.py +0 -0
  183. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_incremental.py +0 -0
  184. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_indexer.py +0 -0
  185. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_java_callbacks.py +0 -0
  186. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_lang.py +0 -0
  187. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_manifests.py +0 -0
  188. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_may_continue.py +0 -0
  189. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_models.py +0 -0
  190. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_pool.py +0 -0
  191. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_reachability.py +0 -0
  192. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_registry_cache.py +0 -0
  193. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_render.py +0 -0
  194. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_resolver.py +0 -0
  195. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_rust_callbacks.py +0 -0
  196. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_rust_scoped_sinks.py +0 -0
  197. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_sanitizer_languages.py +0 -0
  198. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_scoring.py +0 -0
  199. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_sink_catalog.py +0 -0
  200. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_taint.py +0 -0
  201. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_taint_sanitizers.py +0 -0
  202. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_taint_sources.py +0 -0
  203. {entrygraph-0.1.45 → entrygraph-0.1.47}/tests/test_walker.py +0 -0
  204. {entrygraph-0.1.45 → entrygraph-0.1.47}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: entrygraph
3
- Version: 0.1.45
3
+ Version: 0.1.47
4
4
  Summary: Language-agnostic code graph: query symbols, entrypoints, and source-to-sink call paths from a SQLite index
5
5
  Project-URL: Repository, https://github.com/brettbergin/entrygraph
6
6
  Author-email: Brett Bergin <brettberginbc@yahoo.com>
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.1.45'
22
- __version_tuple__ = version_tuple = (0, 1, 45)
21
+ __version__ = version = '0.1.47'
22
+ __version_tuple__ = version_tuple = (0, 1, 47)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -25,6 +25,9 @@ from entrygraph.kinds import EntrypointKind, SymbolKind
25
25
  _HTTP_ATTR = re.compile(r"^\[Http(Get|Post|Put|Delete|Patch|Head|Options)\b")
26
26
  _ROUTE_ATTR = re.compile(r"^\[Route\b")
27
27
  _CONTROLLER_ATTR = re.compile(r"^\[(ApiController|Controller)\b")
28
+ _APICONTROLLER_ATTR = re.compile(r"^\[ApiController\b")
29
+ _AREA_ATTR = re.compile(r"^\[Area\b")
30
+ _NONACTION_ATTR = re.compile(r"^\[NonAction\b")
28
31
 
29
32
  _MINIMAL_MAP = {
30
33
  "MapGet": "GET",
@@ -64,45 +67,93 @@ def _class_route_prefix(t: RawSymbol) -> str:
64
67
  return prefix.replace("[controller]", _controller_token(t.qualified_name))
65
68
 
66
69
 
70
+ def _is_conventional_controller(t: RawSymbol) -> bool:
71
+ """A classic MVC controller reached by convention (`{controller}/{action}`),
72
+ not attribute routing. `[ApiController]` mandates attribute routing, and a
73
+ class-level `[Route]` opts the whole controller into attribute routing, so
74
+ neither can be convention-routed."""
75
+ return not any(_APICONTROLLER_ATTR.match(d) or _ROUTE_ATTR.match(d) for d in t.decorators)
76
+
77
+
78
+ def _is_action_method(m: RawSymbol, ctor_name: str) -> bool:
79
+ """A public instance method that MVC exposes as a convention-routed action.
80
+
81
+ Excludes constructors, static/override members (framework overrides like
82
+ `OnActionExecuting`), `[NonAction]`, and anything already carrying an
83
+ `[Http*]`/`[Route]` attribute (handled by the attribute-routing branches)."""
84
+ if "public" not in m.modifiers or "static" in m.modifiers or "override" in m.modifiers:
85
+ return False
86
+ if m.name == ctor_name:
87
+ return False
88
+ return not any(
89
+ _NONACTION_ATTR.match(d) or _HTTP_ATTR.match(d) or _ROUTE_ATTR.match(d)
90
+ for d in m.decorators
91
+ )
92
+
93
+
94
+ def _conventional_route(t: RawSymbol, action: str) -> str:
95
+ """`[Area("Admin")]` + FooController + Bar -> /Admin/Foo/Bar."""
96
+ area_dec = next((d for d in t.decorators if _AREA_ATTR.match(d)), None)
97
+ area = (first_string_arg(area_dec) if area_dec else None) or ""
98
+ parts = [area, _controller_token(t.qualified_name), action]
99
+ return "/" + "/".join(p.strip("/") for p in parts if p and p.strip("/"))
100
+
101
+
67
102
  def _aspnet_controller_routes(x: FileExtraction) -> list[EntrypointHint]:
68
103
  controller_syms = [t for t in _type_symbols(x) if _is_controller(t)]
69
104
  controllers = {t.qualified_name for t in controller_syms}
70
105
  if not controllers:
71
106
  return []
72
107
  prefixes = {t.qualified_name: _class_route_prefix(t) for t in controller_syms}
108
+ # controllers reached by convention -> their symbol, for building /controller/action
109
+ conventional = {t.qualified_name: t for t in controller_syms if _is_conventional_controller(t)}
73
110
  hints: list[EntrypointHint] = []
74
111
  for method in _methods(x):
75
- if method.parent_qualified_name not in controllers:
112
+ parent = method.parent_qualified_name or ""
113
+ if parent not in controllers:
76
114
  continue
77
- prefix = prefixes.get(method.parent_qualified_name or "", "")
78
- for decorator in method.decorators:
79
- m = _HTTP_ATTR.match(decorator)
80
- if m:
81
- hints.append(
82
- EntrypointHint(
83
- rule_id="csharp.aspnet.controller-route",
84
- kind=EntrypointKind.HTTP_ROUTE,
85
- handler_qualified_name=method.qualified_name,
86
- route=compose_route(prefix, first_string_arg(decorator)),
87
- http_methods=[m.group(1).upper()],
88
- framework="aspnetcore",
89
- )
115
+ prefix = prefixes.get(parent, "")
116
+ verb_match = next((m for d in method.decorators if (m := _HTTP_ATTR.match(d))), None)
117
+ if verb_match is not None:
118
+ hints.append(
119
+ EntrypointHint(
120
+ rule_id="csharp.aspnet.controller-route",
121
+ kind=EntrypointKind.HTTP_ROUTE,
122
+ handler_qualified_name=method.qualified_name,
123
+ route=compose_route(prefix, first_string_arg(verb_match.string)),
124
+ http_methods=[verb_match.group(1).upper()],
125
+ framework="aspnetcore",
90
126
  )
91
- break
92
- else:
93
- # No Http* verb attribute; a bare [Route("...")] still exposes it.
94
- route_dec = next((d for d in method.decorators if _ROUTE_ATTR.match(d)), None)
95
- if route_dec is not None:
96
- hints.append(
97
- EntrypointHint(
98
- rule_id="csharp.aspnet.controller-route",
99
- kind=EntrypointKind.HTTP_ROUTE,
100
- handler_qualified_name=method.qualified_name,
101
- route=compose_route(prefix, first_string_arg(route_dec)),
102
- http_methods=["*"],
103
- framework="aspnetcore",
104
- )
127
+ )
128
+ continue
129
+ # No Http* verb attribute; a bare [Route("...")] still exposes it.
130
+ route_dec = next((d for d in method.decorators if _ROUTE_ATTR.match(d)), None)
131
+ if route_dec is not None:
132
+ hints.append(
133
+ EntrypointHint(
134
+ rule_id="csharp.aspnet.controller-route",
135
+ kind=EntrypointKind.HTTP_ROUTE,
136
+ handler_qualified_name=method.qualified_name,
137
+ route=compose_route(prefix, first_string_arg(route_dec)),
138
+ http_methods=["*"],
139
+ framework="aspnetcore",
105
140
  )
141
+ )
142
+ continue
143
+ # No attribute at all: a convention-routed MVC action (/controller/action),
144
+ # reachable via GET. Only for non-attribute controllers (#37).
145
+ controller = conventional.get(parent)
146
+ if controller is not None and _is_action_method(method, controller.name):
147
+ hints.append(
148
+ EntrypointHint(
149
+ rule_id="csharp.aspnet.mvc-conventional",
150
+ kind=EntrypointKind.HTTP_ROUTE,
151
+ handler_qualified_name=method.qualified_name,
152
+ route=_conventional_route(controller, method.name),
153
+ http_methods=["GET"],
154
+ framework="aspnetcore",
155
+ )
156
+ )
106
157
  return hints
107
158
 
108
159
 
@@ -15,6 +15,7 @@ import re
15
15
 
16
16
  from entrygraph.detect.entrypoints.base import (
17
17
  EntrypointRule,
18
+ compose_route,
18
19
  first_string_arg,
19
20
  register,
20
21
  )
@@ -58,10 +59,36 @@ def _rust_main(x: FileExtraction) -> list[EntrypointHint]:
58
59
  return hints
59
60
 
60
61
 
62
+ _AXUM_NEST_FN = re.compile(r",\s*([A-Za-z_]\w*)\s*\(") # 2nd arg of nest: funcName(
63
+
64
+
65
+ def _axum_nest_prefixes(x: FileExtraction) -> dict[str, str]:
66
+ """Map a router-builder function to the prefix it's nested under:
67
+ `.nest("/admin", admin_routes())` -> {admin_routes: "/admin"} (#36).
68
+
69
+ axum's other nest form, `.nest("/x", router_var)`, mounts a router built inline
70
+ in the same function as everything else, so its routes can't be told apart by
71
+ caller — that variable form stays out of static reach.
72
+ """
73
+ prefixes: dict[str, str] = {}
74
+ for ref in x.references:
75
+ if ref.kind != "call" or ref.callee_name != "nest" or not ref.arg_preview:
76
+ continue
77
+ prefix = first_string_arg("(" + ref.arg_preview.lstrip("("))
78
+ if prefix is None or not prefix.startswith("/"):
79
+ continue
80
+ m = _AXUM_NEST_FN.search(ref.arg_preview)
81
+ if m:
82
+ prefixes[m.group(1)] = prefix
83
+ return prefixes
84
+
85
+
61
86
  def _axum_routes(x: FileExtraction) -> list[EntrypointHint]:
62
87
  """`Router::new().route("/x", post(handler))` — the handler is buried in the
63
88
  second argument, so we regex it out of the preview but can't statically bind
64
- it (the Express-rule fidelity tradeoff)."""
89
+ it (the Express-rule fidelity tradeoff). Routes declared inside a function that
90
+ is `.nest("/prefix", fn())`-mounted are composed with that prefix."""
91
+ nest_prefixes = _axum_nest_prefixes(x)
65
92
  hints = []
66
93
  for ref in x.references:
67
94
  if ref.kind != "call" or ref.callee_name != "route" or not ref.arg_preview:
@@ -70,12 +97,15 @@ def _axum_routes(x: FileExtraction) -> list[EntrypointHint]:
70
97
  if route is None or not route.startswith("/"):
71
98
  continue
72
99
  method, handler = _axum_method_and_handler(ref.arg_preview)
100
+ # the enclosing router-builder function, if it's mounted under a nest prefix
101
+ builder = (ref.caller_qualified_name or "").rsplit(".", 1)[-1]
102
+ full = compose_route(nest_prefixes.get(builder, ""), route)
73
103
  hints.append(
74
104
  EntrypointHint(
75
105
  rule_id="rust.axum.route",
76
106
  kind=EntrypointKind.HTTP_ROUTE,
77
107
  handler_qualified_name=None,
78
- route=route,
108
+ route=full,
79
109
  http_methods=[method],
80
110
  framework="axum",
81
111
  metadata={"handler_text": handler, "registration": ref.arg_preview},
@@ -0,0 +1,75 @@
1
+ """C# entrypoint-rule tests (kept per-language so PRs touching different languages
2
+ don't serially conflict on one shared test module)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from entrygraph.detect.entrypoints import rules_for
7
+ from entrygraph.extract.base import FileContext
8
+ from entrygraph.extract.csharp import CSharpExtractor
9
+ from entrygraph.parsing.parsers import parse
10
+
11
+
12
+ def _controller_rule():
13
+ return {r.id: r for r in rules_for("csharp", {"aspnetcore"})}["csharp.aspnet.controller-route"]
14
+
15
+
16
+ def _extract(src: bytes, path="Controllers/C.cs", module="App.Controllers"):
17
+ ctx = FileContext(
18
+ path=path, language="csharp", module_path=module, source=src, is_package=False
19
+ )
20
+ return CSharpExtractor().extract(parse("csharp", src), ctx)
21
+
22
+
23
+ def test_conventional_mvc_actions_detected():
24
+ # Non-attribute controller: public actions route to /{controller}/{action} via
25
+ # GET; constructors, [NonAction], override, and [HttpPost] methods are excluded
26
+ # (the POST one is emitted by the attribute branch instead) (#37).
27
+ src = (
28
+ b"namespace App.Controllers;\n"
29
+ b"public class HomeController : Controller\n{\n"
30
+ b" public HomeController() {}\n"
31
+ b" public IActionResult Index() { return View(); }\n"
32
+ b" public async Task<IActionResult> About() { return View(); }\n"
33
+ b" [NonAction] public void Helper() {}\n"
34
+ b" public override void OnActionExecuting() {}\n"
35
+ b"}\n"
36
+ )
37
+ got = {(tuple(h.http_methods), h.route) for h in _controller_rule().match(_extract(src))}
38
+ assert got == {(("GET",), "/Home/Index"), (("GET",), "/Home/About")}
39
+
40
+
41
+ def test_conventional_route_includes_area_prefix():
42
+ src = (
43
+ b"namespace App.Areas.Admin.Controllers;\n"
44
+ b'[Area("Admin")]\n'
45
+ b"public class DashboardController : Controller\n{\n"
46
+ b" public IActionResult Stats() { return View(); }\n"
47
+ b"}\n"
48
+ )
49
+ got = {h.route for h in _controller_rule().match(_extract(src))}
50
+ assert got == {"/Admin/Dashboard/Stats"}
51
+
52
+
53
+ def test_api_controllers_are_not_convention_routed():
54
+ # [ApiController] and a class-level [Route] both mandate attribute routing, so a
55
+ # bare public method must NOT get a convention route.
56
+ src = (
57
+ b"namespace App.Controllers;\n"
58
+ b"[ApiController]\n"
59
+ b'[Route("api/[controller]")]\n'
60
+ b"public class ThingsController : ControllerBase\n{\n"
61
+ b" public IActionResult NoAttr() { return Ok(); }\n"
62
+ b"}\n"
63
+ )
64
+ assert _controller_rule().match(_extract(src)) == []
65
+
66
+
67
+ def test_attribute_routes_still_win_over_convention():
68
+ src = (
69
+ b"namespace App.Controllers;\n"
70
+ b"public class HomeController : Controller\n{\n"
71
+ b' [HttpGet("ping")] public IActionResult Ping() { return Ok(); }\n'
72
+ b"}\n"
73
+ )
74
+ got = {(tuple(h.http_methods), h.route) for h in _controller_rule().match(_extract(src))}
75
+ assert got == {(("GET",), "/ping")} # attribute route, not /Home/Ping
@@ -0,0 +1,53 @@
1
+ """Rust entrypoint-rule tests (kept per-language so PRs touching different
2
+ languages don't serially conflict on one shared test module)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from entrygraph.detect.entrypoints import rules_for
7
+ from entrygraph.extract.base import FileContext
8
+ from entrygraph.extract.rust import RustExtractor
9
+ from entrygraph.parsing.parsers import parse
10
+
11
+
12
+ def _axum_rule():
13
+ return {r.id: r for r in rules_for("rust", {"axum"})}["rust.axum.route"]
14
+
15
+
16
+ def _extract(src: bytes, path="src/main.rs"):
17
+ ctx = FileContext(path=path, language="rust", module_path="main", source=src, is_package=False)
18
+ return RustExtractor().extract(parse("rust", src), ctx)
19
+
20
+
21
+ def test_axum_nest_prefix_composed_for_function_router():
22
+ # `.nest("/admin", admin_routes())` prefixes the routes declared inside the
23
+ # admin_routes builder function; top-level routes stay unprefixed (#36).
24
+ src = (
25
+ b"fn admin_routes() -> Router {\n"
26
+ b" Router::new()\n"
27
+ b' .route("/keys", delete(delete_all_keys))\n'
28
+ b' .route("/key/{key}", delete(remove_key))\n'
29
+ b"}\n"
30
+ b"async fn main() {\n"
31
+ b" let app = Router::new()\n"
32
+ b' .route("/keys", get(list_keys))\n'
33
+ b' .nest("/admin", admin_routes());\n'
34
+ b"}\n"
35
+ )
36
+ got = {(h.http_methods[0], h.route) for h in _axum_rule().match(_extract(src))}
37
+ assert got == {
38
+ ("GET", "/keys"), # top-level, no prefix
39
+ ("DELETE", "/admin/keys"), # composed with the nest prefix
40
+ ("DELETE", "/admin/key/{key}"),
41
+ }
42
+
43
+
44
+ def test_axum_routes_without_nest_are_unprefixed():
45
+ src = (
46
+ b"async fn main() {\n"
47
+ b" let app = Router::new()\n"
48
+ b' .route("/users", get(list_users))\n'
49
+ b' .route("/users/{id}", get(get_user));\n'
50
+ b"}\n"
51
+ )
52
+ got = {(h.http_methods[0], h.route) for h in _axum_rule().match(_extract(src))}
53
+ assert got == {("GET", "/users"), ("GET", "/users/{id}")}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes