~raboof/nixpkgs-contributor-dashboard

ref: 08df9196d56f45cbba0d6d9feeb1231481539f68 nixpkgs-contributor-dashboard/src/bin/fetch_failures.rs -rw-r--r-- 2.0 KiB
08df9196 — Arnout Engelen Add feature for clearing PR's 1 year, 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
extern crate nixpkgs_contributor_dashboard;
extern crate diesel;

use self::diesel::prelude::*;
use self::nixpkgs_contributor_dashboard::*;
use self::models::*;
use self::schema::*;
use regex::Regex;

type Result<T> = std::result::Result<T, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>;

#[tokio::main]
pub async fn main() -> Result<()> {
    let trunk_combined_index = reqwest::get("https://hydra.nixos.org/jobset/nixos/trunk-combined").await?.text().await?;
    let re: Regex = Regex::new(r"href=.(?P<url>https://hydra.nixos.org/eval/\d+)").unwrap();
    let link_to_latest_eval = re.captures(trunk_combined_index.as_str()).and_then(|cap| {
      cap.name("url").map(|url| url.as_str())
    });

    let eval = reqwest::get(link_to_latest_eval.unwrap()).await?.text().await?;
    let match_fails_tab: Regex = Regex::new(r"id=.tabs-still-fail(?s:.)*?<tbody>(?P<failure_tab>(?s:.)*?)id=.tabs-still-succ").unwrap();
    let fails_tab = match_fails_tab.captures(eval.as_str()).and_then(|cap| {
        cap.name("failure_tab").map(|tab| tab.as_str())
    });

    let match_fails: Regex = Regex::new(r"<td><a class=.row-link. href=.(?P<url>.*?).>(?P<number>.*?)</a></td>\s*<td>[^>]*>(?P<job>[^<]*).*\n\s*<td>(?P<package>[^<]*)").unwrap();
    let fails = match_fails.captures_iter(fails_tab.unwrap()).map(|cap| {
        NewItem {
            kind: "BUILD",
            draft: 0,
            number: cap.name("number").unwrap().as_str().parse().unwrap(),
            package: cap.name("package").unwrap().as_str(),
            title: cap.name("job").unwrap().as_str(),
            html_url: cap.name("url").unwrap().as_str(),
        }
    });

    let connection = establish_connection();
    for new_item in fails {
        print!("{}\n", new_item.title);
        diesel::insert_into(items::table)
            .values(&new_item)
            // Why does 'on_conflict()' not work here?
            .execute(&connection)
            .expect("Error saving failure");
    }
    Ok(())
}