Skip to content

Commit 1b28334

Browse files
committed
Move render and pr-check into a Cargo workspace
Adds data/Cargo.toml as a workspace root so both crates share a single target directory and a common set of dependency versions via [workspace.dependencies]. pr-check now depends on the render crate directly and uses render::types::ParsedEntry instead of its own ToolEntry struct, removing the duplication. The Makefile and pr-check workflow are updated to target the workspace manifest. The gitignore entry is updated from data/pr-check/target/ to data/target/.
1 parent 0a711f4 commit 1b28334

7 files changed

Lines changed: 61 additions & 59 deletions

File tree

.github/workflows/pr-check.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
pull_request:
55
branches: [master]
66
paths:
7-
- 'data/tools/**.yml'
7+
- "data/tools/**.yml"
88

99
jobs:
1010
pr-check:
@@ -32,18 +32,18 @@ jobs:
3232
path: |
3333
~/.cargo/registry
3434
~/.cargo/git
35-
data/pr-check/target
36-
key: pr-check-${{ runner.os }}-${{ hashFiles('data/pr-check/Cargo.lock') }}
35+
data/target
36+
key: pr-check-${{ runner.os }}-${{ hashFiles('data/Cargo.lock') }}
3737
restore-keys: |
3838
pr-check-${{ runner.os }}-
3939
4040
- name: Build pr-check
41-
run: cargo build --release --manifest-path data/pr-check/Cargo.toml
41+
run: cargo build --release --manifest-path data/Cargo.toml -p pr-check
4242

4343
- name: Run pr-check
4444
env:
4545
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4646
GITHUB_REPOSITORY: ${{ github.repository }}
4747
PR_NUMBER: ${{ github.event.pull_request.number }}
4848
run: |
49-
data/pr-check/target/release/pr-check ${{ steps.changed.outputs.files }}
49+
data/target/release/pr-check ${{ steps.changed.outputs.files }}

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
logcli-linux-amd64
22
logcli.zip
3-
data/pr-check/target/
3+
data/target/

Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ help:
1616

1717
# Main rendering targets
1818
render:
19-
cargo run --manifest-path data/render/Cargo.toml -- --tags data/tags.yml --tools data/tools --md-out README.md --json-out data/api
19+
cargo run --manifest-path data/Cargo.toml -p render -- --tags data/tags.yml --tools data/tools --md-out README.md --json-out data/api
2020

2121
render-skip-deprecated:
22-
cargo run --manifest-path data/render/Cargo.toml -- --tags data/tags.yml --tools data/tools --md-out README.md --json-out data/api --skip-deprecated
22+
cargo run --manifest-path data/Cargo.toml -p render -- --tags data/tags.yml --tools data/tools --md-out README.md --json-out data/api --skip-deprecated
2323

2424
# Development targets
2525
check:
26-
cargo check --manifest-path data/render/Cargo.toml
26+
cargo check --manifest-path data/Cargo.toml
2727

2828
clippy:
29-
cargo clippy --manifest-path data/render/Cargo.toml -- -D warnings
29+
cargo clippy --manifest-path data/Cargo.toml -- -D warnings
3030

3131
fmt:
32-
cargo fmt --manifest-path data/render/Cargo.toml
32+
cargo fmt --manifest-path data/Cargo.toml
3333

3434
test:
35-
cargo test --manifest-path data/render/Cargo.toml
35+
cargo test --manifest-path data/Cargo.toml
3636

3737
clean:
38-
cargo clean --manifest-path data/render/Cargo.toml
38+
cargo clean --manifest-path data/Cargo.toml

data/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[workspace]
2+
members = [
3+
"render",
4+
"pr-check",
5+
]
6+
resolver = "2"
7+
8+
[workspace.dependencies]
9+
anyhow = "1.0"
10+
chrono = { version = "0.4", features = ["serde"] }
11+
pico-args = "0.5"
12+
serde = { version = "1.0", features = ["derive"] }
13+
serde_derive = "1.0"
14+
serde_json = "1.0"
15+
serde_yaml = "0.9"
16+
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

data/pr-check/Cargo.toml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55
description = "Checks pull requests against contributing criteria"
66
license = "MIT"
77
repository = "https://github.com/analysis-tools-dev/static-analysis"
8+
publish = false
89

910
[lints.clippy]
1011
correctness = { level = "deny", priority = -1 }
@@ -32,11 +33,12 @@ similar_names = "allow"
3233
too_many_lines = "allow"
3334

3435
[dependencies]
35-
anyhow = "1.0"
36-
chrono = { version = "0.4", features = ["serde"] }
37-
pico-args = "0.5"
38-
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
39-
serde = { version = "1.0", features = ["derive"] }
40-
serde_yaml = "0.9"
41-
serde_json = "1.0"
42-
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
36+
render = { path = "../render" }
37+
anyhow = { workspace = true }
38+
chrono = { workspace = true }
39+
pico-args = { workspace = true }
40+
serde = { workspace = true }
41+
serde_json = { workspace = true }
42+
serde_yaml = { workspace = true }
43+
tokio = { workspace = true }
44+
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }

data/pr-check/src/main.rs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,12 @@
2020
2121
use anyhow::{Context, Result, bail};
2222
use chrono::{DateTime, Duration, Utc};
23+
use render::types::ParsedEntry;
2324
use serde::Deserialize;
2425
use std::collections::HashMap;
2526
use std::env;
2627
use std::path::{Path, PathBuf};
2728

28-
/// A parsed tool entry from `data/tools/<name>.yml`.
29-
#[derive(Debug, Deserialize)]
30-
struct ToolEntry {
31-
name: String,
32-
source: Option<String>,
33-
}
34-
3529
/// Response from `GET /repos/{owner}/{repo}`.
3630
#[derive(Debug, Deserialize)]
3731
struct RepoInfo {
@@ -187,8 +181,7 @@ impl GithubClient {
187181
///
188182
/// Returns an error if the API call fails.
189183
async fn list_pr_comments(&self, repo: &str, pr: u64) -> Result<Vec<IssueComment>> {
190-
let url =
191-
format!("https://api.github.com/repos/{repo}/issues/{pr}/comments?per_page=100");
184+
let url = format!("https://api.github.com/repos/{repo}/issues/{pr}/comments?per_page=100");
192185
self.get::<Vec<IssueComment>>(&url).await
193186
}
194187

@@ -276,7 +269,7 @@ fn parse_github_repo(url: &str) -> Option<(String, String)> {
276269
/// # Errors
277270
///
278271
/// Returns an error if the file cannot be read or parsed.
279-
fn read_tool(path: &Path) -> Result<ToolEntry> {
272+
fn read_tool(path: &Path) -> Result<ParsedEntry> {
280273
let f = std::fs::File::open(path).with_context(|| format!("Cannot open {}", path.display()))?;
281274
serde_yaml::from_reader(f).with_context(|| format!("Cannot parse {}", path.display()))
282275
}
@@ -287,7 +280,7 @@ fn read_tool(path: &Path) -> Result<ToolEntry> {
287280
///
288281
/// Returns an error only for unexpected failures (network, auth). Missing
289282
/// criteria produce `CheckResult::Fail` values, not errors.
290-
async fn check_tool(client: &GithubClient, tool: &ToolEntry) -> Result<ToolReport> {
283+
async fn check_tool(client: &GithubClient, tool: &ParsedEntry) -> Result<ToolReport> {
291284
let source = tool.source.clone();
292285

293286
let gh_coords = source.as_deref().and_then(parse_github_repo);
@@ -302,9 +295,7 @@ async fn check_tool(client: &GithubClient, tool: &ToolEntry) -> Result<ToolRepor
302295
if s >= MIN_STARS {
303296
CheckResult::Pass(format!("{s} stars"))
304297
} else {
305-
CheckResult::Fail(format!(
306-
"{s} stars (minimum is {MIN_STARS})"
307-
))
298+
CheckResult::Fail(format!("{s} stars (minimum is {MIN_STARS})"))
308299
}
309300
}
310301
Err(e) => CheckResult::Fail(format!("Could not fetch repo info: {e}")),
@@ -341,7 +332,7 @@ async fn check_tool(client: &GithubClient, tool: &ToolEntry) -> Result<ToolRepor
341332
};
342333

343334
Ok(ToolReport {
344-
name: tool.name.clone(),
335+
name: tool.name.to_string(),
345336
source,
346337
stars: stars_check,
347338
contributors: contributors_check,
@@ -357,7 +348,7 @@ async fn check_tool(client: &GithubClient, tool: &ToolEntry) -> Result<ToolRepor
357348
};
358349

359350
Ok(ToolReport {
360-
name: tool.name.clone(),
351+
name: tool.name.to_string(),
361352
source,
362353
stars: CheckResult::Skip("N/A (non-GitHub source)".into()),
363354
contributors: CheckResult::Skip("N/A (non-GitHub source)".into()),
@@ -432,12 +423,7 @@ fn render_comment(reports: &[ToolReport]) -> String {
432423
/// # Errors
433424
///
434425
/// Returns an error if the GitHub API calls fail.
435-
async fn upsert_comment(
436-
client: &GithubClient,
437-
repo: &str,
438-
pr: u64,
439-
body: &str,
440-
) -> Result<()> {
426+
async fn upsert_comment(client: &GithubClient, repo: &str, pr: u64, body: &str) -> Result<()> {
441427
let comments = client.list_pr_comments(repo, pr).await?;
442428

443429
let existing = comments.iter().find(|c| c.body.contains(COMMENT_MARKER));
@@ -462,8 +448,7 @@ fn parse_pr_number(s: &str) -> Result<u64> {
462448
#[tokio::main]
463449
async fn main() -> Result<()> {
464450
let token = env::var("GITHUB_TOKEN").context("GITHUB_TOKEN not set")?;
465-
let gh_repo =
466-
env::var("GITHUB_REPOSITORY").context("GITHUB_REPOSITORY not set")?;
451+
let gh_repo = env::var("GITHUB_REPOSITORY").context("GITHUB_REPOSITORY not set")?;
467452
let pr_number_str = env::var("PR_NUMBER").context("PR_NUMBER not set")?;
468453
let pr_number = parse_pr_number(&pr_number_str)?;
469454

@@ -475,18 +460,16 @@ async fn main() -> Result<()> {
475460
let tool_paths: Vec<PathBuf> = tool_paths
476461
.into_iter()
477462
.filter(|p| {
478-
p.starts_with("data/tools")
479-
&& p.extension().and_then(|e| e.to_str()) == Some("yml")
463+
p.starts_with("data/tools") && p.extension().and_then(|e| e.to_str()) == Some("yml")
480464
})
481465
.collect();
482466

483467
let client = GithubClient::new(token)?;
484468

485469
let mut reports = Vec::new();
486470
for path in &tool_paths {
487-
let tool = read_tool(path)
488-
.with_context(|| format!("Failed to read {}", path.display()))?;
489-
eprintln!("Checking '{}'...", tool.name);
471+
let tool = read_tool(path).with_context(|| format!("Failed to read {}", path.display()))?;
472+
eprintln!("Checking '{}'...", &tool.name);
490473
let report = check_tool(&client, &tool).await?;
491474
reports.push(report);
492475
}
@@ -549,4 +532,4 @@ mod tests {
549532
let comment = render_comment(&[]);
550533
assert!(comment.contains(COMMENT_MARKER));
551534
}
552-
}
535+
}

data/render/Cargo.toml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ license = "MIT"
88
repository = "https://github.com/analysis-tools-dev/static-analysis"
99
keywords = ["static-analysis", "linting", "tools", "catalog"]
1010
categories = ["development-tools"]
11+
publish = false
1112

1213
[lints.clippy]
1314
# Correctness lints (enabled by default, but being explicit)
@@ -44,16 +45,16 @@ similar_names = "allow"
4445
too_many_lines = "allow" # We'll use the clippy.toml threshold instead
4546

4647
[dependencies]
47-
serde = "1.0.228"
48-
serde_derive = "1.0.136"
49-
serde_yaml = "0.9.34"
48+
anyhow = { workspace = true }
49+
chrono = { workspace = true }
50+
pico-args = { workspace = true }
51+
serde = { workspace = true }
52+
serde_derive = { workspace = true }
53+
serde_json = { workspace = true }
54+
serde_yaml = { workspace = true }
55+
tokio = { workspace = true }
5056
askama = "0.12.1"
5157
# Switch back to crates as soon as a new release with tokio 1.x support is
5258
# released. See https://github.com/softprops/hubcaps/pull/285
5359
hubcaps = { git="https://github.com/softprops/hubcaps" }
54-
tokio = { version = "1.43.4", features = ["rt-multi-thread", "macros"] }
55-
chrono = "0.4.44"
56-
anyhow = "1.0.102"
57-
pico-args = "0.5.0"
58-
serde_json = "1.0.149"
5960
slug = "0.1.6"

0 commit comments

Comments
 (0)