1package random_bugs
2
3import (
4 "math/rand"
5 "strings"
6 "time"
7
8 "github.com/MichaelMure/git-bug/bug"
9 "github.com/MichaelMure/git-bug/repository"
10 "github.com/icrowley/fake"
11)
12
13type opsGenerator func(bug.Interface, bug.Person)
14
15type Options struct {
16 BugNumber int
17 PersonNumber int
18 MinOp int
19 MaxOp int
20}
21
22func DefaultOptions() Options {
23 return Options{
24 BugNumber: 15,
25 PersonNumber: 5,
26 MinOp: 3,
27 MaxOp: 20,
28 }
29}
30
31func CommitRandomBugs(repo repository.ClockedRepo, opts Options) {
32 CommitRandomBugsWithSeed(repo, opts, time.Now().UnixNano())
33}
34
35func CommitRandomBugsWithSeed(repo repository.ClockedRepo, opts Options, seed int64) {
36 bugs := GenerateRandomBugsWithSeed(opts, seed)
37
38 for _, b := range bugs {
39 err := b.Commit(repo)
40 if err != nil {
41 panic(err)
42 }
43 }
44}
45
46func GenerateRandomBugs(opts Options) []*bug.Bug {
47 return GenerateRandomBugsWithSeed(opts, time.Now().UnixNano())
48}
49
50func GenerateRandomBugsWithSeed(opts Options, seed int64) []*bug.Bug {
51 rand.Seed(seed)
52 fake.Seed(seed)
53
54 opsGenerators := []opsGenerator{
55 comment,
56 comment,
57 title,
58 labels,
59 open,
60 close,
61 }
62
63 result := make([]*bug.Bug, opts.BugNumber)
64
65 for i := 0; i < opts.BugNumber; i++ {
66 addedLabels = []string{}
67
68 b, err := bug.Create(
69 randomPerson(opts.PersonNumber),
70 time.Now().Unix(),
71 fake.Sentence(),
72 paragraphs(),
73 )
74
75 if err != nil {
76 panic(err)
77 }
78
79 nOps := opts.MinOp
80
81 if opts.MaxOp > opts.MinOp {
82 nOps += rand.Intn(opts.MaxOp - opts.MinOp)
83 }
84
85 for j := 0; j < nOps; j++ {
86 index := rand.Intn(len(opsGenerators))
87 opsGenerators[index](b, randomPerson(opts.PersonNumber))
88 }
89
90 result[i] = b
91 }
92
93 return result
94}
95
96func GenerateRandomOperationPacks(packNumber int, opNumber int) []*bug.OperationPack {
97 return GenerateRandomOperationPacksWithSeed(packNumber, opNumber, time.Now().UnixNano())
98}
99
100func GenerateRandomOperationPacksWithSeed(packNumber int, opNumber int, seed int64) []*bug.OperationPack {
101 // Note: this is a bit crude, only generate a Create + Comments
102
103 rand.Seed(seed)
104 fake.Seed(seed)
105
106 result := make([]*bug.OperationPack, packNumber)
107
108 for i := 0; i < packNumber; i++ {
109 opp := &bug.OperationPack{}
110
111 var op bug.Operation
112
113 op = bug.NewCreateOp(
114 randomPerson(5),
115 time.Now().Unix(),
116 fake.Sentence(),
117 paragraphs(),
118 nil,
119 )
120
121 opp.Append(op)
122
123 for j := 0; j < opNumber-1; j++ {
124 op = bug.NewAddCommentOp(
125 randomPerson(5),
126 time.Now().Unix(),
127 paragraphs(),
128 nil,
129 )
130 opp.Append(op)
131 }
132
133 result[i] = opp
134 }
135
136 return result
137}
138
139func person() bug.Person {
140 return bug.Person{
141 Name: fake.FullName(),
142 Email: fake.EmailAddress(),
143 }
144}
145
146var persons []bug.Person
147
148func randomPerson(personNumber int) bug.Person {
149 if len(persons) == 0 {
150 persons = make([]bug.Person, personNumber)
151 for i := range persons {
152 persons[i] = person()
153 }
154 }
155
156 index := rand.Intn(personNumber)
157 return persons[index]
158}
159
160func paragraphs() string {
161 p := fake.Paragraphs()
162 return strings.Replace(p, "\t", "\n\n", -1)
163}
164
165func comment(b bug.Interface, p bug.Person) {
166 _ = bug.AddComment(b, p, time.Now().Unix(), paragraphs())
167}
168
169func title(b bug.Interface, p bug.Person) {
170 _ = bug.SetTitle(b, p, time.Now().Unix(), fake.Sentence())
171}
172
173func open(b bug.Interface, p bug.Person) {
174 _ = bug.Open(b, p, time.Now().Unix())
175}
176
177func close(b bug.Interface, p bug.Person) {
178 _ = bug.Close(b, p, time.Now().Unix())
179}
180
181var addedLabels []string
182
183func labels(b bug.Interface, p bug.Person) {
184 var removed []string
185 nbRemoved := rand.Intn(3)
186 for nbRemoved > 0 && len(addedLabels) > 0 {
187 index := rand.Intn(len(addedLabels))
188 removed = append(removed, addedLabels[index])
189 addedLabels[index] = addedLabels[len(addedLabels)-1]
190 addedLabels = addedLabels[:len(addedLabels)-1]
191 nbRemoved--
192 }
193
194 var added []string
195 nbAdded := rand.Intn(3)
196 for i := 0; i < nbAdded; i++ {
197 label := fake.Word()
198 added = append(added, label)
199 addedLabels = append(addedLabels, label)
200 }
201
202 // ignore error
203 // if the randomisation produce no changes, no op
204 // is added to the bug
205 _, _ = bug.ChangeLabels(b, p, time.Now().Unix(), added, removed)
206}