forked from realvnc-labs/tacoscript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsort.go
More file actions
90 lines (72 loc) · 2.11 KB
/
sort.go
File metadata and controls
90 lines (72 loc) · 2.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package script
import (
"github.com/cloudradar-monitoring/tacoscript/tasks"
)
type positionedRequirement struct {
previous string
next string
}
func SortScriptsRespectingRequirements(scripts tasks.Scripts) {
requirements, positionsMap := buildRequirementsMap(scripts)
for {
allReqMet, req := allRequirementsMet(requirements, positionsMap)
if allReqMet {
break
}
previousElementIndex := positionsMap[req.previous]
nexElementIndex := positionsMap[req.next]
moveScriptToPosition(scripts, previousElementIndex, nexElementIndex)
positionsMap = make(map[string]int, len(positionsMap))
for pos, script := range scripts {
positionsMap[script.ID] = pos
}
}
}
func allRequirementsMet(requirements []positionedRequirement, positionsMap map[string]int) (bool, positionedRequirement) {
for _, req := range requirements {
if req.previous == req.next {
continue
}
previousPos, ok := positionsMap[req.previous]
if !ok {
continue
}
nextPos, ok := positionsMap[req.next]
if !ok {
continue
}
if previousPos > nextPos {
return false, req
}
}
return true, positionedRequirement{}
}
func buildRequirementsMap(scrpts tasks.Scripts) (req []positionedRequirement, positionsMap map[string]int) {
req = make([]positionedRequirement, 0)
positionsMap = make(map[string]int)
for pos, script := range scrpts {
positionsMap[script.ID] = pos
for _, task := range script.Tasks {
for _, reqName := range task.GetRequirements() {
req = append(req, positionedRequirement{
previous: reqName,
next: script.ID,
})
}
}
}
return req, positionsMap
}
func insertScript(array tasks.Scripts, value tasks.Script, index int) tasks.Scripts {
return append(array[:index], append(tasks.Scripts{value}, array[index:]...)...)
}
func removeScript(array tasks.Scripts, index int) tasks.Scripts {
return append(array[:index], array[index+1:]...)
}
func moveScriptToPosition(array tasks.Scripts, srcIndex, dstIndex int) tasks.Scripts {
if srcIndex > len(array)-1 {
return tasks.Scripts{}
}
value := array[srcIndex]
return insertScript(removeScript(array, srcIndex), value, dstIndex)
}