-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor to use dedicated handler for config validation
- Loading branch information
Showing
3 changed files
with
137 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
//! For pull requests that have changed the triagebot.toml, validate that the | ||
//! changes are a valid configuration file. | ||
//! It won't validate anything unless the PR is open and has changed. | ||
//! For every event, it will fetch the diff of the pull request which is one | ||
//! round-trip of HTTP request to the GitHub API, and another round-trip to | ||
//! fetch the triagebot.toml if it has changed. | ||
|
||
use crate::{ | ||
config::ValidateConfig, | ||
github::{IssuesAction}, | ||
handlers::{Context, IssuesEvent}, | ||
}; | ||
use tracing as log; | ||
|
||
/// If the issue is a pull request and if among the changed files, triagebot.toml | ||
/// is changed, then validate the triagebot.toml config file with the syntax | ||
/// parser from the config module. | ||
pub(super) async fn parse_input( | ||
ctx: &Context, | ||
event: &IssuesEvent, | ||
_config: Option<&ValidateConfig>, | ||
) -> Result<Option<()>, String> { | ||
if !event.issue.is_pr() { | ||
log::debug!("Ignoring issue: {:?}", event.issue); | ||
return Ok(None); | ||
} | ||
|
||
if !matches!( | ||
event.action, | ||
IssuesAction::Opened | IssuesAction::Synchronize | IssuesAction::ReadyForReview, | ||
) { | ||
log::debug!("Ignoring issue action: {:?}", event.action); | ||
return Ok(None); | ||
} | ||
|
||
let diff = match event.issue.diff(&ctx.github).await { | ||
Ok(Some(diff)) => diff, | ||
wildcard => { | ||
log::error!("Failed to fetch diff: {:?}", wildcard); | ||
return Ok(None); | ||
} | ||
}; | ||
|
||
if diff.contains(crate::config::CONFIG_FILE_NAME) { | ||
log::debug!("Validating triagebot config"); | ||
match validate_triagebot_config(ctx, event).await { | ||
Ok(()) => { | ||
log::debug!("Valid triagebot config"); | ||
return Ok(Some(())); | ||
} | ||
Err(e) => { | ||
log::debug!("Invalid triagebot config: {:?}", e); | ||
return Err(e); | ||
} | ||
} | ||
} | ||
|
||
Ok(None) | ||
} | ||
|
||
async fn validate_triagebot_config(ctx: &Context, event: &IssuesEvent) -> Result<(), String> { | ||
if let Some(pr_source) = &event.issue.head { | ||
if let Ok(Some(triagebot_toml)) = ctx | ||
.github | ||
.raw_file( | ||
&pr_source.repo.full_name, | ||
&pr_source.git_ref, | ||
crate::config::CONFIG_FILE_NAME, | ||
) | ||
.await | ||
{ | ||
match toml::from_slice::<crate::handlers::Config>(&triagebot_toml) { | ||
Ok(_) => return Ok(()), | ||
Err(e) => { | ||
let position = e.line_col().map(|(line, col)| format!("{}:{}", line + 1, col + 1)); | ||
let triagebot_toml_blob_url = event | ||
.issue | ||
.files(&ctx.github) | ||
.await | ||
.expect("Failed to fetch files") | ||
.iter() | ||
.find(|file| file.filename == crate::config::CONFIG_FILE_NAME) | ||
.unwrap() | ||
.blob_url | ||
.clone(); | ||
|
||
let absolute_url = format!( | ||
"{}#L{}", | ||
triagebot_toml_blob_url, | ||
position.clone().unwrap_or_default() | ||
); | ||
|
||
return Err(format!( | ||
"Invalid triagebot.toml at position {}", | ||
format!( | ||
"[{}]({})", | ||
position.unwrap_or_default(), | ||
absolute_url | ||
) | ||
)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
pub(super) async fn handle_input( | ||
_ctx: &Context, | ||
_config: &ValidateConfig, | ||
_event: &IssuesEvent, | ||
_input: (), | ||
) -> anyhow::Result<()> { | ||
Ok(()) | ||
} | ||
|
||
pub(super) struct ValidationInput { | ||
diff: String, | ||
} |