Skip to content

Commit 0062a43

Browse files
committed
wip
1 parent 227cc7a commit 0062a43

File tree

2 files changed

+125
-33
lines changed

2 files changed

+125
-33
lines changed

.github/actions/clippy-annotation-reporter/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55
version = "0.1.0"
66

77
[dependencies]
8-
clap = { version = "4.3", features = ["derive"] }
8+
clap = { version = "4.3", features = ["derive", "env"] }
99
octocrab = "0.28"
1010
anyhow = "1.0"
1111
regex = "1.9"
Lines changed: 124 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,150 @@
1-
use anyhow::{Context, Result};
1+
use anyhow::{Context as _, Result};
22
use octocrab::Octocrab;
3+
use serde_json::Value;
34
use std::env;
5+
use std::fs;
6+
use clap::Parser;
7+
8+
#[derive(Parser, Debug)]
9+
#[command(name = "clippy-annotation-reporter")]
10+
#[command(about = "Reports changes in clippy annotations for panic rules")]
11+
struct Args {
12+
/// GitHub token for API access
13+
#[arg(long, env = "GITHUB_TOKEN")]
14+
token: String,
15+
16+
/// Comma-separated list of panic-related Clippy rules to track
17+
#[arg(long, default_value = "unwrap_used,expect_used,todo,unimplemented,panic,unreachable")]
18+
rules: String,
19+
20+
/// GitHub repository (owner/repo) - defaults to current repository
21+
#[arg(long)]
22+
repo: Option<String>,
23+
24+
/// Pull request number - defaults to PR from event context
25+
#[arg(long)]
26+
pr: Option<u64>,
27+
}
28+
29+
/// GitHub event context extracted from environment
30+
struct GitHubContext {
31+
repository: String,
32+
pr_number: u64,
33+
event_name: String,
34+
}
35+
36+
impl GitHubContext {
37+
/// Try to extract GitHub context from environment variables and event file
38+
fn from_env() -> Result<Self> {
39+
// Get repository from env or args
40+
let repository = env::var("GITHUB_REPOSITORY")
41+
.context("GITHUB_REPOSITORY environment variable not set")?;
42+
43+
// Get event name (pull_request, push, etc.)
44+
let event_name = env::var("GITHUB_EVENT_NAME")
45+
.context("GITHUB_EVENT_NAME environment variable not set")?;
46+
47+
// For PR events, get PR number from event payload
48+
let event_path = env::var("GITHUB_EVENT_PATH")
49+
.context("GITHUB_EVENT_PATH environment variable not set")?;
50+
51+
println!("Event name: {}", event_name);
52+
println!("Event path: {}", event_path);
53+
54+
let event_data = fs::read_to_string(event_path)
55+
.context("Failed to read GitHub event file")?;
56+
57+
let event_json: Value = serde_json::from_str(&event_data)
58+
.context("Failed to parse GitHub event JSON")?;
59+
60+
// Print the event JSON for debugging
61+
println!("Event JSON structure (top level): {:?}",
62+
event_json.as_object().map(|o| o.keys().collect::<Vec<_>>()));
63+
64+
// Extract PR number using different strategies based on event type
65+
let pr_number = match event_name.as_str() {
66+
"pull_request" | "pull_request_target" => {
67+
event_json["pull_request"]["number"].as_u64()
68+
.context("Could not find pull_request.number in event data")?
69+
},
70+
"issue_comment" => {
71+
event_json["issue"]["number"].as_u64()
72+
.context("Could not find issue.number in event data")?
73+
},
74+
_ => {
75+
// For other events, PR number must be provided as an argument
76+
0 // Will be overridden by required argument check below
77+
}
78+
};
79+
80+
Ok(GitHubContext {
81+
repository,
82+
pr_number,
83+
event_name,
84+
})
85+
}
86+
}
487

588
#[tokio::main]
689
async fn main() -> Result<()> {
7-
println!("Hello World from clippy-annotation-checker!");
8-
println!("Action is running successfully!");
90+
// Initialize logger
91+
env_logger::init();
992

10-
// Get required environment variables
11-
let github_token = env::var("GITHUB_TOKEN")
12-
.context("GITHUB_TOKEN environment variable not set")?;
93+
// Parse command line arguments
94+
let args = Args::parse();
1395

14-
let github_repository = env::var("GITHUB_REPOSITORY")
15-
.context("GITHUB_REPOSITORY environment variable not set")?;
96+
println!("Clippy Annotation Reporter starting...");
1697

17-
let event_path = env::var("GITHUB_EVENT_PATH")
18-
.context("GITHUB_EVENT_PATH environment variable not set")?;
98+
// Try to get GitHub context from environment
99+
let github_ctx = GitHubContext::from_env()?;
19100

20-
// Parse event data to get PR number
21-
let event_data = std::fs::read_to_string(event_path)
22-
.context("Failed to read event file")?;
101+
// Use provided values from args if available, otherwise use context
102+
let repository = args.repo.unwrap_or(github_ctx.repository);
103+
let pr_number = match args.pr {
104+
Some(pr) => pr,
105+
None => {
106+
if github_ctx.pr_number == 0 {
107+
anyhow::bail!("No PR number found in event context. Please provide --pr argument.");
108+
}
109+
github_ctx.pr_number
110+
}
111+
};
23112

24-
let event_json: serde_json::Value = serde_json::from_str(&event_data)
25-
.context("Failed to parse event JSON")?;
113+
println!("Repository: {}", repository);
114+
println!("PR Number: {}", pr_number);
115+
println!("Event Type: {}", github_ctx.event_name);
116+
println!("Checking for rules: {}", args.rules);
26117

27-
let pr_number = event_json["pull_request"]["number"]
28-
.as_u64()
29-
.context("Could not find PR number in event data")?;
118+
// Initialize GitHub API client with token
119+
let octocrab = Octocrab::builder()
120+
.personal_token(args.token)
121+
.build()
122+
.context("Failed to build GitHub API client")?;
30123

31124
// Split repository into owner and name
32-
let repo_parts: Vec<&str> = github_repository.split('/').collect();
125+
let repo_parts: Vec<&str> = repository.split('/').collect();
33126
if repo_parts.len() != 2 {
34-
anyhow::bail!("Invalid repository format: {}", github_repository);
127+
anyhow::bail!("Invalid repository format. Expected 'owner/repo', got '{}'", repository);
35128
}
36-
37129
let owner = repo_parts[0];
38130
let repo = repo_parts[1];
39131

40-
println!("Posting Hello World comment to PR #{} in {}/{}", pr_number, owner, repo);
132+
// This is just a "Hello World" example that posts a comment to verify everything works
133+
println!("Posting a test comment to PR #{} in {}/{}", pr_number, owner, repo);
41134

42-
// Initialize GitHub client
43-
let octocrab = Octocrab::builder()
44-
.personal_token(github_token)
45-
.build()
46-
.context("Failed to build GitHub client")?;
47-
48-
// Post a simple comment
49135
octocrab
50136
.issues(owner, repo)
51-
.create_comment(pr_number, "## Hello World from clippy-annotation-checker!\n\nThis action is running successfully and can post comments to PRs.")
137+
.create_comment(
138+
pr_number,
139+
format!("## Clippy Annotation Reporter Test\n\nSuccessfully connected to PR #{} in {}/{}.\n\nWill scan for the following rules: `{}`",
140+
pr_number, owner, repo, args.rules)
141+
)
52142
.await
53-
.context("Failed to post comment")?;
143+
.context("Failed to post comment to PR")?;
54144

55145
println!("Comment posted successfully!");
56146

147+
// TODO: Add actual clippy annotation checking logic here
148+
57149
Ok(())
58-
}
150+
}

0 commit comments

Comments
 (0)