Skip to content

Commit 7c760fe

Browse files
committed
fix build-details view for pre-build errors, when another build set the default target
1 parent 5ec4326 commit 7c760fe

File tree

1 file changed

+76
-22
lines changed

1 file changed

+76
-22
lines changed

src/web/build_details.rs

+76-22
Original file line numberDiff line numberDiff line change
@@ -93,37 +93,53 @@ pub(crate) async fn build_details_handler(
9393
.ok_or(AxumNope::BuildNotFound)?;
9494

9595
let (output, all_log_filenames, current_filename) = if let Some(output) = row.output {
96+
// legacy case, for old builds the build log was stored in the database.
9697
(output, Vec::new(), None)
9798
} else {
99+
// for newer builds we have the build logs stored in S3.
100+
// For a long time only for one target, then we started storing the logs for other targets
101+
// toFor a long time only for one target, then we started storing the logs for other
102+
// targets. In any case, all the logfiles are put into a folder we can just query.
98103
let prefix = format!("build-logs/{}/", id);
104+
let all_log_filenames: Vec<_> = storage
105+
.list_prefix(&prefix) // the result from S3 is ordered by key
106+
.await
107+
.map_ok(|path| {
108+
path.strip_prefix(&prefix)
109+
.expect("since we query for the prefix, it has to be always there")
110+
.to_owned()
111+
})
112+
.try_collect()
113+
.await?;
99114

100-
if let Some(current_filename) = params
101-
.filename
102-
.or(row.default_target.map(|target| format!("{}.txt", target)))
103-
{
104-
let path = format!("{prefix}{current_filename}");
105-
let file = File::from_path(&storage, &path, &config).await?;
106-
(
107-
String::from_utf8(file.0.content).context("non utf8")?,
108-
storage
109-
.list_prefix(&prefix) // the result from S3 is ordered by key
110-
.await
111-
.map_ok(|path| {
112-
path.strip_prefix(&prefix)
113-
.expect("since we query for the prefix, it has to be always there")
114-
.to_owned()
115-
})
116-
.try_collect()
117-
.await?,
118-
Some(current_filename),
119-
)
115+
let current_filename = if let Some(filename) = params.filename {
116+
// if we have a given filename in the URL, we use that one.
117+
Some(filename)
118+
} else if let Some(default_target) = row.default_target {
119+
// without a filename in the URL, we try to show the build log
120+
// for the default target, if we have one.
121+
let wanted_filename = format!("{default_target}.txt");
122+
if all_log_filenames.contains(&wanted_filename) {
123+
Some(wanted_filename)
124+
} else {
125+
None
126+
}
120127
} else {
121128
// this can only happen when `releases.default_target` is NULL,
122129
// which is the case for in-progress builds or builds which errored
123130
// before we could determine the target.
124131
// For the "error" case we show `row.errors`, which should contain what we need to see.
125-
("".into(), Vec::new(), None)
126-
}
132+
None
133+
};
134+
135+
let file_content = if let Some(ref filename) = current_filename {
136+
let file = File::from_path(&storage, &format!("{prefix}{filename}"), &config).await?;
137+
String::from_utf8(file.0.content).context("non utf8")?
138+
} else {
139+
"".to_string()
140+
};
141+
142+
(file_content, all_log_filenames, current_filename)
127143
};
128144

129145
Ok(BuildDetailsPage {
@@ -197,6 +213,44 @@ mod tests {
197213
});
198214
}
199215

216+
#[test]
217+
fn test_partial_build_result_plus_default_target_from_previous_build() {
218+
async_wrapper(|env| async move {
219+
let mut conn = env.async_db().await.async_conn().await;
220+
let (release_id, build_id) = fake_release_that_failed_before_build(
221+
&mut conn,
222+
"foo",
223+
"0.1.0",
224+
"some random error",
225+
)
226+
.await?;
227+
228+
sqlx::query!(
229+
"UPDATE releases SET default_target = 'x86_64-unknown-linux-gnu' WHERE id = $1",
230+
release_id.0
231+
)
232+
.execute(&mut *conn)
233+
.await?;
234+
235+
let page = kuchikiki::parse_html().one(
236+
env.web_app()
237+
.await
238+
.get(&format!("/crate/foo/0.1.0/builds/{build_id}"))
239+
.await?
240+
.error_for_status()?
241+
.text()
242+
.await?,
243+
);
244+
245+
let info_text = page.select("pre").unwrap().next().unwrap().text_contents();
246+
247+
assert!(info_text.contains("# pre-build errors"), "{}", info_text);
248+
assert!(info_text.contains("some random error"), "{}", info_text);
249+
250+
Ok(())
251+
});
252+
}
253+
200254
#[test]
201255
fn db_build_logs() {
202256
async_wrapper(|env| async move {

0 commit comments

Comments
 (0)