Skip to content

Commit

Permalink
Improve TOML schema of custom roles
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 5, 2024
1 parent 61f79cb commit 27dcbbc
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 33 deletions.
13 changes: 7 additions & 6 deletions docs/toml-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ members = [
"craterbot",
"rust-timer",
# Any subset of members may hold custom roles, beyond "Team leader" which is
# controlled by the `leads` array above. See [[website.roles]]. Members with
# roles are written using an inline table as follows. A simple string member
# like "bors" is equivalent to {name = "bors", roles = []}.
{ name = "Crab01", roles = ["cohost"] },
{ name = "Crab02", roles = ["cohost"] },
# controlled by the `leads` array above. Members with roles are written
# using an inline table as follows. A simple string member like "bors" is
# equivalent to {github = "bors", roles = []}. The strings in `roles` must
# be present as the `id` of some role in [[roles]] section below.
{ github = "Crab01", roles = ["cohost"] },
{ github = "Crab02", roles = ["cohost"] },
]
# Past members of the team. They will not be considered as part of the team,
# but they will be recognized on the website.
Expand Down Expand Up @@ -141,7 +142,7 @@ weight = -100

# Customized roles held by a subset of the team's members, beyond "Team leader"
# which is rendered automatically for members of the `leads` array.
[[website.roles]]
[[roles]]
# Kebab-case id for the role. This serves as a key for translations.
id = "cohost"
# Text to appear on the website beneath the team member's name and GitHub handle.
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ fn run() -> Result<(), Error> {
name,
website.description()
);
for role in website.roles() {
roles.insert(&role.id, &role.description);
}
}
for role in team.roles() {
roles.insert(&role.id, &role.description);
}
}
for (role_id, description) in roles {
Expand Down
17 changes: 8 additions & 9 deletions src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ pub(crate) struct Team {
rfcbot: Option<RfcbotData>,
website: Option<WebsiteData>,
#[serde(default)]
roles: Vec<MemberRole>,
#[serde(default)]
lists: Vec<TeamList>,
#[serde(default)]
zulip_groups: Vec<RawZulipGroup>,
Expand Down Expand Up @@ -228,6 +230,10 @@ impl Team {
self.website.as_ref()
}

pub(crate) fn roles(&self) -> &[MemberRole] {
&self.roles
}

pub(crate) fn discord_roles(&self) -> Option<&Vec<DiscordRole>> {
self.discord_roles.as_ref()
}
Expand Down Expand Up @@ -529,9 +535,8 @@ pub(crate) struct TeamPeople {
}

#[derive(serde::Deserialize, Clone, Debug)]
#[serde(remote = "Self")]
#[serde(remote = "Self", deny_unknown_fields)]
pub(crate) struct TeamMember {
#[serde(rename = "name")]
pub github: String,
pub roles: Vec<String>,
}
Expand Down Expand Up @@ -586,8 +591,6 @@ pub(crate) struct WebsiteData {
name: String,
description: String,
page: Option<String>,
#[serde(default)]
roles: Vec<WebsiteRole>,
email: Option<String>,
repo: Option<String>,
discord_invite: Option<String>,
Expand All @@ -614,10 +617,6 @@ impl WebsiteData {
self.page.as_deref()
}

pub(crate) fn roles(&self) -> &[WebsiteRole] {
&self.roles
}

pub(crate) fn email(&self) -> Option<&str> {
self.email.as_deref()
}
Expand All @@ -644,7 +643,7 @@ impl WebsiteData {

#[derive(serde_derive::Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub(crate) struct WebsiteRole {
pub(crate) struct MemberRole {
pub id: String,
pub description: String,
}
Expand Down
22 changes: 9 additions & 13 deletions src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static CHECKS: &[Check<fn(&Data, &mut Vec<String>)>] = checks![
validate_zulip_group_ids,
validate_zulip_group_extra_people,
validate_repos,
validate_website_roles,
validate_member_roles,
];

#[allow(clippy::type_complexity)]
Expand Down Expand Up @@ -776,24 +776,20 @@ fn validate_repos(data: &Data, errors: &mut Vec<String>) {
});
}

/// Enforce that website roles are only assigned to a valid team member, and
/// that the same role id always has a consistent description across teams
/// (because the role id becomes the Fluent id used for translation).
fn validate_website_roles(data: &Data, errors: &mut Vec<String>) {
/// Enforce that roles are only assigned to a valid team member, and that the
/// same role id always has a consistent description across teams (because the
/// role id becomes the Fluent id used for translation).
fn validate_member_roles(data: &Data, errors: &mut Vec<String>) {
let mut role_descriptions = HashMap::new();

wrapper(
data.teams().chain(data.archived_teams()),
errors,
|team, errors| {
let Some(website_data) = team.website_data() else {
return Ok(());
};

let team_name = team.name();
let mut role_ids = HashSet::new();

for role in website_data.roles() {
for role in team.roles() {
let role_id = &role.id;
if !ascii_kebab_case(role_id) {
errors.push(format!(
Expand All @@ -808,9 +804,9 @@ fn validate_website_roles(data: &Data, errors: &mut Vec<String>) {
Entry::Occupied(entry) => {
if **entry.get() != role.description {
errors.push(format!(
"website role '{role_id}' has inconsistent description \
between different teams; if this is intentional, you \
must give those roles different ids",
"role '{role_id}' has inconsistent description bewteen \
different teams; if this is intentional, you must give \
those roles different ids",
));
}
}
Expand Down
4 changes: 2 additions & 2 deletions teams/spec.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ leads = ["pnkfelix", "m-ou-se"]
members = [
"pnkfelix",
"m-ou-se",
{ name = "JoelMarcey", roles = ["spec-editor"] },
{ github = "JoelMarcey", roles = ["spec-editor"] },
"ehuss",
]
alumni = []
Expand All @@ -17,7 +17,7 @@ description = "Creating and maintaining the specification for the Rust language"
zulip-stream = "t-spec"
repo = "https://github.com/rust-lang/spec"

[[website.roles]]
[[roles]]
id = "spec-editor"
description = "Editor"

Expand Down

0 comments on commit 27dcbbc

Please sign in to comment.