Add PATCH support in Gitea client and update issue handling
Extend Gitea client with a `patch` method for executing PATCH requests. Introduce `IssueWriteSetBody` struct for serializing issue update payloads. Update Gitea action to append related issues and send PATCH requests to update issue descriptions.
This commit is contained in:
		| @@ -2,12 +2,12 @@ use crate::cli::Issue2Work; | ||||
| use crate::config::Config; | ||||
| use crate::error::GeneralError; | ||||
| use crate::gitea::client::has_client_for_url; | ||||
| use crate::gitea::issue::{issue_html_url_to_api, Issue}; | ||||
| use crate::gitea::issue::{issue_html_url_to_api, Issue, IssueWriteSetBody}; | ||||
| use crate::openproject::user::{GetMe, User}; | ||||
| use crate::openproject::work::WorkPackageWriter; | ||||
| use crate::planning::utils::{append_related_issues, IssueRelated}; | ||||
| use crate::planning::Issue2WorkActionTrait; | ||||
| use url::Url; | ||||
| use crate::planning::utils::{append_related_issues, IssueRelated}; | ||||
|  | ||||
| pub(crate) struct GiteaAction {} | ||||
|  | ||||
| @@ -33,20 +33,28 @@ impl Issue2WorkActionTrait for GiteaAction { | ||||
|             .create_work_package(&work_package, &args.project_id) | ||||
|             .await?; | ||||
|  | ||||
|         let url = format!( | ||||
|         let url_wp = format!( | ||||
|             "{}/projects/{}/work_packages/{}", | ||||
|             config.openproject.base_url, args.project_id, work_package.id | ||||
|         ); | ||||
|  | ||||
|         let content = append_related_issues(&IssueRelated::OpenProjectIssue(url.to_string()), &issue.body); | ||||
|  | ||||
|         let content = append_related_issues( | ||||
|             &IssueRelated::OpenProjectIssue(url_wp.to_string()), | ||||
|             &issue.body, | ||||
|         ); | ||||
|         let _u: Issue = gitea_client | ||||
|             .patch( | ||||
|                 issue_html_url_to_api(url)?, | ||||
|                 &IssueWriteSetBody { body: content }, | ||||
|             ) | ||||
|             .await?; | ||||
|  | ||||
|         println!( | ||||
|             "new work package created: {:?}, edit at {}", | ||||
|             work_package.subject, url | ||||
|             work_package.subject, url_wp | ||||
|         ); | ||||
|  | ||||
|         if let Err(e) = open::that(url) { | ||||
|         if let Err(e) = open::that(url_wp) { | ||||
|             println!("failed to open work package in browser: {}", e); | ||||
|         }; | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| use crate::config::{Config, GiteaConfig}; | ||||
| use crate::error::GeneralError; | ||||
| use reqwest::header::{HeaderMap, ACCEPT, AUTHORIZATION}; | ||||
| use reqwest::{ClientBuilder, StatusCode}; | ||||
| use reqwest::{Body, ClientBuilder, StatusCode}; | ||||
| use serde::de::DeserializeOwned; | ||||
| use serde::Serialize; | ||||
| use url::Url; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| @@ -79,6 +80,38 @@ impl Client { | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub async fn patch<T: DeserializeOwned, B: Serialize>( | ||||
|         &self, | ||||
|         url: Url, | ||||
|         body: &B, | ||||
|     ) -> Result<T, GeneralError> { | ||||
|         let mut headers = HeaderMap::new(); | ||||
|         headers.append(AUTHORIZATION, format!("token {}", self.token).parse()?); | ||||
|         headers.append(ACCEPT, "application/json".parse()?); | ||||
|  | ||||
|         let client = ClientBuilder::new() | ||||
|             .default_headers(headers) | ||||
|             .build() | ||||
|             .unwrap(); | ||||
|  | ||||
|         let response = client.patch(url.clone()).json(body).send().await?; | ||||
|  | ||||
|         match response.status() { | ||||
|             StatusCode::OK | StatusCode::CREATED => { | ||||
|                 let result: T = response.json().await?; | ||||
|  | ||||
|                 Ok(result) | ||||
|             } | ||||
|             _ => Err(GeneralError { | ||||
|                 description: format!( | ||||
|                     "Could not call PATCH on {:?}, error code {}", | ||||
|                     url, | ||||
|                     response.status() | ||||
|                 ), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| use crate::error::GeneralError; | ||||
| use crate::gitea::client::Client; | ||||
| use crate::gitea::repository::Repository; | ||||
| use serde::Deserialize; | ||||
| use reqwest::Body; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use url::Url; | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
| @@ -14,6 +15,11 @@ pub struct Issue { | ||||
|     pub html_url: String, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Serialize)] | ||||
| pub struct IssueWriteSetBody { | ||||
|     pub body: String, | ||||
| } | ||||
|  | ||||
| pub trait IssueClient { | ||||
|     fn get_issue(owner_or_organisation: &String, repo: &String, number: &u64) -> Option<Issue>; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user