Skip to content

Commit b648b96

Browse files
Allow webhook to link to list of crates
1 parent c05f80f commit b648b96

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

src/server/routes/webhooks/args.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
11
use crate::experiments::{Assignee, CapLints, CrateSelect, Mode};
22
use crate::toolchain::Toolchain;
3+
use failure::{self, Fallible};
4+
use reqwest;
5+
use url::Url;
6+
7+
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
8+
pub enum DeferredCrateSelect {
9+
Direct(CrateSelect),
10+
Indirect(Url),
11+
}
12+
13+
impl From<CrateSelect> for DeferredCrateSelect {
14+
fn from(v: CrateSelect) -> Self {
15+
DeferredCrateSelect::Direct(v)
16+
}
17+
}
18+
19+
impl DeferredCrateSelect {
20+
pub fn resolve(self) -> Fallible<CrateSelect> {
21+
let url = match self {
22+
DeferredCrateSelect::Direct(v) => return Ok(v),
23+
DeferredCrateSelect::Indirect(url) => url,
24+
};
25+
26+
let body = reqwest::get(url)?.text()?;
27+
if body.contains(",") {
28+
bail!("Crate identifiers must not contain a comma");
29+
}
30+
31+
let crates = body
32+
.split(|c: char| c.is_whitespace())
33+
.map(|s| s.to_owned())
34+
.collect();
35+
Ok(CrateSelect::List(crates).into())
36+
}
37+
}
38+
39+
impl FromStr for DeferredCrateSelect {
40+
type Err = failure::Error;
41+
42+
fn from_str(input: &str) -> Fallible<Self> {
43+
if input.starts_with("https://") || input.starts_with("http://") {
44+
Ok(DeferredCrateSelect::Indirect(input.parse()?))
45+
} else {
46+
Ok(DeferredCrateSelect::Direct(input.parse()?))
47+
}
48+
}
49+
}
350

451
#[derive(Debug, Fail)]
552
#[cfg_attr(test, derive(PartialEq, Eq))]
@@ -107,7 +154,7 @@ generate_parser!(pub enum Command {
107154
start: Option<Toolchain> = "start",
108155
end: Option<Toolchain> = "end",
109156
mode: Option<Mode> = "mode",
110-
crates: Option<CrateSelect> = "crates",
157+
crates: Option<DeferredCrateSelect> = "crates",
111158
cap_lints: Option<CapLints> = "cap-lints",
112159
priority: Option<i32> = "p",
113160
ignore_blacklist: Option<bool> = "ignore-blacklist",
@@ -136,7 +183,7 @@ generate_parser!(pub enum Command {
136183
start: Option<Toolchain> = "start",
137184
end: Option<Toolchain> = "end",
138185
mode: Option<Mode> = "mode",
139-
crates: Option<CrateSelect> = "crates",
186+
crates: Option<DeferredCrateSelect> = "crates",
140187
cap_lints: Option<CapLints> = "cap-lints",
141188
priority: Option<i32> = "p",
142189
ignore_blacklist: Option<bool> = "ignore-blacklist",

src/server/routes/webhooks/commands.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ pub fn run(
5656

5757
// Make crater runs created via webhook require linux by default.
5858
let requirement = args.requirement.unwrap_or_else(|| "linux".to_string());
59+
let crates = args
60+
.crates
61+
.map(|c| c.resolve())
62+
.transpose()
63+
.map_err(|e| e.context("Failed to resolve crate list"))?;
5964

6065
actions::CreateExperiment {
6166
name: name.clone(),
@@ -68,7 +73,7 @@ pub fn run(
6873
.ok_or_else(|| err_msg("missing end toolchain"))?,
6974
],
7075
mode: args.mode.unwrap_or(Mode::BuildAndTest),
71-
crates: args.crates.unwrap_or(CrateSelect::Full),
76+
crates: crates.unwrap_or(CrateSelect::Full),
7277
cap_lints: args.cap_lints.unwrap_or(CapLints::Forbid),
7378
priority: args.priority.unwrap_or(0),
7479
github_issue: Some(GitHubIssue {
@@ -104,10 +109,16 @@ pub fn run(
104109
pub fn edit(data: &Data, issue: &Issue, args: EditArgs) -> Fallible<()> {
105110
let name = get_name(&data.db, issue, args.name)?;
106111

112+
let crates = args
113+
.crates
114+
.map(|c| c.resolve())
115+
.transpose()
116+
.map_err(|e| e.context("Failed to resolve crate list"))?;
117+
107118
actions::EditExperiment {
108119
name: name.clone(),
109120
toolchains: [args.start, args.end],
110-
crates: args.crates,
121+
crates,
111122
mode: args.mode,
112123
cap_lints: args.cap_lints,
113124
priority: args.priority,

0 commit comments

Comments
 (0)