Skip to content

Commit 9b71ad8

Browse files
authored
Merge pull request #1988 from Kobzol/deterministic-static-api
Make the output of the static API deterministic
2 parents fe9c45f + a896101 commit 9b71ad8

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ atty.workspace = true
2929
difference.workspace = true
3030
duct.workspace = true
3131
walkdir.workspace = true
32+
dir-diff = "0.3"
3233

3334
[workspace]
3435
members = [

src/static_api.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::{ensure, Context as _, Error};
44
use indexmap::IndexMap;
55
use log::info;
66
use rust_team_data::v1;
7-
use rust_team_data::v1::BranchProtectionMode;
7+
use rust_team_data::v1::{BranchProtectionMode, RepoMember};
88
use std::collections::HashMap;
99
use std::path::Path;
1010

@@ -121,25 +121,30 @@ impl<'a> Generator<'a> {
121121
}
122122
}
123123
}
124+
teams.sort_by_key(|t| t.name.clone());
124125
teams
125126
},
126-
members: r
127-
.access
128-
.individuals
129-
.iter()
130-
.map(|(name, permission)| {
131-
let permission = match permission {
132-
RepoPermission::Admin => v1::RepoPermission::Admin,
133-
RepoPermission::Write => v1::RepoPermission::Write,
134-
RepoPermission::Maintain => v1::RepoPermission::Maintain,
135-
RepoPermission::Triage => v1::RepoPermission::Triage,
136-
};
137-
v1::RepoMember {
138-
name: name.clone(),
139-
permission,
140-
}
141-
})
142-
.collect(),
127+
members: {
128+
let mut members: Vec<RepoMember> = r
129+
.access
130+
.individuals
131+
.iter()
132+
.map(|(name, permission)| {
133+
let permission = match permission {
134+
RepoPermission::Admin => v1::RepoPermission::Admin,
135+
RepoPermission::Write => v1::RepoPermission::Write,
136+
RepoPermission::Maintain => v1::RepoPermission::Maintain,
137+
RepoPermission::Triage => v1::RepoPermission::Triage,
138+
};
139+
v1::RepoMember {
140+
name: name.clone(),
141+
permission,
142+
}
143+
})
144+
.collect();
145+
members.sort_by_key(|m| m.name.clone());
146+
members
147+
},
143148
branch_protections,
144149
archived,
145150
auto_merge_enabled: !managed_by_bors,
@@ -204,7 +209,8 @@ impl<'a> Generator<'a> {
204209
let mut github_teams = team.github_teams(self.data)?;
205210
github_teams.sort();
206211

207-
let member_discord_ids = team.discord_ids(self.data)?;
212+
let mut member_discord_ids = team.discord_ids(self.data)?;
213+
member_discord_ids.sort();
208214

209215
let team_data = v1::Team {
210216
name: team.name().into(),

tests/snapshot.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,24 @@ fn static_api() -> Result<(), Error> {
7777
Ok(())
7878
}
7979

80+
#[test]
81+
fn static_api_determinism() -> Result<(), Error> {
82+
// Ensure that the output of `static-api` is deterministic
83+
let dir = tempfile::TempDir::new()?;
84+
let reference_dir = dir.path().join("reference");
85+
cmd!(bin(), "static-api", &reference_dir).assert_success()?;
86+
87+
for i in 0..10 {
88+
let out = dir.path().join(format!("output-{i}"));
89+
cmd!(bin(), "static-api", &out).assert_success()?;
90+
assert!(
91+
!dir_diff::is_different(&reference_dir, &out)?,
92+
"static-api produced non-deterministic output"
93+
);
94+
}
95+
Ok(())
96+
}
97+
8098
fn bin() -> &'static str {
8199
env!("CARGO_BIN_EXE_rust-team")
82100
}

0 commit comments

Comments
 (0)