-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.rs
130 lines (108 loc) · 3.75 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#[macro_use]
extern crate napi_derive;
use crate::api::{compare_commits, list_members};
use crate::error::{env_var_error, format_cli_error};
use crate::utils::{create_entries, create_output, get_current_date, group_by_author};
use clap::{CommandFactory, FromArgMatches, Parser};
use clap_verbosity_flag::Verbosity;
use dotenv::dotenv;
use log::{debug, info};
use napi::bindgen_prelude::{Error as NapiError, Result};
use std::env;
use std::fs;
pub mod api;
pub mod error;
pub mod utils;
#[allow(dead_code)]
#[napi]
async fn run(args: Vec<String>) -> Result<()> {
// Support .env files
dotenv().ok();
// Arguments are coming from bin.js
let matches = Cli::command().get_matches_from(args);
let cli = Cli::from_arg_matches(&matches).map_err(format_cli_error::<Cli>)?;
env_logger::Builder::new()
.filter_level(cli.verbose.log_level_filter())
.init();
// By default, don't include org members
let should_include_org_members = cli.include_org_members.unwrap_or(false);
// By default, exclude renovate bot
let parsed_excludes = match cli.excludes {
Some(e) => e,
None => vec!["renovate[bot]".to_string(), "renovate-bot".to_string()],
};
debug!("Parsed Excludes: {:#?}", parsed_excludes);
let gh_token = env::var("GITHUB_ACCESS_TOKEN").map_err(env_var_error)?;
let commits = compare_commits(&cli.owner, &cli.repo, cli.base, cli.head, &gh_token).await?;
let org_members = list_members(&cli.owner, &gh_token).await?;
debug!("Commits: {:#?}", commits);
debug!("Org members: {:#?}", org_members);
if commits.is_empty() {
return Err(NapiError::from_reason(
"Couldn't find any relevant commits. Are you sure you used the correct head & base?"
.to_owned(),
));
}
info!("Fetched {} commits", commits.len());
let entries = create_entries(
commits,
should_include_org_members,
parsed_excludes,
org_members,
);
info!("Process {} filtered commits", entries.len());
let groups = group_by_author(entries);
let output = create_output(groups, &cli.owner, &cli.repo);
let current_dir = env::current_dir()?;
let directory_path = current_dir.join("output");
let filepath = directory_path.join(format!("{}.md", get_current_date()));
fs::create_dir_all(directory_path).unwrap();
fs::write(&filepath, output).unwrap();
println!("Successfully created {}", &filepath.display());
Ok(())
}
#[derive(Parser)]
#[clap(
author = "LekoArts",
name = "@lekoarts/thanks-contributors",
about = "Generate a list of contributors for a commit range",
long_about = "This little script accesses GitHub's API to get all contributors and their PRs between two distinct points in the history of commits. This is helpful for changelogs where you'd want to list all contributions for that release (so e.g. changes between v1 and v1.1)."
)]
#[clap(no_binary_name = true)]
struct Cli {
/// Pointer from where to start looking for changes
#[clap(required = true)]
base: String,
/// Pointer until where to stop looking for changes
#[clap(required = true)]
head: String,
/// Name of the owner/user/organization of the repository
#[clap(default_value = "gatsbyjs")]
owner: String,
/// Name of the repository
#[clap(default_value = "gatsby")]
repo: String,
/// Include organization members into the list [default: false]
#[clap(short, long)]
include_org_members: Option<bool>,
/// List of members to exclude from the list. Usage: -e=member1,member2 [default: "renovate-bot", "renovate[bot]"]
#[clap(
short,
long,
num_args = 1..,
use_value_delimiter = true,
value_delimiter = ',',
)]
excludes: Option<Vec<String>>,
#[clap(flatten)]
verbose: Verbosity,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn verify_cli() {
use clap::CommandFactory;
Cli::command().debug_assert()
}
}