Skip to content

Commit dea794c

Browse files
committed
Add command for generating CODEOWNERS
# The commit message #2 will be skipped: # fixup! Add command for generating CODEOWNERS
1 parent c467c7d commit dea794c

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

.github/CODEOWNERS

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# This is an automatically generated file
2+
# Run `cargo run ci generate-codeowners` to regenerate it.
3+
4+
/.github/ @Mark-Simulacrum @pietroalbini @jdno @marcoieni
5+
/src/ @Mark-Simulacrum @pietroalbini @jdno @marcoieni
6+
/rust_team_data/ @Mark-Simulacrum @pietroalbini @jdno @marcoieni
7+
/repos/rust-lang/team.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
8+
/repos/rust-lang/sync-team.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
9+
/teams/infra-admins.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
10+
/teams/team-repo-admins.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
11+
.cargo @Mark-Simulacrum @pietroalbini @jdno @marcoieni
12+
target @Mark-Simulacrum @pietroalbini @jdno @marcoieni
13+
Cargo.lock @Mark-Simulacrum @pietroalbini @jdno @marcoieni
14+
Cargo.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
15+
config.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
16+
/people/Mark-Simulacrum.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
17+
/people/pietroalbini.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
18+
/people/jdno.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni
19+
/people/marcoieni.toml @Mark-Simulacrum @pietroalbini @jdno @marcoieni

src/ci.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::schema::Team;
2+
use anyhow::Context;
3+
use std::path::{Path, PathBuf};
4+
5+
/// Generates the contents of `.github/CODEOWNERS`, based on
6+
/// the infra admins in `infra-admins.toml`.
7+
pub fn generate_codeowners_file() -> anyhow::Result<()> {
8+
let admins = load_infra_admins()?;
9+
let codeowners_content = generate_codeowners_content(admins);
10+
std::fs::write(codeowners_path(), codeowners_content).context("cannot write CODEOWNERS")?;
11+
Ok(())
12+
}
13+
14+
fn generate_codeowners_content(admins: Vec<String>) -> String {
15+
use std::fmt::Write;
16+
17+
let mut output = String::new();
18+
writeln!(
19+
output,
20+
r#"# This is an automatically generated file
21+
# Run `cargo run ci generate-codeowners` to regenerate it.
22+
"#
23+
)
24+
.unwrap();
25+
26+
let admin_list = admins
27+
.iter()
28+
.map(|admin| format!("@{admin}"))
29+
.collect::<Vec<_>>()
30+
.join(" ");
31+
32+
// Set of paths that should only be modifiable by infra-admins
33+
let mut secure_paths = vec![
34+
"/.github/".to_string(),
35+
"/src/".to_string(),
36+
"/rust_team_data/".to_string(),
37+
"/repos/rust-lang/team.toml".to_string(),
38+
"/repos/rust-lang/sync-team.toml".to_string(),
39+
"/teams/infra-admins.toml".to_string(),
40+
"/teams/team-repo-admins.toml".to_string(),
41+
".cargo".to_string(),
42+
"target".to_string(),
43+
"Cargo.lock".to_string(),
44+
"Cargo.toml".to_string(),
45+
"config.toml".to_string(),
46+
];
47+
for admin in admins {
48+
secure_paths.push(format!("/people/{admin}.toml"));
49+
}
50+
51+
for path in secure_paths {
52+
writeln!(output, "{path} {admin_list}").unwrap();
53+
}
54+
output
55+
}
56+
57+
fn codeowners_path() -> PathBuf {
58+
Path::new(&env!("CARGO_MANIFEST_DIR"))
59+
.join(".github")
60+
.join("CODEOWNERS")
61+
}
62+
63+
fn load_infra_admins() -> anyhow::Result<Vec<String>> {
64+
let admins = std::fs::read_to_string(
65+
Path::new(&env!("CARGO_MANIFEST_DIR"))
66+
.join("teams")
67+
.join("infra-admins.toml"),
68+
)
69+
.context("cannot load infra-admins.toml")?;
70+
let team: Team = toml::from_str(&admins).context("cannot deserialize infra-admins")?;
71+
Ok(team
72+
.raw_people()
73+
.members
74+
.iter()
75+
.map(|member| member.github.clone())
76+
.collect())
77+
}

src/main.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
mod data;
44
#[macro_use]
55
mod permissions;
6+
mod ci;
67
mod github;
78
mod schema;
89
mod static_api;
@@ -15,6 +16,7 @@ use data::Data;
1516
use schema::{Email, Team, TeamKind};
1617
use zulip::ZulipApi;
1718

19+
use crate::ci::generate_codeowners_file;
1820
use crate::schema::RepoPermission;
1921
use anyhow::{bail, format_err, Error};
2022
use log::{error, info, warn};
@@ -111,6 +113,14 @@ enum Cli {
111113
EncryptEmail,
112114
#[structopt(name = "decrypt-email", help = "decrypt an email address")]
113115
DecryptEmail,
116+
#[structopt(name = "ci", help = "CI scripts")]
117+
Ci(CiOpts),
118+
}
119+
120+
#[derive(structopt::StructOpt)]
121+
enum CiOpts {
122+
#[structopt(help = "Generate the .github/CODEOWNERS file")]
123+
GenerateCodeowners,
114124
}
115125

116126
fn main() {
@@ -422,6 +432,9 @@ fn run() -> Result<(), Error> {
422432
rust_team_data::email_encryption::try_decrypt(&key, &encrypted)?
423433
);
424434
}
435+
Cli::Ci(opts) => match opts {
436+
CiOpts::GenerateCodeowners => generate_codeowners_file()?,
437+
},
425438
}
426439

427440
Ok(())

0 commit comments

Comments
 (0)