entrygraph 0.1.4__tar.gz → 0.1.5__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.
- {entrygraph-0.1.4 → entrygraph-0.1.5}/PKG-INFO +1 -1
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/_version.py +2 -2
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/python.py +25 -14
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/frameworks.py +10 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/manifests.py +3 -1
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/graph/scoring.py +1 -1
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/pipeline/scanner.py +3 -2
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/resolve/resolver.py +4 -1
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_entrypoint_expansion.py +11 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_frameworks.py +12 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_manifests.py +11 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_resolver.py +32 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_scoring.py +9 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/.github/workflows/ci.yml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/.github/workflows/release.yml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/.gitignore +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/LICENSE +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/README.md +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/RELEASING.md +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/pyproject.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/__main__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/api.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/cli/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/cli/main.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/cli/render.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/csharp.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/go.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/java.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/javascript.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/lib_javascript.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/lib_python.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/php.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/python.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/ruby.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/data/sinks/rust.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/db/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/db/engine.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/db/meta.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/db/models.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/db/queries.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/base.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/configs.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/csharp.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/golang.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/java.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/javascript.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/php.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/ruby.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/entrypoints/rust.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/detect/taint.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/errors.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/base.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/csharp.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/golang.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/ir.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/java.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/javascript.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/php.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/python.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/registry.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/ruby.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/extract/rust.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/fs/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/fs/hashing.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/fs/lang.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/fs/walker.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/graph/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/graph/adjacency.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/graph/cte.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/kinds.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/parsing/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/parsing/parsers.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/parsing/queries.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/pipeline/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/pipeline/worker.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/pipeline/writer.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/py.typed +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/csharp/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/csharp/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/csharp/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/go/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/go/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/go/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/java/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/java/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/java/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/javascript/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/javascript/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/javascript/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/php/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/php/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/php/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/python/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/python/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/python/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/ruby/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/ruby/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/ruby/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/rust/calls.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/rust/definitions.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/queries/rust/imports.scm +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/resolve/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/resolve/externals.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/resolve/hierarchy.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/resolve/symbol_table.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/src/entrygraph/results.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/conftest.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/csharp/aspnet_app/Controllers/ReportsController.cs +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/csharp/aspnet_app/Program.cs +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/csharp/aspnet_app/Services/ReportService.cs +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/csharp/aspnet_app/app.csproj +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/go/gin_app/go.mod +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/go/gin_app/main.go +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/go/gin_app/service.go +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/java/spring_app/pom.xml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/java/spring_app/src/main/java/com/example/Application.java +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportRunner.java +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportService.java +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/java/spring_app/src/main/java/com/example/UserController.java +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/javascript/express_app/package.json +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/javascript/express_app/src/routes.js +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/javascript/express_app/src/services.js +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/php/laravel_app/app/Http/Controllers/ReportController.php +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/php/laravel_app/artisan +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/php/laravel_app/composer.json +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/php/laravel_app/routes/web.php +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/python/flask_app/app/__init__.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/python/flask_app/app/db.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/python/flask_app/app/routes.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/python/flask_app/app/services.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/python/flask_app/cli.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/python/flask_app/requirements.txt +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/ruby/sinatra_app/Gemfile +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/ruby/sinatra_app/app.rb +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/ruby/sinatra_app/services/runner.rb +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/rust/axum_app/Cargo.toml +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/rust/axum_app/src/handlers.rs +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/rust/axum_app/src/main.rs +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_api.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_cli.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_engine_pragmas.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_entrypoints.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_csharp.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_go.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_java.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_javascript.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_php.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_python.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_ruby.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_extract_rust.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_hardening.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_incremental.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_indexer.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_lang.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_models.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_pool.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_reachability.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_render.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_sink_catalog.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_taint.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/tests/test_walker.py +0 -0
- {entrygraph-0.1.4 → entrygraph-0.1.5}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: entrygraph
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
21
|
+
__version__ = version = '0.1.5'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 5)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -7,6 +7,7 @@ import re
|
|
|
7
7
|
|
|
8
8
|
from entrygraph.detect.entrypoints.base import (
|
|
9
9
|
EntrypointRule,
|
|
10
|
+
Matcher,
|
|
10
11
|
first_string_arg,
|
|
11
12
|
identifier_args,
|
|
12
13
|
methods_kwarg,
|
|
@@ -157,20 +158,30 @@ def _django_urls(x: FileExtraction) -> list[EntrypointHint]:
|
|
|
157
158
|
return hints
|
|
158
159
|
|
|
159
160
|
|
|
160
|
-
def
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
161
|
+
def _click_like(framework: str, rule_id: str) -> Matcher:
|
|
162
|
+
"""click and typer share decorator shape (`@app.command`); only the
|
|
163
|
+
reported framework/rule_id differ, so bind them per rule."""
|
|
164
|
+
|
|
165
|
+
def _match(x: FileExtraction) -> list[EntrypointHint]:
|
|
166
|
+
hints = []
|
|
167
|
+
for symbol, decorator in _decorated(x):
|
|
168
|
+
if _CLICK_CMD.match(decorator):
|
|
169
|
+
hints.append(
|
|
170
|
+
EntrypointHint(
|
|
171
|
+
rule_id=rule_id,
|
|
172
|
+
kind=EntrypointKind.CLI_COMMAND,
|
|
173
|
+
handler_qualified_name=symbol.qualified_name,
|
|
174
|
+
name=first_string_arg(decorator) or symbol.name,
|
|
175
|
+
framework=framework,
|
|
176
|
+
)
|
|
171
177
|
)
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
return hints
|
|
179
|
+
|
|
180
|
+
return _match
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
_click_commands = _click_like("click", "python.click.command")
|
|
184
|
+
_typer_commands = _click_like("typer", "python.typer.command")
|
|
174
185
|
|
|
175
186
|
|
|
176
187
|
def _celery_tasks(x: FileExtraction) -> list[EntrypointHint]:
|
|
@@ -363,7 +374,7 @@ register(
|
|
|
363
374
|
)
|
|
364
375
|
register(
|
|
365
376
|
EntrypointRule(
|
|
366
|
-
"python.typer.command", "python", "typer", EntrypointKind.CLI_COMMAND,
|
|
377
|
+
"python.typer.command", "python", "typer", EntrypointKind.CLI_COMMAND, _typer_commands
|
|
367
378
|
)
|
|
368
379
|
)
|
|
369
380
|
register(
|
|
@@ -104,6 +104,16 @@ FRAMEWORKS: list[FrameworkSpec] = [
|
|
|
104
104
|
),
|
|
105
105
|
),
|
|
106
106
|
# JS/TS, Go, Java, Ruby specs land with their extractors (M8)
|
|
107
|
+
FrameworkSpec(
|
|
108
|
+
"aws-lambda-js",
|
|
109
|
+
"javascript",
|
|
110
|
+
(
|
|
111
|
+
FrameworkSignal("file_presence", "serverless.y*ml", 0.5),
|
|
112
|
+
FrameworkSignal("file_presence", "template.y*ml", 0.3),
|
|
113
|
+
FrameworkSignal("manifest_dep", "@types/aws-lambda", 0.6),
|
|
114
|
+
FrameworkSignal("manifest_dep", "aws-lambda", 0.5),
|
|
115
|
+
),
|
|
116
|
+
),
|
|
107
117
|
FrameworkSpec(
|
|
108
118
|
"express",
|
|
109
119
|
"javascript",
|
|
@@ -223,9 +223,11 @@ def parse_manifests(root: str | Path) -> ManifestDeps:
|
|
|
223
223
|
if not manifest.is_file():
|
|
224
224
|
continue
|
|
225
225
|
if any(
|
|
226
|
-
part in ("node_modules", "vendor", ".venv", "venv", "target"
|
|
226
|
+
part in ("node_modules", "vendor", ".venv", "venv", "target")
|
|
227
227
|
for part in manifest.parts
|
|
228
228
|
):
|
|
229
|
+
# note: "packages" is intentionally NOT excluded — it is the
|
|
230
|
+
# standard JS workspace layout (packages/<name>/package.json).
|
|
229
231
|
continue
|
|
230
232
|
try:
|
|
231
233
|
text = manifest.read_text(encoding="utf-8", errors="replace")
|
|
@@ -33,7 +33,7 @@ _LENGTH_DECAY = 0.97
|
|
|
33
33
|
_CONST_TOKEN = re.compile(
|
|
34
34
|
r"""^(
|
|
35
35
|
\s | , | = | \( | \) | \[ | \] | \{ | \} | : |
|
|
36
|
-
'[^']*' | "[^"]*" | `[
|
|
36
|
+
'[^']*' | "[^"]*" | `(?:[^`$]|\$(?!\{))*` | # backtick: no ${...} interpolation
|
|
37
37
|
\d[\d_.eExXaAbBcCdDfF]* |
|
|
38
38
|
True|False|None|null|true|false|nil |
|
|
39
39
|
[A-Za-z_]\w*\s*= # kwarg name before '='
|
|
@@ -305,12 +305,13 @@ def _write_files(
|
|
|
305
305
|
for path, fid in session.execute(select(File.path, File.id).where(File.repo_id == repo.id)):
|
|
306
306
|
file_id_by_path[path] = fid
|
|
307
307
|
|
|
308
|
-
|
|
308
|
+
to_index_paths = {w.path for w in diff.to_index}
|
|
309
|
+
reindexed = to_index_paths | {
|
|
309
310
|
w.path for w in walked if w.skip_reason and w.path not in file_id_by_path
|
|
310
311
|
}
|
|
311
312
|
new_rows = []
|
|
312
313
|
for wf in walked:
|
|
313
|
-
if wf.path in file_id_by_path and wf.path not in
|
|
314
|
+
if wf.path in file_id_by_path and wf.path not in to_index_paths:
|
|
314
315
|
continue # unchanged; row already present
|
|
315
316
|
if wf.path not in reindexed and not wf.skip_reason:
|
|
316
317
|
continue
|
|
@@ -71,6 +71,7 @@ class FileResolver:
|
|
|
71
71
|
self.module_symbol_id = module_symbol_id
|
|
72
72
|
self.table = table
|
|
73
73
|
self.externals = externals
|
|
74
|
+
self.is_package = is_package
|
|
74
75
|
self.prefix = LANG_PREFIX.get(extraction.language, extraction.language)
|
|
75
76
|
self.import_map, self.wildcard_modules = build_import_map(extraction, is_package)
|
|
76
77
|
|
|
@@ -122,7 +123,9 @@ class FileResolver:
|
|
|
122
123
|
seen: set[str] = set()
|
|
123
124
|
for imp in self.x.imports:
|
|
124
125
|
module = (
|
|
125
|
-
expand_relative(imp, self.x.module_path,
|
|
126
|
+
expand_relative(imp, self.x.module_path, self.is_package)
|
|
127
|
+
if imp.is_relative
|
|
128
|
+
else imp.module
|
|
126
129
|
)
|
|
127
130
|
if not module or module in seen:
|
|
128
131
|
continue
|
|
@@ -160,6 +160,17 @@ def test_lambda_js_handler_rule():
|
|
|
160
160
|
assert hints and hints[0].kind is EntrypointKind.LAMBDA_HANDLER
|
|
161
161
|
|
|
162
162
|
|
|
163
|
+
def test_typer_command_reports_typer_not_click():
|
|
164
|
+
# typer reuses click's decorator shape; the hint must carry framework/rule_id
|
|
165
|
+
# for typer, not be mislabeled as click.
|
|
166
|
+
sym = _sym("serve", "cli.serve")
|
|
167
|
+
sym.decorators = ["@app.command()"]
|
|
168
|
+
hints = _run("python.typer.command", _extraction([sym]), frameworks=frozenset({"typer"}))
|
|
169
|
+
assert hints
|
|
170
|
+
assert hints[0].framework == "typer"
|
|
171
|
+
assert hints[0].rule_id == "python.typer.command"
|
|
172
|
+
|
|
173
|
+
|
|
163
174
|
def test_sidekiq_worker_rule():
|
|
164
175
|
from entrygraph.detect.entrypoints import rules_for
|
|
165
176
|
|
|
@@ -33,6 +33,18 @@ def test_language_gating():
|
|
|
33
33
|
assert not any(d.name == "rails" for d in detected)
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def test_aws_lambda_js_detected_from_serverless_config():
|
|
37
|
+
# the javascript.aws-lambda.handler entrypoint rule is gated on this spec;
|
|
38
|
+
# regression: the spec was missing, so the rule could never fire.
|
|
39
|
+
detected = detect_frameworks(
|
|
40
|
+
ManifestDeps(javascript={"@types/aws-lambda"}),
|
|
41
|
+
import_signals=set(),
|
|
42
|
+
file_paths=["serverless.yml"],
|
|
43
|
+
languages_present={"javascript"},
|
|
44
|
+
)
|
|
45
|
+
assert any(d.name == "aws-lambda-js" for d in detected)
|
|
46
|
+
|
|
47
|
+
|
|
36
48
|
def test_typescript_counts_for_js_frameworks():
|
|
37
49
|
manifests = ManifestDeps(javascript={"express"})
|
|
38
50
|
detected = detect_frameworks(
|
|
@@ -78,6 +78,17 @@ def test_parse_manifests_fixture():
|
|
|
78
78
|
assert "requirements.txt" in deps.sources
|
|
79
79
|
|
|
80
80
|
|
|
81
|
+
def test_parse_manifests_reads_js_workspace_packages(tmp_path: Path):
|
|
82
|
+
# `packages/<name>/package.json` is the standard JS workspace layout and must
|
|
83
|
+
# not be excluded (regression: "packages" was in the skip list).
|
|
84
|
+
pkg = tmp_path / "packages" / "api"
|
|
85
|
+
pkg.mkdir(parents=True)
|
|
86
|
+
(pkg / "package.json").write_text('{"dependencies": {"express": "^4"}}')
|
|
87
|
+
deps = parse_manifests(tmp_path)
|
|
88
|
+
assert "express" in deps.javascript
|
|
89
|
+
assert "packages/api/package.json" in deps.sources
|
|
90
|
+
|
|
91
|
+
|
|
81
92
|
# ---------------- C1: C#, PHP, Rust manifests ----------------
|
|
82
93
|
from entrygraph.detect.manifests import ( # noqa: E402
|
|
83
94
|
parse_cargo_toml,
|
|
@@ -57,6 +57,38 @@ def test_import_based_project_resolution():
|
|
|
57
57
|
assert call.confidence is Confidence.IMPORT
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
def test_relative_import_from_package_init_resolves_submodule():
|
|
61
|
+
# `from .sub import thing` in the package's own __init__.py (module_path
|
|
62
|
+
# "app", is_package=True) must resolve to the project module "app.sub".
|
|
63
|
+
# Regression: is_package was hardcoded False, dropping "app" and yielding a
|
|
64
|
+
# bogus ".sub" external placeholder.
|
|
65
|
+
table = make_table()
|
|
66
|
+
table.add_module("app.sub", 20)
|
|
67
|
+
x = FileExtraction(
|
|
68
|
+
path="app/__init__.py",
|
|
69
|
+
language="python",
|
|
70
|
+
module_path="app",
|
|
71
|
+
parse_ok=True,
|
|
72
|
+
error_count=0,
|
|
73
|
+
imports=[
|
|
74
|
+
RawImport(
|
|
75
|
+
module="sub",
|
|
76
|
+
imported_name="thing",
|
|
77
|
+
alias="thing",
|
|
78
|
+
span=SPAN,
|
|
79
|
+
is_relative=True,
|
|
80
|
+
relative_level=1,
|
|
81
|
+
)
|
|
82
|
+
],
|
|
83
|
+
)
|
|
84
|
+
externals = ExternalRegistry(iter(range(100, 200)).__next__)
|
|
85
|
+
resolver = FileResolver(x, 1, table, externals, is_package=True)
|
|
86
|
+
edges = resolver.resolve()
|
|
87
|
+
imp = next(e for e in edges if e.kind is EdgeKind.IMPORTS)
|
|
88
|
+
assert imp.dst_qname == "app.sub"
|
|
89
|
+
assert imp.dst_symbol_id == 20
|
|
90
|
+
|
|
91
|
+
|
|
60
92
|
def test_external_import_creates_placeholder():
|
|
61
93
|
table = make_table()
|
|
62
94
|
imports = [RawImport(module="subprocess", imported_name=None, alias="sub", span=SPAN)]
|
|
@@ -17,6 +17,15 @@ def test_is_constant_args():
|
|
|
17
17
|
assert not is_constant_args("(a, b, c, d, e, f, ...")
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
def test_js_template_literal_interpolation_is_not_constant():
|
|
21
|
+
# a plain backtick template with no interpolation is a literal
|
|
22
|
+
assert is_constant_args("(`ls -la`)")
|
|
23
|
+
# `${...}` carries a variable into the sink -> the archetypal JS command
|
|
24
|
+
# injection must NOT be scored as constant/safe
|
|
25
|
+
assert not is_constant_args("(`ls ${req.query.dir}`)")
|
|
26
|
+
assert not is_constant_args("(`${userInput}`)")
|
|
27
|
+
|
|
28
|
+
|
|
20
29
|
def test_score_path_ordering_by_severity():
|
|
21
30
|
common = {
|
|
22
31
|
"hop_confidences": [int(Confidence.EXACT)],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{entrygraph-0.1.4 → entrygraph-0.1.5}/tests/fixtures/csharp/aspnet_app/Services/ReportService.cs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|