This repository has no description
5.7 kB
170 lines
1use std::fmt::{self, Display, Formatter};
2
3use crate::adopt::AdoptOutcome;
4use crate::emit::CobSummary;
5use crate::mapping::{Mapping, SkipReason};
6
7pub struct Report<'a> {
8 pub mapping: &'a Mapping,
9 pub orphan_alias_count: u64,
10 pub adoption: Option<&'a AdoptOutcome>,
11 pub cobs: Option<&'a CobSummary>,
12}
13
14impl Display for Report<'_> {
15 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
16 let mapping = self.mapping;
17 let drift = &mapping.drift;
18 writeln!(f, "knot owner: {}", mapping.knot_owner)?;
19 writeln!(f, "members to grant: {}", mapping.members.len())?;
20 writeln!(f, "repos to adopt: {}", mapping.repos.len())?;
21 writeln!(
22 f,
23 "collaborator grants: {}",
24 mapping
25 .repos
26 .iter()
27 .map(|repo| repo.collaborators.len())
28 .sum::<usize>()
29 )?;
30 writeln!(f)?;
31 writeln!(f, "casbin cross-check drift:")?;
32 writeln!(
33 f,
34 "acl-only collaborator grants unioned in: {}",
35 drift.acl_only_collaborators.len()
36 )?;
37 drift
38 .acl_only_collaborators
39 .iter()
40 .try_for_each(|(repo, did)| writeln!(f, "{repo} <- {did}"))?;
41 writeln!(
42 f,
43 "table-only collaborator grants missing from acl: {}",
44 drift.table_only_collaborators.len()
45 )?;
46 drift
47 .table_only_collaborators
48 .iter()
49 .try_for_each(|(repo, did)| writeln!(f, "{repo} <- {did}"))?;
50 writeln!(
51 f,
52 "repos with no acl owner marker where the owner regains push: {}",
53 drift.markerless_owner_repos.len()
54 )?;
55 drift
56 .markerless_owner_repos
57 .iter()
58 .try_for_each(|repo| writeln!(f, "{repo}"))?;
59 writeln!(
60 f,
61 "orphan owner markers on unknown repos: {}",
62 drift.orphan_owner_markers.len()
63 )?;
64 writeln!(
65 f,
66 "extra acl owner markers dropped: {}",
67 drift.extra_owner_markers.len()
68 )?;
69 drift
70 .extra_owner_markers
71 .iter()
72 .try_for_each(|(repo, did)| writeln!(f, "{repo} <- {did}"))?;
73 writeln!(
74 f,
75 "orphan collaborator pairs on unknown repos: {}",
76 drift.orphan_collaborator_pairs.len()
77 )?;
78 writeln!(
79 f,
80 "acl-only members unioned in: {}",
81 drift.acl_only_members.len()
82 )?;
83 drift
84 .acl_only_members
85 .iter()
86 .try_for_each(|did| writeln!(f, "{did}"))?;
87 writeln!(
88 f,
89 "table-only members missing from acl: {}",
90 drift.table_only_members.len()
91 )?;
92 writeln!(f, "slash-form owner markers: {}", drift.slash_owner_markers)?;
93 writeln!(
94 f,
95 "slash-form collaborator rows: {}",
96 drift.slash_collab_rows
97 )?;
98 writeln!(
99 f,
100 "slash-resolved collaborator grants left out of the union: {}",
101 drift.slash_resolved_collaborators.len()
102 )?;
103 drift
104 .slash_resolved_collaborators
105 .iter()
106 .try_for_each(|(repo, did)| writeln!(f, "{repo} <- {did}"))?;
107 writeln!(
108 f,
109 "unresolved slash forms: {}",
110 drift.unresolved_slash_forms.len()
111 )?;
112 drift
113 .unresolved_slash_forms
114 .iter()
115 .try_for_each(|form| writeln!(f, "{form}"))?;
116 writeln!(f, "orphan aliases: {}", self.orphan_alias_count)?;
117 writeln!(f)?;
118 writeln!(f, "skipped repos: {}", mapping.skipped.len())?;
119 mapping.skipped.iter().try_for_each(|skip| {
120 writeln!(f, "{} {}", skip.repo_did, describe(&skip.reason))?;
121 skip.lost_collaborators
122 .iter()
123 .try_for_each(|did| writeln!(f, "drops collaborator grant for {did}"))
124 })?;
125 self.adoption.map_or(Ok(()), |adoption| {
126 writeln!(f)?;
127 writeln!(
128 f,
129 "adopted by {}: {} new, {} already present, {} sha1, {} sha256",
130 adoption.transfer,
131 adoption.adopted,
132 adoption.already_present,
133 adoption.sha1,
134 adoption.sha256
135 )
136 })?;
137 self.cobs.map_or(Ok(()), |cobs| {
138 writeln!(f)?;
139 writeln!(
140 f,
141 "member grants: {} appended, {} already present",
142 cobs.members.appended, cobs.members.already_present
143 )?;
144 writeln!(
145 f,
146 "registrations: {} appended, {} already present",
147 cobs.registrations.appended, cobs.registrations.already_present
148 )?;
149 writeln!(
150 f,
151 "collaborator grants: {} appended, {} already present",
152 cobs.collaborators.appended, cobs.collaborators.already_present
153 )
154 })
155 }
156}
157
158fn describe(reason: &SkipReason) -> String {
159 match reason {
160 SkipReason::Name { value } => format!("unrepresentable name {:?}", value.as_str()),
161 SkipReason::Rkey { value } => format!("unrepresentable rkey {:?}", value.as_str()),
162 SkipReason::RkeyCollision { rkey, winner } => {
163 format!(
164 "record key {:?} belongs to the alias-backed {winner}",
165 rkey.as_str()
166 )
167 }
168 SkipReason::NoSourceRepo => "no git repository at the source path".to_string(),
169 }
170}