///|
pub struct ReviewPlan {
required_owners : Array[String]
approved_owners : Array[String]
unapproved_owners : Array[String]
required_checks : Array[String]
passed_checks : Array[String]
unresolved_checks : Array[String]
required_labels : Array[String]
present_labels : Array[String]
missing_labels : Array[String]
touched_rules : Array[String]
maximum_path_approvals : Int
release_note_required : Bool
release_note_present : Bool
} derive(Eq, @debug.Debug)
///|
pub fn ReviewPlan::required_owners(self : ReviewPlan) -> Array[String] {
self.required_owners.copy()
}
///|
pub fn ReviewPlan::approved_owners(self : ReviewPlan) -> Array[String] {
self.approved_owners.copy()
}
///|
pub fn ReviewPlan::unapproved_owners(self : ReviewPlan) -> Array[String] {
self.unapproved_owners.copy()
}
///|
pub fn ReviewPlan::required_checks(self : ReviewPlan) -> Array[String] {
self.required_checks.copy()
}
///|
pub fn ReviewPlan::passed_checks(self : ReviewPlan) -> Array[String] {
self.passed_checks.copy()
}
///|
pub fn ReviewPlan::unresolved_checks(self : ReviewPlan) -> Array[String] {
self.unresolved_checks.copy()
}
///|
pub fn ReviewPlan::required_labels(self : ReviewPlan) -> Array[String] {
self.required_labels.copy()
}
///|
pub fn ReviewPlan::present_labels(self : ReviewPlan) -> Array[String] {
self.present_labels.copy()
}
///|
pub fn ReviewPlan::missing_labels(self : ReviewPlan) -> Array[String] {
self.missing_labels.copy()
}
///|
pub fn ReviewPlan::touched_rules(self : ReviewPlan) -> Array[String] {
self.touched_rules.copy()
}
///|
pub fn ReviewPlan::maximum_path_approvals(self : ReviewPlan) -> Int {
self.maximum_path_approvals
}
///|
pub fn ReviewPlan::requires_release_note(self : ReviewPlan) -> Bool {
self.release_note_required
}
///|
pub fn ReviewPlan::has_release_note(self : ReviewPlan) -> Bool {
self.release_note_present
}
///|
fn check_is_passed(evidence : Evidence, name : String) -> Bool {
match check_state(evidence, name) {
Some(CheckState::Passed) => true
_ => false
}
}
///|
fn sorted_strings(values : Array[String]) -> Array[String] {
values.sort_by(fn(left, right) { left.lexical_compare(right) })
values
}
///|
fn build_review_plan(
decisions : Array[PathDecision],
evidence : Evidence,
) -> ReviewPlan {
let required_owners : Array[String] = []
let required_checks : Array[String] = []
let required_labels : Array[String] = []
let touched_rules : Array[String] = []
let mut maximum_path_approvals = 0
let mut release_note_required = false
for decision in decisions {
for owner in decision.owners {
push_unique_string(required_owners, owner)
}
for check in decision.checks {
push_unique_string(required_checks, check)
}
for label in decision.labels {
push_unique_string(required_labels, label)
}
for rule in decision.matched_rules {
push_unique_string(touched_rules, rule)
}
if decision.approvals > maximum_path_approvals {
maximum_path_approvals = decision.approvals
}
release_note_required = release_note_required || decision.release_note
}
let approved_owners : Array[String] = []
let unapproved_owners : Array[String] = []
for owner in required_owners {
if contains_string(evidence.approvals, owner) {
approved_owners.push(owner)
} else {
unapproved_owners.push(owner)
}
}
let passed_checks : Array[String] = []
let unresolved_checks : Array[String] = []
for check in required_checks {
if check_is_passed(evidence, check) {
passed_checks.push(check)
} else {
unresolved_checks.push(check)
}
}
let present_labels : Array[String] = []
let missing_labels : Array[String] = []
for label in required_labels {
if contains_string(evidence.labels, label) {
present_labels.push(label)
} else {
missing_labels.push(label)
}
}
{
required_owners: sorted_strings(required_owners),
approved_owners: sorted_strings(approved_owners),
unapproved_owners: sorted_strings(unapproved_owners),
required_checks: sorted_strings(required_checks),
passed_checks: sorted_strings(passed_checks),
unresolved_checks: sorted_strings(unresolved_checks),
required_labels: sorted_strings(required_labels),
present_labels: sorted_strings(present_labels),
missing_labels: sorted_strings(missing_labels),
touched_rules: sorted_strings(touched_rules),
maximum_path_approvals,
release_note_required,
release_note_present: evidence.release_note,
}
}
///|
pub fn ReviewPlan::to_text(self : ReviewPlan) -> String {
let release_note_required = if self.release_note_required {
"yes"
} else {
"no"
}
let release_note_present = if self.release_note_present {
"yes"
} else {
"no"
}
"REQUIRED_OWNERS " +
format_optional_csv(self.required_owners) +
"\nAPPROVED_OWNERS " +
format_optional_csv(self.approved_owners) +
"\nUNAPPROVED_OWNERS " +
format_optional_csv(self.unapproved_owners) +
"\nREQUIRED_CHECKS " +
format_optional_csv(self.required_checks) +
"\nPASSED_CHECKS " +
format_optional_csv(self.passed_checks) +
"\nUNRESOLVED_CHECKS " +
format_optional_csv(self.unresolved_checks) +
"\nREQUIRED_LABELS " +
format_optional_csv(self.required_labels) +
"\nPRESENT_LABELS " +
format_optional_csv(self.present_labels) +
"\nMISSING_LABELS " +
format_optional_csv(self.missing_labels) +
"\nTOUCHED_RULES " +
format_optional_csv(self.touched_rules) +
"\nMAX_PATH_APPROVALS " +
self.maximum_path_approvals.to_string() +
"\nRELEASE_NOTE_REQUIRED " +
release_note_required +
"\nRELEASE_NOTE_PRESENT " +
release_note_present
}