populateLogSegments populates log segments from the provided jobs and data available in the given ZIP archive map. Any missing logs will be assigned a log fetcher that retrieves logs from the API. For example, if there's no step log available in the ZIP archive, the entire job log will be selected
(httpClient *http.Client, repo ghrepo.Interface, jobs []shared.Job, zlm *zipLogMap, onlyFailed bool)
| 87 | // fetchers to be assigned. This is to avoid overwhelming the API with too many |
| 88 | // requests. |
| 89 | func populateLogSegments(httpClient *http.Client, repo ghrepo.Interface, jobs []shared.Job, zlm *zipLogMap, onlyFailed bool) ([]logSegment, error) { |
| 90 | segments := make([]logSegment, 0, len(jobs)) |
| 91 | |
| 92 | apiLogFetcherCount := 0 |
| 93 | for _, job := range jobs { |
| 94 | if shared.IsSkipped(job.Conclusion) { |
| 95 | continue |
| 96 | } |
| 97 | |
| 98 | if onlyFailed && !shared.IsFailureState(job.Conclusion) { |
| 99 | continue |
| 100 | } |
| 101 | |
| 102 | stepLogAvailable := slices.ContainsFunc(job.Steps, func(step shared.Step) bool { |
| 103 | _, ok := zlm.forStep(job.ID, step.Number) |
| 104 | return ok |
| 105 | }) |
| 106 | |
| 107 | // If at least one step log is available, we populate the segments with |
| 108 | // them and don't use the entire job log. |
| 109 | if stepLogAvailable { |
| 110 | steps := slices.Clone(job.Steps) |
| 111 | sort.Sort(steps) |
| 112 | for _, step := range steps { |
| 113 | if onlyFailed && !shared.IsFailureState(step.Conclusion) { |
| 114 | continue |
| 115 | } |
| 116 | |
| 117 | zf, ok := zlm.forStep(job.ID, step.Number) |
| 118 | if !ok { |
| 119 | // We have no step log in the zip archive, but there's nothing we can do |
| 120 | // about that because there is no API endpoint to fetch step logs. |
| 121 | continue |
| 122 | } |
| 123 | |
| 124 | segments = append(segments, logSegment{ |
| 125 | job: &job, |
| 126 | step: &step, |
| 127 | fetcher: &zipLogFetcher{File: zf}, |
| 128 | }) |
| 129 | } |
| 130 | continue |
| 131 | } |
| 132 | |
| 133 | segment := logSegment{job: &job} |
| 134 | if zf, ok := zlm.forJob(job.ID); ok { |
| 135 | segment.fetcher = &zipLogFetcher{File: zf} |
| 136 | } else { |
| 137 | segment.fetcher = &apiLogFetcher{ |
| 138 | httpClient: httpClient, |
| 139 | repo: repo, |
| 140 | jobID: job.ID, |
| 141 | } |
| 142 | apiLogFetcherCount++ |
| 143 | } |
| 144 | segments = append(segments, segment) |
| 145 | |
| 146 | if apiLogFetcherCount > maxAPILogFetchers { |