Skip to main content

mockforge_intelligence/pr_generation/
generator.rs

1//! PR generator for creating pull requests
2//!
3//! This module provides a unified interface for generating PRs across different providers.
4
5use crate::pr_generation::templates::{PRTemplate, PRTemplateContext};
6use crate::pr_generation::types::{PRProvider, PRRequest, PRResult};
7use crate::pr_generation::{GitHubPRClient, GitLabPRClient};
8use mockforge_foundation::{Error, Result};
9
10/// PR generator that works with multiple providers
11#[derive(Debug, Clone)]
12pub struct PRGenerator {
13    provider: PRProvider,
14    github_client: Option<GitHubPRClient>,
15    gitlab_client: Option<GitLabPRClient>,
16}
17
18impl PRGenerator {
19    /// Create a new PR generator for GitHub
20    pub fn new_github(owner: String, repo: String, token: String, base_branch: String) -> Self {
21        Self {
22            provider: PRProvider::GitHub,
23            github_client: Some(GitHubPRClient::new(owner, repo, token, base_branch)),
24            gitlab_client: None,
25        }
26    }
27
28    /// Create a new PR generator for GitLab
29    pub fn new_gitlab(owner: String, repo: String, token: String, base_branch: String) -> Self {
30        Self {
31            provider: PRProvider::GitLab,
32            github_client: None,
33            gitlab_client: Some(GitLabPRClient::new(owner, repo, token, base_branch)),
34        }
35    }
36
37    /// Generate and create a PR from template context
38    pub async fn create_pr_from_context(
39        &self,
40        context: PRTemplateContext,
41        files: Vec<crate::pr_generation::types::PRFileChange>,
42        labels: Vec<String>,
43        reviewers: Vec<String>,
44    ) -> Result<PRResult> {
45        let title = PRTemplate::generate_title(&context);
46        let body = PRTemplate::generate_body(&context);
47
48        let branch = format!(
49            "{}-{}-{}",
50            "mockforge/contract-update",
51            context.method.to_lowercase(),
52            &uuid::Uuid::new_v4().to_string()[..8]
53        );
54
55        let request = PRRequest {
56            title,
57            body,
58            branch,
59            files,
60            labels,
61            reviewers,
62        };
63
64        self.create_pr(request).await
65    }
66
67    /// Create a PR
68    pub async fn create_pr(&self, request: PRRequest) -> Result<PRResult> {
69        match self.provider {
70            PRProvider::GitHub => {
71                let client = self
72                    .github_client
73                    .as_ref()
74                    .ok_or_else(|| Error::internal("GitHub client not configured"))?;
75                client.create_pr(request).await
76            }
77            PRProvider::GitLab => {
78                let client = self
79                    .gitlab_client
80                    .as_ref()
81                    .ok_or_else(|| Error::internal("GitLab client not configured"))?;
82                client.create_pr(request).await
83            }
84        }
85    }
86}