gh_workflow_parser/err_msg_parse/
yocto_err.rs1use crate::{
2 commands::locate_failure_log::logfile_path_from_str, err_msg_parse::LOGFILE_MAX_LEN,
3 util::first_path_from_str,
4};
5use std::error::Error;
6
7use self::util::YoctoFailureKind;
8
9pub mod util;
10
11#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
12pub struct YoctoError {
13 summary: String,
14 kind: YoctoFailureKind,
15 logfile: Option<YoctoFailureLog>,
16}
17
18impl YoctoError {
19 pub fn new(summary: String, kind: YoctoFailureKind, logfile: Option<YoctoFailureLog>) -> Self {
20 YoctoError {
21 summary,
22 kind,
23 logfile,
24 }
25 }
26
27 pub fn summary(&self) -> &str {
28 &self.summary
29 }
30 pub fn kind(&self) -> YoctoFailureKind {
31 self.kind
32 }
33 pub fn logfile(&self) -> Option<&YoctoFailureLog> {
34 self.logfile.as_ref()
35 }
36}
37
38#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
39pub struct YoctoFailureLog {
40 pub name: String,
41 pub contents: String,
42}
43
44pub fn parse_yocto_error(log: &str) -> Result<YoctoError, Box<dyn Error>> {
47 let error_summary = util::yocto_error_summary(log)?;
48 log::debug!(
49 "Yocto error before trimming just recipe failures: \n{}",
50 error_summary
51 );
52
53 let error_summary = util::trim_trailing_just_recipes(&error_summary)?;
54 log::info!("Yocto error: \n{}", error_summary);
55
56 let log_file_line = util::find_yocto_failure_log_str(&error_summary)?;
61 let path = first_path_from_str(log_file_line)?;
62 let fname = path.file_stem().unwrap().to_str().unwrap();
63 let yocto_failure_kind = match YoctoFailureKind::parse_from_logfilename(fname) {
64 Ok(kind) => kind,
65 Err(e) => {
66 log::error!("{e}");
67 log::warn!("Could not determine yocto failure kind, continuing with default kind");
68 YoctoFailureKind::default()
69 },
70 };
71
72 let failure_log: Option<YoctoFailureLog> = match logfile_path_from_str(path.to_str().unwrap()) {
73 Ok(p) => {
74 let contents = std::fs::read_to_string(p)?;
75 if contents.len() > LOGFILE_MAX_LEN {
76 log::warn!("Logfile of yocto failure exceeds maximum length of {LOGFILE_MAX_LEN}. It will not be added to the issue body.");
77 None
78 } else {
79 Some(YoctoFailureLog {
80 name: fname.to_owned(),
81 contents,
82 })
83 }
84 },
85 Err(e) => {
86 log::trace!("{e}");
87 log::error!("Logfile from error summary does not exist at: {path:?}");
88 log::warn!("Continuing without attempting to attach logfile to issue");
89 None
90 },
91 };
92
93 let yocto_error = YoctoError {
94 summary: error_summary,
95 kind: yocto_failure_kind,
96 logfile: failure_log,
97 };
98
99 Ok(yocto_error)
100}