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