diff --git a/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect.go b/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect.go index fcbdeef3a..9590b4820 100644 --- a/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect.go +++ b/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect.go @@ -119,10 +119,11 @@ func isDispatcherGitPackageDependency(dependency json.RawMessage) bool { return false } withoutRevision, _, _ := strings.Cut(strings.TrimSpace(value), "#") - if strings.HasPrefix(withoutRevision, "git@") { - return strings.HasSuffix(withoutRevision, ".git") + withoutQuery, _, _ := strings.Cut(withoutRevision, "?") + if strings.HasPrefix(withoutQuery, "git@") { + return strings.HasSuffix(withoutQuery, ".git") } - parsed, err := url.Parse(withoutRevision) + parsed, err := url.Parse(withoutQuery) if err != nil { return false } diff --git a/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect_test.go b/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect_test.go index 59b5474ce..30dc0e8f5 100644 --- a/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect_test.go +++ b/cli/dispatcher/internal/dispatcher/dispatcher_v2_detect_test.go @@ -229,6 +229,28 @@ func TestDetectV2DispatcherProjectRejectsNonGitManifestFallbackWithoutLockEntry( } } +func TestIsDispatcherGitPackageDependencyAcceptsPathQueries(t *testing.T) { + // Verifies Unity Git dependencies with path queries remain eligible for PackageCache fallback. + testCases := []struct { + name string + dependency string + }{ + {name: "scp", dependency: "git@example.invalid:package.git?path=/sub"}, + {name: "https", dependency: "https://example.invalid/package.git?path=/sub"}, + } + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + dependency, err := json.Marshal(testCase.dependency) + if err != nil { + t.Fatalf("marshal dependency: %v", err) + } + if !isDispatcherGitPackageDependency(dependency) { + t.Fatalf("Git dependency was rejected: %s", testCase.dependency) + } + }) + } +} + func TestRunDispatcherReportsV2ProjectGuidanceWhenPinIsMissing(t *testing.T) { // Verifies pinless V2 projects receive migration guidance instead of the missing-pin error. projectRoot := createDispatcherUnityProject(t)