From e81546db299869e50243bc792920d847b3a73974 Mon Sep 17 00:00:00 2001 From: liyipeng06 Date: Thu, 30 Apr 2026 19:34:47 +0800 Subject: [PATCH] fix(group): tidy thrift source-scan identifiers --- gitnexus/src/core/group/extractors/manifest-extractor.ts | 5 ++++- gitnexus/src/core/group/extractors/thrift-extractor.ts | 5 ++++- gitnexus/test/unit/group/sync.test.ts | 2 +- gitnexus/test/unit/group/thrift-extractor.test.ts | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gitnexus/src/core/group/extractors/manifest-extractor.ts b/gitnexus/src/core/group/extractors/manifest-extractor.ts index de2e772d3..08a86a477 100644 --- a/gitnexus/src/core/group/extractors/manifest-extractor.ts +++ b/gitnexus/src/core/group/extractors/manifest-extractor.ts @@ -228,7 +228,10 @@ export class ManifestExtractor { } else if (link.type === 'grpc' || link.type === 'thrift') { // Contract is "Service/Method" or just "Service" (or package.Service // variants). Prefer matching by method name when present, otherwise - // by service name. NO IDL path fallback — that's guaranteed to + // by service name. Thrift generated Java classes often use + // package.Service in manifests while graph Class/Interface names are + // stored as bare Service, so strip the package prefix for thrift + // service-name lookups. NO IDL path fallback — that's guaranteed to // return a wrong symbol in any repo with more than one IDL file. // Label filters scope lookups: methods → Function|Method, services // → Class|Interface (no label match = no silent wrong hits on diff --git a/gitnexus/src/core/group/extractors/thrift-extractor.ts b/gitnexus/src/core/group/extractors/thrift-extractor.ts index 06e75379a..cfd8fef02 100644 --- a/gitnexus/src/core/group/extractors/thrift-extractor.ts +++ b/gitnexus/src/core/group/extractors/thrift-extractor.ts @@ -184,7 +184,10 @@ function thriftSourceScanSymbolUid( filePath: string, symbolName: string, ): string { - return ['source-scan::thrift', role, contractId, normalizeThriftPath(filePath), symbolName].join( + const contractKey = contractId.startsWith('thrift::') + ? contractId.slice('thrift::'.length) + : contractId; + return ['source-scan::thrift', role, contractKey, normalizeThriftPath(filePath), symbolName].join( '::', ); } diff --git a/gitnexus/test/unit/group/sync.test.ts b/gitnexus/test/unit/group/sync.test.ts index 933ed74af..642e7dd59 100644 --- a/gitnexus/test/unit/group/sync.test.ts +++ b/gitnexus/test/unit/group/sync.test.ts @@ -448,7 +448,7 @@ class IfaceOrderHandler implements OrderService.Iface { symbolUid: [ 'source-scan::thrift', 'consumer', - 'thrift::OrderService/PlaceOrder', + 'OrderService/PlaceOrder', 'src/BillingWorkflow.java', 'orderService.PlaceOrder', ].join('::'), diff --git a/gitnexus/test/unit/group/thrift-extractor.test.ts b/gitnexus/test/unit/group/thrift-extractor.test.ts index f18cc905a..ca7045543 100644 --- a/gitnexus/test/unit/group/thrift-extractor.test.ts +++ b/gitnexus/test/unit/group/thrift-extractor.test.ts @@ -488,6 +488,7 @@ class IfaceOrderHandler implements OrderService.Iface { expect(providers.map((c) => c.symbolUid)).toEqual(repeatedProviders.map((c) => c.symbolUid)); expect(providers.every((c) => c.symbolUid.length > 0)).toBe(true); expect(new Set(providers.map((c) => c.symbolUid)).size).toBe(2); + expect(providers.every((c) => !c.symbolUid.includes('::thrift::billing.v1'))).toBe(true); }); it('test_extract_java_thrift_providers_from_fully_qualified_generated_iface', async () => {