19 Jenkins.build_status_profiles ::: Isabelle_Cronjob.build_status_profiles |
19 Jenkins.build_status_profiles ::: Isabelle_Cronjob.build_status_profiles |
20 |
20 |
21 |
21 |
22 /* data profiles */ |
22 /* data profiles */ |
23 |
23 |
24 sealed case class Profile(description: String, history: Int, sql: String) |
24 sealed case class Profile( |
|
25 description: String, history: Int = 0, afp: Boolean = false, sql: String) |
25 { |
26 { |
26 def days(options: Options): Int = options.int("build_log_history") max history |
27 def days(options: Options): Int = options.int("build_log_history") max history |
27 |
28 |
28 def stretch(options: Options): Double = |
29 def stretch(options: Options): Double = |
29 (days(options) max default_history min (default_history * 5)).toDouble / default_history |
30 (days(options) max default_history min (default_history * 5)).toDouble / default_history |
30 |
31 |
31 def select(options: Options, columns: List[SQL.Column], only_sessions: Set[String]): SQL.Source = |
32 def select(options: Options, columns: List[SQL.Column], only_sessions: Set[String]): SQL.Source = |
32 { |
33 { |
33 Build_Log.Data.universal_table.select(columns, distinct = true, |
34 Build_Log.Data.universal_table.select(columns, distinct = true, |
34 sql = "WHERE " + |
35 sql = "WHERE " + |
35 Build_Log.Data.pull_date + " > " + Build_Log.Data.recent_time(days(options)) + " AND " + |
36 Build_Log.Data.pull_date(afp) + " > " + Build_Log.Data.recent_time(days(options)) + |
|
37 " AND " + |
36 SQL.member(Build_Log.Data.status.ident, |
38 SQL.member(Build_Log.Data.status.ident, |
37 List( |
39 List( |
38 Build_Log.Session_Status.finished.toString, |
40 Build_Log.Session_Status.finished.toString, |
39 Build_Log.Session_Status.failed.toString)) + |
41 Build_Log.Session_Status.failed.toString)) + |
40 (if (only_sessions.isEmpty) "" |
42 (if (only_sessions.isEmpty) "" |
41 else " AND " + SQL.member(Build_Log.Data.session_name.ident, only_sessions)) + |
43 else " AND " + SQL.member(Build_Log.Data.session_name.ident, only_sessions)) + |
42 " AND " + SQL.enclose(sql) + |
44 " AND " + SQL.enclose(sql) + |
43 " ORDER BY " + Build_Log.Data.pull_date) |
45 " ORDER BY " + Build_Log.Data.pull_date(afp)) |
44 } |
46 } |
45 } |
47 } |
46 |
48 |
47 |
49 |
48 /* build status */ |
50 /* build status */ |
107 { |
109 { |
108 def finished: Boolean = status == Build_Log.Session_Status.finished |
110 def finished: Boolean = status == Build_Log.Session_Status.finished |
109 def failed: Boolean = status == Build_Log.Session_Status.failed |
111 def failed: Boolean = status == Build_Log.Session_Status.failed |
110 |
112 |
111 def present_errors(name: String): XML.Body = |
113 def present_errors(name: String): XML.Body = |
112 if (errors.isEmpty) HTML.text(name + " (" + isabelle_version + ")") |
114 { |
|
115 if (errors.isEmpty) HTML.text(name + print_versions(isabelle_version, afp_version)) |
113 else { |
116 else { |
114 HTML.tooltip_errors(HTML.text(name), errors.map(s => HTML.text(Symbol.decode(s)))) :: |
117 HTML.tooltip_errors(HTML.text(name), errors.map(s => HTML.text(Symbol.decode(s)))) :: |
115 HTML.text(" (" + isabelle_version + ")") |
118 HTML.text(print_versions(isabelle_version, afp_version)) |
116 } |
119 } |
|
120 } |
117 } |
121 } |
118 |
122 |
119 sealed case class Image(name: String, width: Int, height: Int) |
123 sealed case class Image(name: String, width: Int, height: Int) |
120 { |
124 { |
121 def path: Path = Path.basic(name) |
125 def path: Path = Path.basic(name) |
|
126 } |
|
127 |
|
128 def print_versions(isabelle_version: String, afp_version: String): String = |
|
129 { |
|
130 val body = |
|
131 proper_string(isabelle_version).map("Isabelle/" + _).toList ::: |
|
132 proper_string(afp_version).map("AFP/" + _).toList |
|
133 if (body.isEmpty) "" else body.mkString(" (", ", ", ")") |
122 } |
134 } |
123 |
135 |
124 def read_data(options: Options, |
136 def read_data(options: Options, |
125 progress: Progress = No_Progress, |
137 progress: Progress = No_Progress, |
126 profiles: List[Profile] = default_profiles, |
138 profiles: List[Profile] = default_profiles, |
140 using(store.open_database())(db => |
152 using(store.open_database())(db => |
141 { |
153 { |
142 for (profile <- profiles.sortBy(_.description)) { |
154 for (profile <- profiles.sortBy(_.description)) { |
143 progress.echo("input " + quote(profile.description)) |
155 progress.echo("input " + quote(profile.description)) |
144 |
156 |
|
157 val afp = profile.afp |
145 val columns = |
158 val columns = |
146 List( |
159 List( |
147 Build_Log.Data.pull_date, |
160 Build_Log.Data.pull_date(afp), |
148 Build_Log.Prop.build_host, |
161 Build_Log.Prop.build_host, |
149 Build_Log.Prop.isabelle_version, |
162 Build_Log.Prop.isabelle_version, |
150 Build_Log.Prop.afp_version, |
163 Build_Log.Prop.afp_version, |
151 Build_Log.Settings.ISABELLE_BUILD_OPTIONS, |
164 Build_Log.Settings.ISABELLE_BUILD_OPTIONS, |
152 Build_Log.Settings.ML_PLATFORM, |
165 Build_Log.Settings.ML_PLATFORM, |
193 data_hosts += (data_name -> (get_hosts(data_name) + host))) |
206 data_hosts += (data_name -> (get_hosts(data_name) + host))) |
194 |
207 |
195 data_stretch += (data_name -> profile.stretch(options)) |
208 data_stretch += (data_name -> profile.stretch(options)) |
196 |
209 |
197 val isabelle_version = res.string(Build_Log.Prop.isabelle_version) |
210 val isabelle_version = res.string(Build_Log.Prop.isabelle_version) |
|
211 val afp_version = res.string(Build_Log.Prop.afp_version) |
198 |
212 |
199 val ml_stats = |
213 val ml_stats = |
200 ML_Statistics( |
214 ML_Statistics( |
201 if (ml_statistics) |
215 if (ml_statistics) |
202 Properties.uncompress(res.bytes(Build_Log.Data.ml_statistics)) |
216 Properties.uncompress(res.bytes(Build_Log.Data.ml_statistics)) |
203 else Nil, heading = session_name + " (Isabelle/" + isabelle_version + ")") |
217 else Nil, heading = session_name + print_versions(isabelle_version, afp_version)) |
204 |
218 |
205 val entry = |
219 val entry = |
206 Entry( |
220 Entry( |
207 pull_date = res.date(Build_Log.Data.pull_date), |
221 pull_date = res.date(Build_Log.Data.pull_date(afp)), |
208 isabelle_version = isabelle_version, |
222 isabelle_version = isabelle_version, |
209 afp_version = res.string(Build_Log.Prop.afp_version), |
223 afp_version = afp_version, |
210 timing = |
224 timing = |
211 res.timing( |
225 res.timing( |
212 Build_Log.Data.timing_elapsed, |
226 Build_Log.Data.timing_elapsed, |
213 Build_Log.Data.timing_cpu, |
227 Build_Log.Data.timing_cpu, |
214 Build_Log.Data.timing_gc), |
228 Build_Log.Data.timing_gc), |