GitHubMiner

Struct GitHubMiner 

Source
pub struct GitHubMiner { /* private fields */ }
Expand description

GitHub organization miner Phase 1: Basic organization and repository fetching

ImplementationsΒ§

SourceΒ§

impl GitHubMiner

Source

pub fn new(token: Option<String>) -> Self

Create a new GitHub miner

Β§Arguments
  • token - Optional GitHub personal access token for authenticated requests
Β§Examples
use organizational_intelligence_plugin::github::GitHubMiner;

// Public repos only (unauthenticated)
let miner = GitHubMiner::new(None);

// With authentication (higher rate limits)
let miner_auth = GitHubMiner::new(Some("ghp_token".to_string()));
Examples found in repository?
examples/analyze_org.rs (line 29)
19async fn main() -> Result<()> {
20    // Initialize logging
21    tracing_subscriber::fmt::fmt()
22        .with_max_level(tracing::Level::INFO)
23        .init();
24
25    println!("πŸš€ Organizational Intelligence Plugin - Example");
26    println!("   Analyzing organization: tokio-rs\n");
27
28    // Initialize GitHub client (unauthenticated for this example)
29    let miner = GitHubMiner::new(None);
30
31    // Fetch organization repositories
32    println!("πŸ“₯ Fetching repositories...");
33    let repos = miner.fetch_organization_repos("tokio-rs").await?;
34
35    println!("βœ… Found {} repositories\n", repos.len());
36
37    // Display top 3 by stars
38    let mut sorted_repos = repos.clone();
39    sorted_repos.sort_by(|a, b| b.stars.cmp(&a.stars));
40
41    println!("⭐ Top repositories:");
42    for (i, repo) in sorted_repos.iter().take(3).enumerate() {
43        println!(
44            "   {}. {} ({} ⭐) - {}",
45            i + 1,
46            repo.name,
47            repo.stars,
48            repo.language.as_deref().unwrap_or("Unknown")
49        );
50    }
51
52    // Generate report
53    println!("\nπŸ“Š Generating YAML report...");
54    let report_generator = ReportGenerator::new();
55
56    let metadata = AnalysisMetadata {
57        organization: "tokio-rs".to_string(),
58        analysis_date: Utc::now().to_rfc3339(),
59        repositories_analyzed: repos.len(),
60        commits_analyzed: 0, // Phase 1: Not analyzing commits yet
61        analyzer_version: env!("CARGO_PKG_VERSION").to_string(),
62    };
63
64    let report = AnalysisReport {
65        version: "1.0".to_string(),
66        metadata,
67        defect_patterns: vec![], // Phase 1: No classifier yet
68    };
69
70    // Write to file
71    let output_path = PathBuf::from("tokio-rs-analysis.yaml");
72    report_generator
73        .write_to_file(&report, &output_path)
74        .await?;
75
76    println!("βœ… Report saved to: {}", output_path.display());
77
78    // Display a sample of the YAML
79    let yaml_content = tokio::fs::read_to_string(&output_path).await?;
80    println!("\nπŸ“„ Report preview:");
81    println!("---");
82    for (i, line) in yaml_content.lines().take(15).enumerate() {
83        println!("{}", line);
84        if i == 14 && yaml_content.lines().count() > 15 {
85            println!("   ... (truncated)");
86        }
87    }
88    println!("---");
89
90    println!("\n🎯 Example complete!");
91    println!("   Phase 1 MVP features demonstrated:");
92    println!("   βœ… GitHub API integration");
93    println!("   βœ… Repository fetching");
94    println!("   βœ… YAML report generation");
95
96    Ok(())
97}
More examples
Hide additional examples
examples/full_analysis.rs (line 31)
20async fn main() -> Result<()> {
21    // Initialize logging
22    tracing_subscriber::fmt::fmt()
23        .with_max_level(tracing::Level::INFO)
24        .init();
25
26    println!("πŸš€ Organizational Intelligence Plugin - Full Analysis Example\n");
27    println!("Demonstrates: GitHub API β†’ Git Mining β†’ Classification β†’ YAML Report\n");
28
29    // Step 1: Fetch repositories from GitHub organization
30    println!("πŸ“₯ Step 1: Fetching repositories from GitHub...");
31    let github_miner = GitHubMiner::new(None); // Unauthenticated for demo
32    let org_name = "tokio-rs";
33
34    let repos = github_miner.fetch_organization_repos(org_name).await?;
35    println!("βœ… Found {} repositories in {}\n", repos.len(), org_name);
36
37    // Display top repositories
38    let mut sorted_repos = repos.clone();
39    sorted_repos.sort_by(|a, b| b.stars.cmp(&a.stars));
40
41    println!("⭐ Top 3 repositories:");
42    for (i, repo) in sorted_repos.iter().take(3).enumerate() {
43        println!("   {}. {} ({} ⭐)", i + 1, repo.name, repo.stars);
44    }
45    println!();
46
47    // Step 2: Analyze repositories for defect patterns
48    println!("πŸ” Step 2: Analyzing commit history for defect patterns...");
49
50    // Create temporary directory for cloning
51    let temp_dir = TempDir::new()?;
52    let analyzer = OrgAnalyzer::new(temp_dir.path());
53
54    // Analyze top repository (limit to 100 commits for demo speed)
55    let top_repo = &sorted_repos[0];
56    println!("   Analyzing: {} (up to 100 commits)", top_repo.name);
57
58    let patterns = analyzer
59        .analyze_repository(
60            &format!("https://github.com/{}/{}", org_name, top_repo.name),
61            &top_repo.name,
62            100,
63        )
64        .await?;
65
66    if patterns.is_empty() {
67        println!("   ℹ️  No defect patterns detected in last 100 commits");
68    } else {
69        println!("   βœ… Found {} defect categories\n", patterns.len());
70
71        // Display patterns
72        println!("πŸ“Š Defect Patterns Found:");
73        for pattern in &patterns {
74            println!(
75                "   β€’ {} (n={}, confidence={:.0}%)",
76                pattern.category.as_str(),
77                pattern.frequency,
78                pattern.confidence * 100.0
79            );
80            if !pattern.examples.is_empty() {
81                let example = &pattern.examples[0];
82                println!("     Example: {}: {}", example.commit_hash, example.message);
83            }
84        }
85        println!();
86    }
87
88    // Step 3: Generate YAML report
89    println!("πŸ“ Step 3: Generating YAML report...");
90    let report_generator = ReportGenerator::new();
91
92    let metadata = AnalysisMetadata {
93        organization: org_name.to_string(),
94        analysis_date: Utc::now().to_rfc3339(),
95        repositories_analyzed: 1, // We analyzed 1 repo in this demo
96        commits_analyzed: 100,
97        analyzer_version: env!("CARGO_PKG_VERSION").to_string(),
98    };
99
100    let report = AnalysisReport {
101        version: "1.0".to_string(),
102        metadata,
103        defect_patterns: patterns,
104    };
105
106    // Write to file
107    let output_path = PathBuf::from("full-analysis-report.yaml");
108    report_generator
109        .write_to_file(&report, &output_path)
110        .await?;
111
112    println!("βœ… Report saved to: {}", output_path.display());
113
114    // Display YAML preview
115    let yaml_content = tokio::fs::read_to_string(&output_path).await?;
116    println!("\nπŸ“„ Report Preview (first 20 lines):");
117    println!("---");
118    for (i, line) in yaml_content.lines().enumerate() {
119        if i >= 20 {
120            println!(
121                "   ... (truncated, see {} for full report)",
122                output_path.display()
123            );
124            break;
125        }
126        println!("{}", line);
127    }
128    println!("---");
129
130    // Summary
131    println!("\n🎯 Full Analysis Complete!");
132    println!("   βœ… GitHub API integration");
133    println!("   βœ… Git repository cloning");
134    println!("   βœ… Commit history analysis");
135    println!("   βœ… Rule-based defect classification");
136    println!("   βœ… YAML report generation");
137    println!("\n   Phase 1 MVP complete!");
138    println!("   Next: User feedback mechanism for Phase 2 ML training");
139
140    Ok(())
141}
Source

pub async fn fetch_organization_repos( &self, org_name: &str, ) -> Result<Vec<RepoInfo>>

Fetch all repositories for an organization

Β§Arguments
  • org_name - GitHub organization name
Β§Errors

Returns error if:

  • Organization name is empty
  • API request fails
  • Organization doesn’t exist
Β§Examples
use organizational_intelligence_plugin::github::GitHubMiner;

let miner = GitHubMiner::new(None);
let repos = miner.fetch_organization_repos("rust-lang").await?;
println!("Found {} repositories", repos.len());
Examples found in repository?
examples/analyze_org.rs (line 33)
19async fn main() -> Result<()> {
20    // Initialize logging
21    tracing_subscriber::fmt::fmt()
22        .with_max_level(tracing::Level::INFO)
23        .init();
24
25    println!("πŸš€ Organizational Intelligence Plugin - Example");
26    println!("   Analyzing organization: tokio-rs\n");
27
28    // Initialize GitHub client (unauthenticated for this example)
29    let miner = GitHubMiner::new(None);
30
31    // Fetch organization repositories
32    println!("πŸ“₯ Fetching repositories...");
33    let repos = miner.fetch_organization_repos("tokio-rs").await?;
34
35    println!("βœ… Found {} repositories\n", repos.len());
36
37    // Display top 3 by stars
38    let mut sorted_repos = repos.clone();
39    sorted_repos.sort_by(|a, b| b.stars.cmp(&a.stars));
40
41    println!("⭐ Top repositories:");
42    for (i, repo) in sorted_repos.iter().take(3).enumerate() {
43        println!(
44            "   {}. {} ({} ⭐) - {}",
45            i + 1,
46            repo.name,
47            repo.stars,
48            repo.language.as_deref().unwrap_or("Unknown")
49        );
50    }
51
52    // Generate report
53    println!("\nπŸ“Š Generating YAML report...");
54    let report_generator = ReportGenerator::new();
55
56    let metadata = AnalysisMetadata {
57        organization: "tokio-rs".to_string(),
58        analysis_date: Utc::now().to_rfc3339(),
59        repositories_analyzed: repos.len(),
60        commits_analyzed: 0, // Phase 1: Not analyzing commits yet
61        analyzer_version: env!("CARGO_PKG_VERSION").to_string(),
62    };
63
64    let report = AnalysisReport {
65        version: "1.0".to_string(),
66        metadata,
67        defect_patterns: vec![], // Phase 1: No classifier yet
68    };
69
70    // Write to file
71    let output_path = PathBuf::from("tokio-rs-analysis.yaml");
72    report_generator
73        .write_to_file(&report, &output_path)
74        .await?;
75
76    println!("βœ… Report saved to: {}", output_path.display());
77
78    // Display a sample of the YAML
79    let yaml_content = tokio::fs::read_to_string(&output_path).await?;
80    println!("\nπŸ“„ Report preview:");
81    println!("---");
82    for (i, line) in yaml_content.lines().take(15).enumerate() {
83        println!("{}", line);
84        if i == 14 && yaml_content.lines().count() > 15 {
85            println!("   ... (truncated)");
86        }
87    }
88    println!("---");
89
90    println!("\n🎯 Example complete!");
91    println!("   Phase 1 MVP features demonstrated:");
92    println!("   βœ… GitHub API integration");
93    println!("   βœ… Repository fetching");
94    println!("   βœ… YAML report generation");
95
96    Ok(())
97}
More examples
Hide additional examples
examples/full_analysis.rs (line 34)
20async fn main() -> Result<()> {
21    // Initialize logging
22    tracing_subscriber::fmt::fmt()
23        .with_max_level(tracing::Level::INFO)
24        .init();
25
26    println!("πŸš€ Organizational Intelligence Plugin - Full Analysis Example\n");
27    println!("Demonstrates: GitHub API β†’ Git Mining β†’ Classification β†’ YAML Report\n");
28
29    // Step 1: Fetch repositories from GitHub organization
30    println!("πŸ“₯ Step 1: Fetching repositories from GitHub...");
31    let github_miner = GitHubMiner::new(None); // Unauthenticated for demo
32    let org_name = "tokio-rs";
33
34    let repos = github_miner.fetch_organization_repos(org_name).await?;
35    println!("βœ… Found {} repositories in {}\n", repos.len(), org_name);
36
37    // Display top repositories
38    let mut sorted_repos = repos.clone();
39    sorted_repos.sort_by(|a, b| b.stars.cmp(&a.stars));
40
41    println!("⭐ Top 3 repositories:");
42    for (i, repo) in sorted_repos.iter().take(3).enumerate() {
43        println!("   {}. {} ({} ⭐)", i + 1, repo.name, repo.stars);
44    }
45    println!();
46
47    // Step 2: Analyze repositories for defect patterns
48    println!("πŸ” Step 2: Analyzing commit history for defect patterns...");
49
50    // Create temporary directory for cloning
51    let temp_dir = TempDir::new()?;
52    let analyzer = OrgAnalyzer::new(temp_dir.path());
53
54    // Analyze top repository (limit to 100 commits for demo speed)
55    let top_repo = &sorted_repos[0];
56    println!("   Analyzing: {} (up to 100 commits)", top_repo.name);
57
58    let patterns = analyzer
59        .analyze_repository(
60            &format!("https://github.com/{}/{}", org_name, top_repo.name),
61            &top_repo.name,
62            100,
63        )
64        .await?;
65
66    if patterns.is_empty() {
67        println!("   ℹ️  No defect patterns detected in last 100 commits");
68    } else {
69        println!("   βœ… Found {} defect categories\n", patterns.len());
70
71        // Display patterns
72        println!("πŸ“Š Defect Patterns Found:");
73        for pattern in &patterns {
74            println!(
75                "   β€’ {} (n={}, confidence={:.0}%)",
76                pattern.category.as_str(),
77                pattern.frequency,
78                pattern.confidence * 100.0
79            );
80            if !pattern.examples.is_empty() {
81                let example = &pattern.examples[0];
82                println!("     Example: {}: {}", example.commit_hash, example.message);
83            }
84        }
85        println!();
86    }
87
88    // Step 3: Generate YAML report
89    println!("πŸ“ Step 3: Generating YAML report...");
90    let report_generator = ReportGenerator::new();
91
92    let metadata = AnalysisMetadata {
93        organization: org_name.to_string(),
94        analysis_date: Utc::now().to_rfc3339(),
95        repositories_analyzed: 1, // We analyzed 1 repo in this demo
96        commits_analyzed: 100,
97        analyzer_version: env!("CARGO_PKG_VERSION").to_string(),
98    };
99
100    let report = AnalysisReport {
101        version: "1.0".to_string(),
102        metadata,
103        defect_patterns: patterns,
104    };
105
106    // Write to file
107    let output_path = PathBuf::from("full-analysis-report.yaml");
108    report_generator
109        .write_to_file(&report, &output_path)
110        .await?;
111
112    println!("βœ… Report saved to: {}", output_path.display());
113
114    // Display YAML preview
115    let yaml_content = tokio::fs::read_to_string(&output_path).await?;
116    println!("\nπŸ“„ Report Preview (first 20 lines):");
117    println!("---");
118    for (i, line) in yaml_content.lines().enumerate() {
119        if i >= 20 {
120            println!(
121                "   ... (truncated, see {} for full report)",
122                output_path.display()
123            );
124            break;
125        }
126        println!("{}", line);
127    }
128    println!("---");
129
130    // Summary
131    println!("\n🎯 Full Analysis Complete!");
132    println!("   βœ… GitHub API integration");
133    println!("   βœ… Git repository cloning");
134    println!("   βœ… Commit history analysis");
135    println!("   βœ… Rule-based defect classification");
136    println!("   βœ… YAML report generation");
137    println!("\n   Phase 1 MVP complete!");
138    println!("   Next: User feedback mechanism for Phase 2 ML training");
139
140    Ok(())
141}
Source

pub fn filter_by_date( repos: Vec<RepoInfo>, since: DateTime<Utc>, ) -> Vec<RepoInfo>

Filter repositories by last update date

Β§Arguments
  • repos - List of repositories to filter
  • since - Only include repos updated since this date
Β§Returns

Filtered list of repositories

Auto Trait ImplementationsΒ§

Blanket ImplementationsΒ§

SourceΒ§

impl<T> Any for T
where T: 'static + ?Sized,

SourceΒ§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
SourceΒ§

impl<T> Borrow<T> for T
where T: ?Sized,

SourceΒ§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
SourceΒ§

impl<T> BorrowMut<T> for T
where T: ?Sized,

SourceΒ§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
SourceΒ§

impl<T> From<T> for T

SourceΒ§

fn from(t: T) -> T

Returns the argument unchanged.

SourceΒ§

impl<T> Instrument for T

SourceΒ§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
SourceΒ§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
SourceΒ§

impl<T, U> Into<U> for T
where U: From<T>,

SourceΒ§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

SourceΒ§

impl<T> IntoEither for T

SourceΒ§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
SourceΒ§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
SourceΒ§

impl<T> PolicyExt for T
where T: ?Sized,

SourceΒ§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
SourceΒ§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
SourceΒ§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

SourceΒ§

type Error = Infallible

The type returned in the event of a conversion error.
SourceΒ§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
SourceΒ§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

SourceΒ§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
SourceΒ§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
SourceΒ§

impl<T> WithSubscriber for T

SourceΒ§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
SourceΒ§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more