Created
July 19, 2021 18:16
-
-
Save DJMcNab/dbb89917ab9cc533727cd62488e8ac26 to your computer and use it in GitHub Desktop.
License Checker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [package] | |
| name = "licenses" | |
| version = "0.1.0" | |
| authors = ["Daniel McNab"] | |
| edition = "2018" | |
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
| [dependencies] | |
| octocrab = "0.9.1" | |
| tokio = { version="1.7.1", features=["rt", "macros", "rt-multi-thread"] } | |
| serde_json = "*" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::collections::hash_map::RandomState; | |
| use std::collections::{HashMap, HashSet}; | |
| use std::io::Write; | |
| use std::iter::FromIterator; | |
| use octocrab; | |
| fn crab() -> octocrab::Octocrab { | |
| octocrab::Octocrab::builder() | |
| .personal_token("<YOUR TOKEN HERE>".to_string()) | |
| .build() | |
| .unwrap() | |
| } | |
| #[tokio::main] | |
| async fn main() { | |
| let first = std::env::args().skip(1).next(); | |
| let owner = "bevyengine"; | |
| let repo = "bevy"; | |
| match first.as_deref() { | |
| Some("download_prs") => { | |
| let mut all_prs = Vec::new(); | |
| let mut empty_pages = 0u32; | |
| let mut page = 0u32; | |
| let octocrab = crab(); | |
| loop { | |
| let pulls = octocrab | |
| .pulls(owner, repo) | |
| .list() | |
| .state(octocrab::params::State::All) | |
| .page(page) | |
| .per_page(50) | |
| .send() | |
| .await | |
| .unwrap(); | |
| let count = (&pulls).into_iter().count(); | |
| eprintln!("{}: {}", page, count); | |
| all_prs.extend(pulls); | |
| if count == 0 { | |
| empty_pages += 1; | |
| } else { | |
| empty_pages = 0; | |
| } | |
| if empty_pages > 3 { | |
| break; | |
| } | |
| page += 1; | |
| } | |
| let file = std::fs::File::create("out/bevy_prs.json").unwrap(); | |
| serde_json::to_writer_pretty(file, &all_prs).unwrap(); | |
| } | |
| Some("download_comments") => { | |
| let mut all_comments = Vec::new(); | |
| let mut empty_pages = 0u32; | |
| let mut page = 0u32; | |
| let octocrab = crab(); | |
| loop { | |
| let comments = octocrab | |
| .issues(owner, repo) | |
| .list_comments(2373) | |
| .page(page) | |
| .per_page(50) | |
| .send() | |
| .await | |
| .unwrap(); | |
| let count = (&comments).into_iter().count(); | |
| eprintln!("{}: {}", page, count); | |
| all_comments.extend(comments); | |
| if count == 0 { | |
| empty_pages += 1; | |
| } else { | |
| empty_pages = 0; | |
| } | |
| if empty_pages > 3 { | |
| break; | |
| } | |
| page += 1; | |
| } | |
| let file = std::fs::File::create("out/relicense_comments.json").unwrap(); | |
| serde_json::to_writer_pretty(file, &all_comments).unwrap(); | |
| } | |
| Some("parse_authors") => { | |
| let thread = std::thread::Builder::new() | |
| .stack_size(100_000_000) | |
| .spawn(|| { | |
| let file = std::fs::read("out/bevy_prs.json").unwrap(); | |
| let all_prs: Vec<octocrab::models::pulls::PullRequest> = | |
| serde_json::from_slice(&file).unwrap(); | |
| let mut users = HashSet::new(); | |
| let co_authors = std::fs::read_to_string("out/co_authors.txt").unwrap(); | |
| for co_author in co_authors.lines(){ | |
| users.insert(co_author.trim().to_string()); | |
| } | |
| for pr in all_prs { | |
| let mut should = /* matches!(pr.state, octocrab::models::IssueState::Open) | |
| || */ pr.merged_at.is_some(); | |
| should |= pr.title.starts_with("[Merged by Bors]"); | |
| if should { | |
| users.insert(pr.user.login); | |
| } | |
| } | |
| let mut users = users.into_iter().collect::<Vec<_>>(); | |
| users.sort(); | |
| let mut output_file = std::fs::File::create("out/uniq_authors.txt").unwrap(); | |
| for chunk in users.chunks(45) { | |
| for user in chunk { | |
| writeln!(output_file, "{}", user).unwrap(); | |
| } | |
| } | |
| }) | |
| .unwrap(); | |
| thread.join().unwrap(); | |
| } | |
| Some("parse_commenters")=>{ | |
| let thread = std::thread::Builder::new() | |
| .stack_size(100_000_000) | |
| .spawn(|| { | |
| let file = std::fs::read("out/relicense_comments.json").unwrap(); | |
| let comments: Vec<octocrab::models::issues::Comment> = | |
| serde_json::from_slice(&file).unwrap(); | |
| let mut users = HashSet::new(); | |
| let known_allright = HashSet::<_, RandomState>::from_iter(["marcusbuffett", | |
| "Incipium", | |
| "mrk-its", | |
| "CAD97", | |
| "anchpop", | |
| "lee-orr", | |
| "cart", // Lol | |
| "termhn", | |
| "GabLotus", | |
| "CGMossa" | |
| ]); | |
| let mut sus = HashMap::new(); | |
| for cmt in comments { | |
| let text = "I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to choose either at their option"; | |
| let text_with_dot_newline = "\nI license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to choose either at their option."; | |
| let body = cmt.body.unwrap(); | |
| let body = body.trim(); | |
| if body.starts_with(text)|| body.ends_with(text_with_dot_newline) || known_allright.contains(&*cmt.user.login) { | |
| users.insert(cmt.user.login); | |
| }else{ | |
| sus.insert(cmt.user.login, cmt.html_url); | |
| } | |
| } | |
| let mut users_vec = users.iter().collect::<Vec<_>>(); | |
| users_vec.sort(); | |
| let mut output_file = std::fs::File::create("out/agreed.txt").unwrap(); | |
| for chunk in users_vec.chunks(45) { | |
| for user in chunk { | |
| writeln!(output_file, "{}", user).unwrap(); | |
| } | |
| } | |
| for (user, url) in sus { | |
| if !users.contains(&user){ | |
| eprintln!("{}: {}", user, url); | |
| } | |
| } | |
| }) | |
| .unwrap(); | |
| thread.join().unwrap(); | |
| } | |
| Some("diff")=>{ | |
| let mut authors = HashSet::new(); | |
| for co_author in std::fs::read_to_string("out/uniq_authors.txt").unwrap().lines(){ | |
| authors.insert(co_author.trim().to_string()); | |
| } | |
| let mut agreer = HashSet::new(); | |
| for agreed in std::fs::read_to_string("out/agreed.txt").unwrap().lines(){ | |
| agreer.insert(agreed.trim().to_string()); | |
| } | |
| let mut output_file = std::fs::File::create("out/diff.txt").unwrap(); | |
| let mut out = authors.difference(&agreer).collect::<Vec<_>>(); | |
| out.sort(); | |
| for diff in out { | |
| writeln!(output_file, "{}", diff).unwrap(); | |
| } | |
| } | |
| x => println!( | |
| "Unknown argument {:?}. Valid choices are: download_prs, download_comments, parse_authors, parse_commenters", | |
| x.unwrap_or("") | |
| ), | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment