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