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