| 1401 | } |
| 1402 | |
| 1403 | func listDirSubdirsViaGitForHost(owner, repo, ref, dirPath, host string) ([]string, error) { |
| 1404 | remoteLog.Printf("Git fallback for listing subdirs: %s/%s@%s (path: %s)", owner, repo, ref, dirPath) |
| 1405 | |
| 1406 | tmpDir, err := getOrCreateListRepoClone(owner, repo, ref, host) |
| 1407 | if err != nil { |
| 1408 | return nil, err |
| 1409 | } |
| 1410 | |
| 1411 | // Use ls-tree -d to list only direct subdirectory entries. |
| 1412 | lsTreeDirsCmd := exec.Command("git", "-C", tmpDir, "ls-tree", "--name-only", "-d", "HEAD", dirPath+"/") |
| 1413 | lsTreeDirsOutput, err := lsTreeDirsCmd.CombinedOutput() |
| 1414 | if err != nil { |
| 1415 | remoteLog.Printf("Failed to list tree subdirs: %s", string(lsTreeDirsOutput)) |
| 1416 | return nil, fmt.Errorf("failed to list subdirs: %w", err) |
| 1417 | } |
| 1418 | |
| 1419 | lines := strings.Split(strings.TrimSpace(string(lsTreeDirsOutput)), "\n") |
| 1420 | var dirs []string |
| 1421 | for _, line := range lines { |
| 1422 | line = strings.TrimSpace(line) |
| 1423 | if line == "" { |
| 1424 | continue |
| 1425 | } |
| 1426 | afterDirPath := strings.TrimPrefix(line, dirPath+"/") |
| 1427 | if !strings.Contains(afterDirPath, "/") && afterDirPath != "" { |
| 1428 | dirs = append(dirs, line) |
| 1429 | } |
| 1430 | } |
| 1431 | |
| 1432 | remoteLog.Printf("Found %d subdirs via git for %s/%s@%s (path: %s)", len(dirs), owner, repo, ref, dirPath) |
| 1433 | return dirs, nil |
| 1434 | } |
| 1435 | |
| 1436 | // listDirSubdirsViaPublicAPI lists subdirectories using an unauthenticated call |
| 1437 | // to the public GitHub API. Used as a last-resort fallback when both |