Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Currently, the following modules are available as of version `0.17`.
- [`teams`] Teams.
- [`gists`] GitHub's gists API
- [`users`] Users.
- [`code_scannings`] Code scannings

[`models`]: https://docs.rs/octocrab/latest/octocrab/models/index.html
[`auth`]: https://docs.rs/octocrab/latest/octocrab/auth/index.html
Expand Down
1 change: 1 addition & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod actions;
pub mod activity;
pub mod apps;
pub mod checks;
pub mod code_scannings;
pub mod commits;
pub mod current;
pub mod events;
Expand Down
43 changes: 43 additions & 0 deletions src/api/code_scannings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! The code scanning API.
use crate::{models, params, Octocrab, Result};

mod list;

/// Handler for GitHub's code scanning API.
///
/// Created with [`Octocrab::code_scannings`].
pub struct CodeScanningHandler<'octo> {
crab: &'octo Octocrab,
owner: String,
repo: Option<String>,
}

impl<'octo> CodeScanningHandler<'octo> {
pub(crate) fn new(crab: &'octo Octocrab, owner: String, repo: Option<String>) -> Self {
Self { crab, owner, repo }
}

/// Gets an code scanning from the repository.
/// ```no_run
/// # async fn run() -> octocrab::Result<()> {
/// # let octocrab = octocrab::Octocrab::default();
/// let code_scanning = octocrab.code_scannings("owner", "repo").get(3).await?;
/// # Ok(())
/// # }
/// ```
pub async fn get(&mut self, number: u64) -> Result<models::code_scannings::CodeScanningAlert> {
let route = format!(
"/repos/{owner}/{repo}/code-scanning/alerts/{number}",
owner = self.owner,
repo = self.repo.as_mut().expect("Repository must be specified"),
number = number,
);

self.crab.get(route, None::<&()>).await
}

/// List code scannings in the repository.
pub fn list(&self) -> list::ListCodeScanningsBuilder<'_, '_> {
list::ListCodeScanningsBuilder::new(self)
}
}
100 changes: 100 additions & 0 deletions src/api/code_scannings/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use super::*;
use crate::params::Direction;

#[derive(crate::Serialize)]
pub struct ListCodeScanningsBuilder<'octo, 'b> {
#[serde(skip)]
handler: &'b CodeScanningHandler<'octo>,
#[serde(skip_serializing_if = "Option::is_none")]
tool_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
tool_guid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
per_page: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
reference: Option<params::code_scannings::Reference>,
#[serde(skip_serializing_if = "Option::is_none")]
direction: Option<Direction>,
#[serde(skip_serializing_if = "Option::is_none")]
sort: Option<params::code_scannings::Sort>,
#[serde(skip_serializing_if = "Option::is_none")]
state: Option<params::State>,
#[serde(skip_serializing_if = "Option::is_none")]
severity: Option<params::code_scannings::Severity>,
}

impl<'octo, 'b, 'c, 'd> ListCodeScanningsBuilder<'octo, 'b> {
pub(crate) fn new(handler: &'b CodeScanningHandler<'octo>) -> Self {
Self {
handler,
tool_name: None,
tool_guid: None,
per_page: None,
page: None,
reference: None,
direction: None,
sort: None,
state: None,
severity: None,
}
}

/// Filter pull requests by `state`.
pub fn state(mut self, state: params::State) -> Self {
self.state = Some(state);
self
}

/// What to sort results by. Can be either `created`, `updated`,
/// `popularity` (comment count) or `long-running` (age, filtering by pulls
/// updated in the last month).
pub fn sort(mut self, sort: impl Into<params::code_scannings::Sort>) -> Self {
self.sort = Some(sort.into());
self
}

/// The direction of the sort. Can be either ascending or descending.
/// Default: descending when sort is `created` or sort is not specified,
/// otherwise ascending sort.
pub fn direction(mut self, direction: impl Into<params::Direction>) -> Self {
self.direction = Some(direction.into());
self
}

/// Results per page (max 100).
pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
self.per_page = Some(per_page.into());
self
}

/// Page number of the results to fetch.
pub fn page(mut self, page: impl Into<u32>) -> Self {
self.page = Some(page.into());
self
}

/// Sends the actual request.
pub async fn send(
self,
) -> crate::Result<crate::Page<models::code_scannings::CodeScanningAlert>> {
let route = self
.handler
.repo
.as_ref()
.map(|r| {
format!(
"/repos/{owner}/{repo}/code-scanning/alerts",
owner = self.handler.owner,
repo = r,
)
})
.unwrap_or(format!(
"/orgs/{owner}/code-scanning/alerts",
owner = self.handler.owner,
));

self.handler.crab.get(route, Some(&self)).await
}
}
21 changes: 20 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ use crate::service::middleware::extra_headers::ExtraHeadersLayer;
#[cfg(feature = "retry")]
use crate::service::middleware::retry::RetryConfig;

use crate::api::users;
use crate::api::{code_scannings, users};
use auth::{AppAuth, Auth};
use models::{AppId, InstallationId, InstallationToken};

Expand Down Expand Up @@ -1047,6 +1047,25 @@ impl Octocrab {
issues::IssueHandler::new(self, owner.into(), repo.into())
}

/// Creates a [`code_scanning::CodeSCanningHandler`] for the repo specified at `owner/repo`,
/// that allows you to access GitHub's Code scanning API.
pub fn code_scannings(
&self,
owner: impl Into<String>,
repo: impl Into<String>,
) -> code_scannings::CodeScanningHandler {
code_scannings::CodeScanningHandler::new(self, owner.into(), Option::from(repo.into()))
}

/// Creates a [`code_scanning::CodeSCanningHandler`] for the org specified at `owner`,
/// that allows you to access GitHub's Code scanning API.
pub fn code_scannings_organisation(
&self,
owner: impl Into<String>,
) -> code_scannings::CodeScanningHandler {
code_scannings::CodeScanningHandler::new(self, owner.into(), None)
}

/// Creates a [`commits::CommitHandler`] for the repo specified at `owner/repo`,
pub fn commits(
&self,
Expand Down
2 changes: 2 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod actions;
pub mod activity;
pub mod apps;
pub mod checks;
pub mod code_scannings;
pub mod commits;
pub mod events;
pub mod gists;
Expand Down Expand Up @@ -105,6 +106,7 @@ id_type!(
CardId,
CheckSuiteId,
CheckRunId,
CodeScanningId,
CommentId,
InstallationId,
IssueEventId,
Expand Down
107 changes: 107 additions & 0 deletions src/models/code_scannings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use super::*;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CodeScanningAlert {
pub number: i64,
pub created_at: String,
pub updated_at: Option<String>,
pub url: String,
pub html_url: String,
pub state: String,
pub fixed_at: Option<String>,
pub dismissed_by: Dismisser,
pub dismissed_at: String,
pub dismissed_reason: String,
pub dismissed_comment: String,
pub rule: Rule,
pub tool: Tool,
pub most_recent_instance: MostRecentInstance,
pub instances_url: String,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Dismisser {
pub login: String,
pub id: UserId,
pub node_id: String,
pub avatar_url: Url,
pub gravatar_id: String,
pub url: Url,
pub html_url: Url,
pub followers_url: Url,
pub following_url: Url,
pub gists_url: Url,
pub starred_url: Url,
pub subscriptions_url: Url,
pub organizations_url: Url,
pub repos_url: Url,
pub events_url: Url,
pub received_events_url: Url,
pub r#type: String,
pub site_admin: bool,
pub patch_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Rule {
pub id: String,
pub severity: String,
pub description: String,
pub name: String,
pub tags: Vec<String>,
pub security_severity_level: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Tool {
pub name: String,
pub guid: Option<String>,
pub version: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct MostRecentInstance {
#[serde(rename = "ref")]
pub ref_field: String,
pub analysis_key: String,
pub environment: Environment,
pub category: String,
pub state: String,
pub commit_sha: String,
pub message: Message,
pub location: Location,
pub classifications: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Environment {
#[serde(rename = "build-mode")]
pub build_mode: Option<String>,
pub category: Option<String>,
pub language: Option<String>,
pub runner: Option<Vec<String>>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Message {
pub text: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Location {
pub path: String,
pub start_line: i64,
pub end_line: i64,
pub start_column: i64,
pub end_column: i64,
}
Loading