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