Skip to content

fix(cli): detect Spring Boot request mappings as routes#619

Closed
ShiningXu wants to merge 6 commits into
abhigyanpatwari:mainfrom
ShiningXu:fix/spring-route-nodes
Closed

fix(cli): detect Spring Boot request mappings as routes#619
ShiningXu wants to merge 6 commits into
abhigyanpatwari:mainfrom
ShiningXu:fix/spring-route-nodes

Conversation

@ShiningXu

@ShiningXu ShiningXu commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Add Spring-specific route extraction so Spring Boot request mapping annotations produce Route nodes, HANDLES_ROUTE edges, and framework route call links during ingestion.

Motivation / context

Fixes #600.

Spring controller methods annotated with @RequestMapping and the shortcut mapping annotations were not being converted into graph route data, which meant Spring Boot API endpoints were missing from the knowledge graph.

Areas touched

  • gitnexus/ (CLI / core / MCP server)
  • gitnexus-web/ (Vite / React UI)
  • .github/ (workflows, actions)
  • eval/ or other tooling
  • Docs / agent config only (AGENTS.md, CLAUDE.md, .cursor/, llms.txt, etc.)

Scope & constraints

In scope

  • detect Spring controller route methods from @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, and @PatchMapping
  • support class-level prefixes plus method-level paths
  • support method-level @RequestMapping with both implicit default method handling and explicit RequestMethod.*
  • wire extraction into both worker and sequential parsing paths
  • add focused Spring fixture coverage and integration assertions

Explicitly out of scope / not done here

  • Java HTTP client FETCHES edges
  • Feign, JAX-RS, and MQ route/client extraction
  • dynamic route expressions or builder-based path construction
  • method-level HANDLES_ROUTE granularity changes

Implementation notes

  • added a Spring-specific framework route extractor in gitnexus/src/core/ingestion/route-extractors/spring-java.ts
  • reused the existing ExtractedRoute[] -> framework-route pipeline instead of introducing a new route node path
  • generalized processRoutesFromExtracted() reason text from Laravel-specific wording to framework-generic wording
  • added regression coverage for method-level @RequestMapping with and without explicit RequestMethod

Testing & verification

  • cd gitnexus && npm test
  • cd gitnexus && npm run test:integration (if core/indexing/MCP paths changed)
  • cd gitnexus && npx tsc --noEmit
  • cd gitnexus-web && npm test (if web changed)
  • cd gitnexus-web && npx tsc -b --noEmit (if web changed)
  • Manual / Playwright E2E (note environment — see gitnexus-web/e2e/)

Commands run:

  • cd gitnexus && npm run build
  • cd gitnexus && npx vitest run test/integration/resolvers/route-mapping.test.ts test/integration/resolvers/spring-route-mapping.test.ts
  • cd gitnexus && npx tsc --noEmit

Risk & rollout

Risk is low and localized to route extraction:

  • Java route detection is gated behind Spring-style controller file heuristics
  • existing route registry creation is reused instead of adding a parallel graph shape
  • route mapping regressions were checked against the existing integration route suite

No migration is required beyond normal re-indexing on the target repository.

Checklist

  • PR body meets repo minimum length (workflow may label short descriptions)
  • If AGENTS.md / overlays changed: headers, scope block, and changelog updated per project conventions
  • No secrets, tokens, or machine-specific paths committed

许恩宁 added 2 commits April 1, 2026 21:40
Add a Spring-specific framework route extractor so RequestMapping-style annotations produce Route nodes and handler links in both worker and sequential parsing paths.

Made-with: Cursor
Add Spring fixture coverage for method-level RequestMapping variants with and without an explicit RequestMethod to lock in route extraction behavior.

Made-with: Cursor
@vercel

vercel Bot commented Apr 1, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the NexusCore Team on Vercel.

A member of the Team first needs to authorize it.

@ThinhKVT

ThinhKVT commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

@ShiningXu Thanks for adding Spring request mapping support — this is very helpful!

One important case is missing: the current extractor only handles string literals (e.g. @RequestMapping("/foo")) and does not resolve paths declared via constants/identifiers/field access (for example @RequestMapping(PATHS.USERS), @RequestMapping(path = MyConstants.USERS) or private static final String USERS = "/users"; @RequestMapping(USERS)). Routes declared with constants will be skipped and no Route / HANDLES_ROUTE / CALLS edges will be created.

Please implement the fully-correct resolution only (no temporary fallbacks). Requirements for that approach:

Resolve identifier and field_access annotation values to their actual string values, not just the expression text.
Support same-file and cross-file constant resolution, including static imports and constants defined in other classes.
Reuse the repository’s existing AST/type-env infrastructure (or extend it) so resolution works across files and imports rather than only scanning a single file.
Ensure enum-like field_access (e.g., RequestMethod.GET) and array initializers remain supported for method resolution.
Add tests: a fixture with constants declared in the same class, in another class (regular import and static import), and an imported constant used in @RequestMapping. Assert that Route nodes and HANDLES_ROUTE / CALLS edges are created using the resolved literal paths.

@ShiningXu

ShiningXu commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, this is a good catch.

You're right that the current implementation only resolves string literals, so mappings declared via identifiers / field access / imported constants are still missed. I agree this should be fixed with proper resolution rather than a temporary fallback.

I'll update this PR to support:

  • same-file constants
  • constants from other classes via regular imports
  • constants brought in via static imports

I'll also add focused fixtures and assertions covering those cases, while keeping RequestMethod.* and array-initializer handling intact.

@magyargergo @abhigyanpatwari not sure if this fits well with the current ingestion/resolution flow — would appreciate your thoughts before I go
too far. Happy to adjust if there's a better way to handle this.

@ShiningXu Thanks for adding Spring request mapping support — this is very helpful!

One important case is missing: the current extractor only handles string literals (e.g. @RequestMapping("/foo")) and does not resolve paths declared via constants/identifiers/field access (for example @RequestMapping(PATHS.USERS), @RequestMapping(path = MyConstants.USERS) or private static final String USERS = "/users"; @RequestMapping(USERS)). Routes declared with constants will be skipped and no Route / HANDLES_ROUTE / CALLS edges will be created.

Please implement the fully-correct resolution only (no temporary fallbacks). Requirements for that approach:

Resolve identifier and field_access annotation values to their actual string values, not just the expression text. Support same-file and cross-file constant resolution, including static imports and constants defined in other classes. Reuse the repository’s existing AST/type-env infrastructure (or extend it) so resolution works across files and imports rather than only scanning a single file. Ensure enum-like field_access (e.g., RequestMethod.GET) and array initializers remain supported for method resolution. Add tests: a fixture with constants declared in the same class, in another class (regular import and static import), and an imported constant used in @RequestMapping. Assert that Route nodes and HANDLES_ROUTE / CALLS edges are created using the resolved literal paths.

Finalize Spring route candidates after import resolution so Java Spring mappings can use local, imported, and fully qualified constants. Skip unresolved explicit mappings and expand route metadata coverage to prevent bad fallback routes.

Made-with: Cursor
@ShiningXu

Copy link
Copy Markdown
Contributor Author

@ThinhKVT Thanks for the detailed review. I pushed a follow-up commit that addresses the requested changes:

  • fixed the incorrect / route fallback when an explicit Spring path / value cannot be resolved
  • added support for fully qualified constants
  • expanded tests to cover HTTP methods, Route node metadata, and failure / boundary cases
  • fixed the import formatting issue
  • deduplicated the Java string extraction helper

I also widened the class walker so Spring controller discovery is not limited to class_declaration.

Revalidated with:

  • npm run build
  • npx tsc --noEmit
  • npm test -- --run test/integration/resolvers/spring-route-mapping.test.ts
  • npm test -- --run test/integration/resolvers/express-routes.test.ts
  • npm test -- --run test/integration/resolvers/python.test.ts

@github-actions

github-actions Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

CI Report

Some checks failed

Pipeline Status

Stage Status Details
❌ Typecheck failure tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
4874 4828 0 46 180s

✅ All 4828 tests passed

46 test(s) skipped — expand for details
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature
  • Swift constructor-inferred type resolution > detects User and Repo classes, both with save methods
  • Swift constructor-inferred type resolution > resolves user.save() to Models/User.swift via constructor-inferred type
  • Swift constructor-inferred type resolution > resolves repo.save() to Models/Repo.swift via constructor-inferred type
  • Swift constructor-inferred type resolution > emits exactly 2 save() CALLS edges (one per receiver type)
  • Swift self resolution > detects User and Repo classes, each with a save function
  • Swift self resolution > resolves self.save() inside User.process to User.save, not Repo.save
  • Swift parent resolution > detects BaseModel and User classes plus Serializable protocol
  • Swift parent resolution > emits EXTENDS edge: User → BaseModel
  • Swift parent resolution > emits IMPLEMENTS edge: User → Serializable (protocol conformance)
  • Swift cross-file User.init() inference > resolves user.save() via User.init(name:) inference
  • Swift cross-file User.init() inference > resolves user.greet() via User.init(name:) inference
  • Swift return type inference > detects User class and getUser function
  • Swift return type inference > detects save function on User (Swift class methods are Function nodes)
  • Swift return type inference > resolves user.save() to User#save via return type of getUser() -> User
  • Swift return-type inference via function return type > resolves user.save() to User#save via return type of getUser()
  • Swift return-type inference via function return type > user.save() does NOT resolve to Repo#save
  • Swift return-type inference via function return type > resolves repo.save() to Repo#save via return type of getRepo()
  • Swift implicit imports (cross-file visibility) > detects UserService class in Models.swift
  • Swift implicit imports (cross-file visibility) > resolves UserService() constructor call across files (no explicit import)
  • Swift implicit imports (cross-file visibility) > resolves service.fetchUser() member call across files
  • Swift implicit imports (cross-file visibility) > creates IMPORTS edges between files in the same module
  • Swift extension deduplication > detects Product class
  • Swift extension deduplication > resolves Product() constructor despite extension creating duplicate class node
  • Swift extension deduplication > resolves product.save() to Product.swift (primary definition)
  • Swift constructor call fallback (no new keyword) > resolves OCRService() as constructor call across files
  • Swift constructor call fallback (no new keyword) > resolves ocr.recognize() member call via constructor-inferred type
  • Swift export visibility (internal vs private) > resolves PublicService() constructor across files
  • Swift export visibility (internal vs private) > resolves internalHelper() across files (internal = module-scoped)
  • Swift if let / guard let binding resolution > detects User and Repo classes
  • Swift if let / guard let binding resolution > resolves user.save() inside if-let to User#save
  • Swift if let / guard let binding resolution > resolves repo.save() inside guard-let to Repo#save
  • Swift if let / guard let binding resolution > user.save() in if-let does NOT resolve to Repo#save
  • Swift await / try expression unwrapping > resolves user.save() via await fetchUser() return type
  • Swift await / try expression unwrapping > resolves repo.save() via try parseRepo() return type
  • Swift await / try expression unwrapping > detects fetchUser and parseRepo as functions
  • Swift for-in loop element type inference > detects User and Repo classes
  • Swift for-in loop element type inference > creates implicit import edges between files
  • Swift field-type resolution > detects classes and their properties
  • Swift field-type resolution > emits HAS_PROPERTY edges from class to field
  • Swift field-type resolution > resolves field-chain call user.address.save() → Address#save
  • Swift field-type resolution > emits ACCESSES edges for field reads in chains
  • Swift field-type resolution > populates field metadata (visibility, declaredType) on Property nodes
  • Swift call-result binding > resolves call-result-bound method call user.save() → User#save
  • Swift call-result binding > getUser() is present as a defined function
  • Swift call-result binding > emits processUser -> getUser CALLS edge for let-assigned free function call

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 71.08% 13459/18933 70.94% 📈 +0.1 🟢 ██████████████░░░░░░
Branches 60.38% 8939/14803 60.26% 📈 +0.1 🟢 ████████████░░░░░░░░
Functions 75.85% 1197/1578 75.72% 📈 +0.1 🟢 ███████████████░░░░░
Lines 73.34% 12215/16654 73.18% 📈 +0.2 🟢 ██████████████░░░░░░

📋 View full run · Generated by CI

Remove the unused parsing import and format the updated Spring route files so the quality lint and prettier checks pass cleanly.

Made-with: Cursor
@magyargergo

Copy link
Copy Markdown
Collaborator

@claude review this pr, check if what's promised is actually delivered. Fits well into the architecture and language agnostic and doesn't violate DAG. Try to find gaps and potential issues. You must have detailed explanations and proof for each of the findigns.

@github-actions

github-actions Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @magyargergo's task in 6m 4s —— View job


PR Review: fix(cli): detect Spring Boot request mappings as routes

Tasks

  • Read trigger comment and understand review scope
  • Read core implementation (spring-java.ts, spring-java-types.ts)
  • Read integration points (pipeline.ts, parsing-processor.ts, parse-worker.ts)
  • Read supporting changes (java-strings.ts, field-extractor changes, symbol-table)
  • Read test fixtures and integration tests
  • Compare against existing route extractor patterns (Laravel, Express)
  • Check CI typecheck failure details
  • Verify promised features vs delivered
  • Assess architectural fit, language-agnostic design, DAG compliance
  • Compile and post final review

Summary

The PR delivers the core goal — Spring Boot @RequestMapping/shortcut annotations produce Route nodes, HANDLES_ROUTE edges, and CALLS framework-route links. The two-phase design (collect during parse → finalize after symbol resolution) is sound, and the DAG is not violated. Tests pass and coverage went up. However, there are several architectural and correctness issues worth calling out in detail.


What's Delivered vs. Promised

Promise Delivered? Notes
@RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping spring-java.ts:20-27
Class-level prefix + method-level path finalizeSpringJavaRoutes joins via joinRoutePaths
method= / RequestMethod.* extractRequestMethodName:121-150
Wire into worker + sequential parsing paths parse-worker.ts:1906-1908, parsing-processor.ts:506-510, both paths collected in pipeline.ts:833-835
Same-file constant resolution resolvePathExpression case 'identifier' looks up same-class field then same-file property
Cross-file constant via regular imports resolveFieldAccessConstant via resolveUniqueClassLike
Cross-file constant via static imports resolveNamedImportConstant via namedImportMap
npx tsc --noEmit passes CI typecheck failed in the last automated run at 2026-04-02T14:31:14Z. HEAD commit 59db54f claims to fix this but CI is blocked by a Vercel auth gate (action_required) so this can't be confirmed.
npm test checkbox ticked Left unchecked in PR body, despite CI showing all 4828 tests passing.

Architectural Issues

1. Spring-specific type leaks into the language-agnostic LanguageProvider interface

Severity: High

language-provider.ts:23 imports directly from spring-java-types.ts:

// language-provider.ts:23
import type { ExtractedDeferredRouteCandidate } from './route-extractors/spring-java-types.js';

The deferredRouteExtractor hook on the core LanguageProvider interface returns this type:

// language-provider.ts:150-153
readonly deferredRouteExtractor?: (
  tree: Parser.Tree,
  filePath: string,
) => ExtractedDeferredRouteCandidate[];

ExtractedDeferredRouteCandidate is declared as a direct alias for ExtractedSpringJavaRouteCandidate:

// spring-java-types.ts:18
export type ExtractedDeferredRouteCandidate = ExtractedSpringJavaRouteCandidate;

ExtractedSpringJavaRouteCandidate carries Spring-specific fields (controllerName, classPathExpression, hasExplicitClassPath, hasExplicitMethodPath). The file comment in language-provider.ts describes the design as a Strategy pattern for language-agnostic capabilities, but that invariant is now broken. Any future language (Django, Rails, NestJS) wanting deferred route extraction would be forced to return Spring-typed data from its extractor.

The same leakage appears in parsing-processor.ts:21 and parse-worker.ts:42.

Fix this →


2. Pipeline hardcodes finalizeSpringJavaRoutes — not extensible

Severity: Medium

// pipeline.ts:1035
const finalizedSpringRoutes = finalizeSpringJavaRoutes(allDeferredRouteCandidates, ctx);

The pipeline now has a hard Spring dependency at the finalization point. There's no hook on LanguageProvider that maps deferredRouteExtractordeferredRouteFinalize. If a second language needs the same two-phase pattern the pipeline needs another hardcoded call site. The existing isRouteFile/deferredRouteExtractor pair on LanguageProvider is extensible in the first phase; the second phase isn't.


3. isSpringRouteFile heuristic misses controllers that don't follow naming conventions

Severity: Medium

// languages/java.ts:23-30
function isSpringRouteFile(filePath: string): boolean {
  const normalized = filePath.replace(/\\/g, '/');
  return (
    normalized.endsWith('Controller.java') ||
    normalized.includes('/controller/') ||
    normalized.includes('/controllers/')
  );
}

Spring projects routinely use *Resource.java (HAL/HATEOAS), *Endpoint.java, *Api.java, *Handler.java, or package paths like /rest/, /api/, /web/. None of these are detected. The PR body describes the heuristic as a known gate but the consequence is silent omission — no route nodes, no error.

Since extractSpringJavaRouteCandidates already validates the @Controller/@RestController annotation internally, a more robust alternative is to scan all .java files and rely on the annotation check as the real gate. The current path filter is a redundant pre-filter that also excludes valid controllers.


DAG Compliance ✅

The two-phase design is correct. All deferred candidates are collected during parsing (pipeline.ts:833-835), then finalizeSpringJavaRoutes is called at line 1035, after all chunks have been parsed and imports processed. The ResolutionContext is fully populated before finalization. No cycle is introduced.


Correctness Issues

4. Array initializer paths silently dropped — not documented as a limitation

Severity: Medium

// UserController.java:47
@RequestMapping(path = { "/users/array" }, method = RequestMethod.DELETE)

extractRequestMappingPath never returns a usable expression for array_initializer nodes. The route is silently skipped. This is confirmed by the test:

// spring-route-mapping.test.ts:36
expect(routes).not.toContain('/api/users/array');

Array-valued path/value attributes are a legitimate, common Spring pattern for mapping multiple paths to the same handler. The PR body's out-of-scope list mentions "dynamic route expressions" and "builder-based path construction" but not array initializers, which are fully static. This gap should be documented or addressed.


5. FQN package qualifier ignored in resolveFieldAccessConstant

Severity: Low–Medium

// spring-java.ts:236
const ownerName = ownerPath[ownerPath.length - 1];

For @RequestMapping(path = com.example.constants.ApiPaths.FQCN), ownerPath is ['com', 'example', 'constants', 'ApiPaths'] but only the last segment ApiPaths is used for resolution. The package prefix is discarded. In a project with two classes named ApiPaths in different packages, resolveUniqueClassLike returns null (by design — it rejects ambiguous matches), so the route is silently dropped instead of using the FQN to disambiguate.


6. Dead code branch in extractRequestMappingPath

Severity: Low

// spring-java.ts:100-106
if (
  child.type === 'string_literal' ||
  child.type === 'identifier' ||
  child.type === 'field_access'
) {
  return { expression: null, hasExplicitPath: true };
}

extractRoutePathExpression (called on line 97) already handles all three node types and returns a non-null expression for each:

  • string_literal{ kind: 'literal', value: ... } (since extractJavaStringLiteral on a string_literal node always returns a string, never undefined)
  • identifier{ kind: 'identifier', name: ... }
  • field_access{ kind: 'field-access', ... }

The block at lines 100-106 is therefore unreachable. It reads like a defensive fallback left over from an earlier draft.


Test Coverage Gaps

7. Static import resolution covered only for HealthController — no dedicated failure/miss assertions

The HealthController fixture exercises static imports, but there's no test that asserts a constant-backed route is absent when the constant is unresolvable (e.g., from a missing import). The only negative assertion is:

// spring-route-mapping.test.ts:34-37
expect(routes).not.toContain('/');
expect(routes).not.toContain('/api');
expect(routes).not.toContain('/api/users/array');

BrokenPaths.MISSING in UserController.java tests the failure path, but the test only asserts /api/users/array is absent (that's the array-initializer case, not the broken-path case). There's no assertion that routes backed by BrokenPaths are silently skipped rather than producing a fallback route.

8. Sequential fallback path not covered

The integration test runs the full pipeline, which will use the worker pool. The sequential path in parsing-processor.ts:506-510 that collects deferred candidates isn't tested independently. If the worker pool isn't available, deferred candidate collection still happens (confirmed by code), but a dedicated test or comment would make this verifiable.


Minor Observations

  • firstConstantValue (spring-java.ts:200-203) returns null unless exactly one match is found. If a file declares two constants with the same simple name in different inner classes, both are in the file index and the tie-break returns null. This is conservative but could cause quiet misses.
  • extractJavaStringLiteral is moved to utils/java-strings.ts — correct deduplication of a helper previously duplicated.
  • processRoutesFromExtracted reason text was generalized from Laravel-specific wording to 'framework-route' — the change is in call-processor.ts:3/-3 and is appropriate.
  • walkClasses visits interface_declaration and enum_declaration — Spring controllers are never interfaces or enums in practice, so these branches in CLASS_DECLARATION_TYPES add no real coverage but also no harm.

Verdict

The implementation is mechanically correct for the covered cases and doesn't introduce regressions. The main concerns for the maintainers to decide on are:

  1. Whether the LanguageProvider interface should be decoupled from Spring-specific types before this merges — it's much easier to fix now than after a second deferred extractor is added.
  2. Whether the pipeline's hardcoded finalizeSpringJavaRoutes call is an acceptable pragmatic choice for now, with a note to generalize.
  3. Whether the isSpringRouteFile heuristic should be documented as a known gap or broadened.

Move deferred route finalization behind language provider hooks so Spring-specific candidate handling no longer leaks into the shared pipeline contract. Also broaden Java controller heuristics and preserve FQCN-backed Spring constant resolution.

Made-with: Cursor
@ShiningXu

Copy link
Copy Markdown
Contributor Author

Pushed a follow-up refactor commit to tighten the deferred Spring route design.

Completed in this update:

  • moved deferred route candidate typing behind a generic DeferredRouteCandidate entry point instead of importing Spring-specific aliases into shared interfaces
  • added a provider-level deferredRouteFinalizer hook so the shared pipeline no longer hardcodes finalizeSpringJavaRoutes
  • kept Spring-specific extraction/finalization inside the Java provider wiring
  • broadened Java controller file heuristics to cover additional common naming/package conventions
  • improved FQCN-backed constant resolution by using the qualified owner path when disambiguating class references
  • added a stricter regression assertion to ensure the fixture still emits exactly the expected Spring routes

Revalidated with:

  • npm run build
  • npx tsc --noEmit
  • npm test -- --run test/integration/resolvers/spring-route-mapping.test.ts test/integration/resolvers/route-mapping.test.ts test/integration/resolvers/express-routes.test.ts test/integration/resolvers/python.test.ts
  • npx prettier --check .
  • npx eslint .

Intentionally not changed in this round:

  • walkClasses() recursive traversal: reviewed again and kept as-is; visiting inner classes is expected and does not mis-bind modifiers
  • DeferredRouteCandidate.kind remains an open string for now; the current guard is still narrowed by the 'spring-java' literal and this can be tightened later if another deferred extractor is added
  • the defensive fallback in extractRequestMappingPath() was kept because it still helps mark unsupported explicit field_access shapes as explicit-path failures instead of silently degrading
  • the exact toHaveLength(7) assertion is kept as a deliberate regression guard for this closed fixture

Add an explicit negative regression for unresolved Spring route constants so broken mappings do not emit Route, HANDLES_ROUTE, or framework CALLS links.

Made-with: Cursor
@ShiningXu

Copy link
Copy Markdown
Contributor Author

@magyargergo I’ve pushed fixes for the issues raised in review and updated the tests as well. When you have time, could you take another look at this PR? If you spot anything else that should be changed, just let me know and I’ll update it.

@magyargergo

Copy link
Copy Markdown
Collaborator

@ShiningXu thank you for your contribution! We put hold on every improvements until we finished with the migration to the Semantic Model. We created some issue ticket regarding this and we established the direction. It would be appreciated if you could contribute to that and unblock all the exciting contributions.

@magyargergo

Copy link
Copy Markdown
Collaborator

Please submit a new PR if this is still relevant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Spring Boot] GitNexus does not create Route nodes for REST APIs when analyzing project

3 participants