• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dcdpr / jp / 22154979281

18 Feb 2026 07:44PM UTC coverage: 55.288% (+1.3%) from 54.027%
22154979281

Pull #395

github

web-flow
Merge 0b5125385 into 76444fafa
Pull Request #395: Vet

780 of 1027 new or added lines in 36 files covered. (75.95%)

3 existing lines in 3 files now uncovered.

11606 of 20992 relevant lines covered (55.29%)

117.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/.config/jp/tools/src/github/pulls.rs
1
use chrono::{DateTime, Utc};
2
use jp_github::{models::repos::DiffEntryStatus, params};
3
use url::Url;
4

5
use super::auth;
6
use crate::{
7
    Result,
8
    github::{ORG, REPO, handle_404},
9
    to_xml, to_xml_with_root,
10
    util::OneOrMany,
11
};
12

13
/// The status of a issue or pull request.
14
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
15
#[serde(rename_all = "lowercase")]
16
pub enum State {
17
    Open,
18
    Closed,
19
}
20

21
pub(crate) async fn github_pulls(
×
22
    number: Option<u64>,
×
23
    state: Option<State>,
×
24
    file_diffs: Option<OneOrMany<String>>,
×
25
) -> Result<String> {
×
26
    auth().await?;
×
27

28
    let file_diffs = file_diffs.unwrap_or_default();
×
29

30
    match number {
×
31
        Some(number) if !file_diffs.is_empty() => diff(number, file_diffs.into_vec()).await,
×
32
        Some(number) => get(number).await,
×
33
        None => list(state).await,
×
34
    }
35
}
×
36

37
async fn get(number: u64) -> Result<String> {
×
38
    #[derive(serde::Serialize)]
39
    struct ChangedFile {
40
        filename: String,
41
        status: DiffEntryStatus,
42
        additions: u64,
43
        deletions: u64,
44
        changes: u64,
45
        previous_filename: Option<String>,
46
    }
47

48
    #[derive(serde::Serialize)]
49
    struct Pull {
50
        number: u64,
51
        title: Option<String>,
52
        body: Option<String>,
53
        url: Option<Url>,
54
        labels: Vec<String>,
55
        author: Option<String>,
56
        created_at: Option<DateTime<Utc>>,
57
        closed_at: Option<DateTime<Utc>>,
58
        merged_at: Option<DateTime<Utc>>,
59
        merge_commit_sha: Option<String>,
60
        changed_files: Vec<ChangedFile>,
61
    }
62

NEW
63
    let pull = jp_github::instance()
×
64
        .pulls(ORG, REPO)
×
65
        .get(number)
×
66
        .await
×
67
        .map_err(|e| handle_404(e, format!("Pull #{number} not found in {ORG}/{REPO}")))?;
×
68

NEW
69
    let page = jp_github::instance()
×
70
        .pulls(ORG, REPO)
×
71
        .list_files(number)
×
72
        .await
×
73
        .map_err(|e| handle_404(e, format!("Pull #{number} not found in {ORG}/{REPO}")))?;
×
74

NEW
75
    let changed_files = jp_github::instance()
×
76
        .all_pages(page)
×
77
        .await?
×
78
        .into_iter()
×
79
        .map(|file| ChangedFile {
×
80
            filename: file.filename,
×
81
            status: file.status,
×
82
            additions: file.additions,
×
83
            deletions: file.deletions,
×
84
            changes: file.changes,
×
85
            previous_filename: file.previous_filename,
×
86
        })
×
87
        .collect();
×
88

89
    to_xml(Pull {
×
90
        number,
×
91
        title: pull.title,
×
92
        body: pull.body,
×
93
        url: pull.html_url,
×
94
        labels: pull
×
95
            .labels
×
96
            .into_iter()
×
97
            .flatten()
×
98
            .map(|label| label.name)
×
99
            .collect(),
×
100
        author: pull.user.map(|user| user.login),
×
NEW
101
        created_at: pull.created_at,
×
NEW
102
        closed_at: pull.closed_at,
×
NEW
103
        merged_at: pull.merged_at,
×
104
        merge_commit_sha: pull.merge_commit_sha,
×
105
        changed_files,
×
106
    })
107
}
×
108

109
async fn diff(number: u64, file_diffs: Vec<String>) -> Result<String> {
×
110
    #[derive(serde::Serialize)]
111
    struct ChangedFile {
112
        filename: String,
113
        status: DiffEntryStatus,
114
        additions: u64,
115
        deletions: u64,
116
        changes: u64,
117
        previous_filename: Option<String>,
118
        patch: Option<String>,
119
    }
120

NEW
121
    let page = jp_github::instance()
×
122
        .pulls(ORG, REPO)
×
123
        .list_files(number)
×
124
        .await
×
125
        .map_err(|e| handle_404(e, format!("Pull #{number} not found in {ORG}/{REPO}")))?;
×
126

NEW
127
    let changed_files: Vec<_> = jp_github::instance()
×
128
        .all_pages(page)
×
129
        .await?
×
130
        .into_iter()
×
131
        .filter(|file| file_diffs.contains(&file.filename))
×
132
        .map(|file| ChangedFile {
×
133
            patch: file.patch,
×
134
            filename: file.filename,
×
135
            status: file.status,
×
136
            additions: file.additions,
×
137
            deletions: file.deletions,
×
138
            changes: file.changes,
×
139
            previous_filename: file.previous_filename,
×
140
        })
×
141
        .collect();
×
142

143
    to_xml_with_root(&changed_files, "files")
×
144
}
×
145

146
async fn list(state: Option<State>) -> Result<String> {
×
147
    #[derive(serde::Serialize)]
148
    struct Pulls {
149
        pull: Vec<Pull>,
150
    }
151

152
    #[derive(serde::Serialize)]
153
    struct Pull {
154
        number: u64,
155
        title: Option<String>,
156
        url: Option<Url>,
157
        labels: Vec<String>,
158
        author: Option<String>,
159
        created_at: Option<DateTime<Utc>>,
160
        closed_at: Option<DateTime<Utc>>,
161
        merged_at: Option<DateTime<Utc>>,
162
        merge_commit_sha: Option<String>,
163
    }
164

165
    let state = match state {
×
166
        Some(State::Open) => params::State::Open,
×
167
        Some(State::Closed) => params::State::Closed,
×
168
        None => params::State::All,
×
169
    };
170

NEW
171
    let page = jp_github::instance()
×
172
        .pulls(ORG, REPO)
×
173
        .list()
×
174
        .state(state)
×
175
        .per_page(100)
×
176
        .send()
×
177
        .await?;
×
178

NEW
179
    let pull = jp_github::instance()
×
180
        .all_pages(page)
×
181
        .await?
×
182
        .into_iter()
×
NEW
183
        .map(|pull| Pull {
×
NEW
184
            number: pull.number,
×
NEW
185
            title: pull.title,
×
NEW
186
            url: pull.html_url,
×
NEW
187
            labels: pull
×
NEW
188
                .labels
×
NEW
189
                .into_iter()
×
NEW
190
                .flatten()
×
NEW
191
                .map(|label| label.name)
×
NEW
192
                .collect(),
×
NEW
193
            author: pull.user.map(|user| user.login),
×
NEW
194
            created_at: pull.created_at,
×
NEW
195
            closed_at: pull.closed_at,
×
NEW
196
            merged_at: pull.merged_at,
×
NEW
197
            merge_commit_sha: pull.merge_commit_sha,
×
198
        })
×
NEW
199
        .collect();
×
200

201
    to_xml(Pulls { pull })
×
202
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc