@@ -14,6 +14,7 @@ import ( |
| 14 | 14 | "github.com/jackc/pgx/v5/pgtype" |
| 15 | 15 | |
| 16 | 16 | orgsdb "github.com/tenseleyFlow/shithub/internal/orgs/sqlc" |
| 17 | + "github.com/tenseleyFlow/shithub/internal/repos" |
| 17 | 18 | repogit "github.com/tenseleyFlow/shithub/internal/repos/git" |
| 18 | 19 | reposdb "github.com/tenseleyFlow/shithub/internal/repos/sqlc" |
| 19 | 20 | "github.com/tenseleyFlow/shithub/internal/worker" |
@@ -62,13 +63,23 @@ func (h *Handlers) submoduleTreeURL(ctx context.Context, cc *codeContext, remote |
| 62 | 63 | return route.RepoURL |
| 63 | 64 | } |
| 64 | 65 | if !existsAtCommit { |
| 65 | | - if fetchURL, ok := githubSubmoduleFetchURL(cfg, remoteURL); ok { |
| 66 | | - backfilled, backfillErr := h.backfillSubmoduleCommit(ctx, gitDir, fetchURL, oid) |
| 66 | + for _, candidate := range h.submoduleBackfillFetchCandidates(ctx, cfg, route, remoteURL) { |
| 67 | + backfilled, backfillErr := h.backfillSubmoduleCommit(ctx, gitDir, candidate.URL, oid) |
| 67 | 68 | if backfillErr != nil { |
| 69 | + if candidate.SourceRepoID != 0 { |
| 70 | + h.markRepoSourceRemoteFetchError(ctx, candidate.SourceRepoID, backfillErr) |
| 71 | + } |
| 68 | 72 | if h.d.Logger != nil { |
| 69 | | - h.d.Logger.WarnContext(ctx, "code: submodule backfill fetch", "error", backfillErr, "owner", route.Owner, "repo", route.RepoName, "oid", oid, "remote", fetchURL) |
| 73 | + h.d.Logger.WarnContext(ctx, "code: submodule backfill fetch", "error", backfillErr, "owner", route.Owner, "repo", route.RepoName, "oid", oid, "remote", candidate.URL) |
| 74 | + } |
| 75 | + continue |
| 76 | + } |
| 77 | + if backfilled { |
| 78 | + if candidate.SourceRepoID != 0 { |
| 79 | + if err := h.rq.MarkRepoSourceRemoteFetched(ctx, h.d.Pool, candidate.SourceRepoID); err != nil && h.d.Logger != nil { |
| 80 | + h.d.Logger.WarnContext(ctx, "code: submodule backfill mark source fetched", "error", err, "repo_id", candidate.SourceRepoID) |
| 81 | + } |
| 70 | 82 | } |
| 71 | | - } else if backfilled { |
| 72 | 83 | h.recordSubmoduleBackfill(ctx, route.Owner, route.RepoName, gitDir) |
| 73 | 84 | return route.TreeURL |
| 74 | 85 | } |
@@ -100,6 +111,49 @@ func (h *Handlers) backfillSubmoduleCommit(ctx context.Context, gitDir, fetchURL |
| 100 | 111 | return v.(bool), nil |
| 101 | 112 | } |
| 102 | 113 | |
| 114 | +type submoduleBackfillFetchCandidate struct { |
| 115 | + URL string |
| 116 | + SourceRepoID int64 |
| 117 | +} |
| 118 | + |
| 119 | +func (h *Handlers) submoduleBackfillFetchCandidates(ctx context.Context, cfg submoduleRouteConfig, route submoduleRoute, remoteURL string) []submoduleBackfillFetchCandidate { |
| 120 | + var out []submoduleBackfillFetchCandidate |
| 121 | + seen := map[string]struct{}{} |
| 122 | + if row, ok := h.lookupSubmoduleRepoRow(ctx, route.Owner, route.RepoName); ok { |
| 123 | + if sourceRemote, err := h.rq.GetRepoSourceRemote(ctx, h.d.Pool, row.ID); err == nil { |
| 124 | + if normalized, sourceErr := repos.ValidateSourceRemoteURL(ctx, sourceRemote.RemoteUrl); sourceErr == nil && normalized != "" { |
| 125 | + out = appendSubmoduleBackfillCandidate(out, seen, submoduleBackfillFetchCandidate{ |
| 126 | + URL: normalized, |
| 127 | + SourceRepoID: row.ID, |
| 128 | + }) |
| 129 | + } else if sourceErr != nil { |
| 130 | + h.markRepoSourceRemoteFetchError(ctx, row.ID, sourceErr) |
| 131 | + if h.d.Logger != nil { |
| 132 | + h.d.Logger.WarnContext(ctx, "code: submodule stored source remote rejected", "error", sourceErr, "repo_id", row.ID, "remote", sourceRemote.RemoteUrl) |
| 133 | + } |
| 134 | + } |
| 135 | + } else if !errors.Is(err, pgx.ErrNoRows) && h.d.Logger != nil { |
| 136 | + h.d.Logger.WarnContext(ctx, "code: submodule source remote lookup", "error", err, "repo_id", row.ID) |
| 137 | + } |
| 138 | + } |
| 139 | + if fetchURL, ok := githubSubmoduleFetchURL(cfg, remoteURL); ok { |
| 140 | + out = appendSubmoduleBackfillCandidate(out, seen, submoduleBackfillFetchCandidate{URL: fetchURL}) |
| 141 | + } |
| 142 | + return out |
| 143 | +} |
| 144 | + |
| 145 | +func appendSubmoduleBackfillCandidate(out []submoduleBackfillFetchCandidate, seen map[string]struct{}, candidate submoduleBackfillFetchCandidate) []submoduleBackfillFetchCandidate { |
| 146 | + candidate.URL = strings.TrimSpace(candidate.URL) |
| 147 | + if candidate.URL == "" { |
| 148 | + return out |
| 149 | + } |
| 150 | + if _, ok := seen[candidate.URL]; ok { |
| 151 | + return out |
| 152 | + } |
| 153 | + seen[candidate.URL] = struct{}{} |
| 154 | + return append(out, candidate) |
| 155 | +} |
| 156 | + |
| 103 | 157 | func (h *Handlers) recordSubmoduleBackfill(ctx context.Context, owner, repoName, gitDir string) { |
| 104 | 158 | row, ok := h.lookupSubmoduleRepoRow(ctx, owner, repoName) |
| 105 | 159 | if !ok { |