create_random_bugs.go

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