Commit 6e98de22 authored by Simon Latapie's avatar Simon Latapie
Browse files

linting/wording

parent 9bebda9d
Pipeline #88090 passed with stages
in 17 seconds
......@@ -5,20 +5,34 @@ import (
"time"
)
// The State list should reflect the nodes from the acceptance graphs in `doc/acceptance.md`.
// None state is used in case of errors in the graph traversal
const (
InitialState = GraphNode("Initial")
RejectedState = GraphNode("Rejected")
PipelineReadyState = GraphNode("PipelineReadyState")
PipelineReadyState = GraphNode("PipelineReady")
ReviewableState = GraphNode("Reviewable")
InReviewState = GraphNode("InReview")
AcceptableState = GraphNode("Acceptable")
AcceptedState = GraphNode("Accepted")
NoneState = GraphNode("None")
MaxTransitions = 100 // Max transitions on graph - avoid graph infinite loop
)
// MaxTransitions represents the maximum number of transitions during graph traversal.
// This is used to avoid infinite loops
const maxTransitions = 100
// GraphNode is a very simple representation of a graph node.
type GraphNode string
// GraphEdge represents an edge/transition in the graph.
// From: edge start (the transition state where the condition will be evaluated)
// Condition: a function that will evaluate if the transition condition is fulfilled.
// To: edge end (this state will be the new current one if the Condition is fulfilled.
// ToOnFalse: if the Condition is not NOT OK and ToOnFalse is equal to NoneState,
// nothing happens (the next edge is evaluated). Otherwise, the new current state
// will be changed to ToOnFalse. This is a very simple way to implement a
// decision-like transition
type GraphEdge struct {
From GraphNode
Condition func(*MergeRequest) Check
......@@ -26,6 +40,7 @@ type GraphEdge struct {
ToOnFalse GraphNode
}
// SimpleEdge defines a simple non-decisional transition (ToOnFalse is set to NoneState)
func SimpleEdge(from GraphNode, condition func(*MergeRequest) Check, to GraphNode) GraphEdge {
return GraphEdge{from, condition, to, NoneState}
}
......@@ -37,7 +52,7 @@ func FindMRGraphState(mr *MergeRequest, graph []GraphEdge) (GraphNode, []Check)
checks := []Check{}
state := InitialState
iteration := 0
for ; iteration < MaxTransitions; iteration++ {
for ; iteration < maxTransitions; iteration++ {
transit := false
for _, edge := range graph {
if edge.From == state {
......@@ -66,13 +81,15 @@ func FindMRGraphState(mr *MergeRequest, graph []GraphEdge) (GraphNode, []Check)
break
}
}
if iteration == MaxTransitions {
if iteration >= maxTransitions {
// We should never been there: this means your Graph is not deterministic.
panic("Infinite loop in graph traversal!")
}
return state, checks
}
// UserAcceptanceGraph is the actual representation of the Acceptance graph for non-developer users
// Note: transitions will be evaluated in the order of definitions
func UserAcceptanceGraph() []GraphEdge {
graph := []GraphEdge{}
graph = append(graph, GraphEdge{InitialState, CheckMergeable, PipelineReadyState, RejectedState})
......@@ -85,6 +102,8 @@ func UserAcceptanceGraph() []GraphEdge {
return graph
}
// DeveloperAcceptanceGraph is the actual representation of the Acceptance graph for developer users
// Note: transitions will be evaluated in the order of definitions
func DeveloperAcceptanceGraph() []GraphEdge {
graph := []GraphEdge{}
graph = append(graph, GraphEdge{InitialState, CheckMergeable, PipelineReadyState, RejectedState})
......@@ -126,6 +145,8 @@ func CheckPipelines(mr *MergeRequest) Check {
}
}
// CheckVoteOrThread checks if the MR review has started, aka some votes and/or
// some threads have been opened
func CheckVoteOrThread(mr *MergeRequest) Check {
description := "MergeRequest should have at least one review and/or vote"
// strictly or not, we only need the number of votes here
......@@ -182,6 +203,7 @@ func CheckNoActivity(mr *MergeRequest) Check {
return Check{description, true, fmt.Sprintf("No developer vote or thread has been found, and time since last update is %s", timeSinceLastUpdate.Round(time.Minute)), nil}
}
// CheckAllThreadResolvedAndDevScoreStrict checks if all threads have been resolved and score is strictly positive
func CheckAllThreadResolvedAndDevScoreStrict(mr *MergeRequest) Check {
description := "All threads should be resolved, have votes and score > 0"
check, _ := CheckAllThreadResolved(mr)
......@@ -201,8 +223,9 @@ func CheckAllThreadResolvedAndDevScoreStrict(mr *MergeRequest) Check {
return Check{description, true, fmt.Sprintf("All threads seem resolved, developer votes (%d) found and score is strictly positive (%d)", votes, score), nil}
}
// CheckAllThreadResolvedAndDevScoreNonStrict checks if all threads have been resolved and score is positive
func CheckAllThreadResolvedAndDevScoreNonStrict(mr *MergeRequest) Check {
description := "All threads should be resolved, have votes and score >= 0"
description := "All threads should be resolved, and score >= 0"
check, _ := CheckAllThreadResolved(mr)
if check.Error != nil || !check.Success {
return check
......@@ -229,7 +252,7 @@ func CheckIsNotActiveAnymoreDeveloper(mr *MergeRequest) Check {
// CheckIsNotActiveAnymore checks if a MR has been inactiv for a certain time
func CheckIsNotActiveAnymore(mr *MergeRequest, discussionHoursThreshold int64, scoreHoursThreshold int64, strictly bool) Check {
description := fmt.Sprintf("MergeRequest should have no activity (threads/votes) for (%d/%d)h", discussionHoursThreshold, scoreHoursThreshold)
description := fmt.Sprintf("MergeRequest should have no activity (threads/votes) for (%dh/%dh)", discussionHoursThreshold, scoreHoursThreshold)
check, lastResolved := CheckAllThreadResolved(mr)
if check.Error != nil || !check.Success {
return check
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment