├── .gitignore ├── Makefile ├── go ├── sort.rb ├── stats │ └── main.go ├── downloader │ └── main.go └── crawler │ └── main.go ├── data └── urls.txt └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | time go run go/downloader/main.go 3 | 4 | 5 | crawl: 6 | time go run go/crawler/main.go 7 | 8 | stats: 9 | go run go/stats/main.go 10 | 11 | sort: 12 | ruby go/sort.rb 13 | 14 | all: sort run crawl stats; 15 | -------------------------------------------------------------------------------- /go/sort.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | content = File 3 | .read("data/urls.txt") 4 | .split("\n") 5 | .map(&:downcase) 6 | .map(&:strip) 7 | .sort 8 | .uniq 9 | .reject{|x| x == ""} 10 | .join("\n") 11 | 12 | File.write("data/urls.txt", content) 13 | -------------------------------------------------------------------------------- /data/urls.txt: -------------------------------------------------------------------------------- 1 | https://github.com/altairsix/eventsource 2 | https://github.com/andrewwebber/cqrs 3 | https://github.com/andrewwebber/cqrs-scaleout 4 | https://github.com/atitsbest/go_cqrs 5 | https://github.com/berkaroad/ddd 6 | https://github.com/berkaroad/ioc 7 | https://github.com/botchniaque/eventsourcing-cqrs-go 8 | https://github.com/cloudnativego/drones-cmds 9 | https://github.com/cloudnativego/drones-events 10 | https://github.com/cloudnativego/drones-query 11 | https://github.com/customerio/esdb 12 | https://github.com/dc0d/sector 13 | https://github.com/diegogub/esgo 14 | https://github.com/diegogub/gocqrs 15 | https://github.com/duskhacker/cqrsnu 16 | https://github.com/egonelbre/guestlist 17 | https://github.com/eventsourcedb/eventsourcedb 18 | https://github.com/f2prateek/coi 19 | https://github.com/hellofresh/goengine 20 | https://github.com/isuruceanu/gocqrs 21 | https://github.com/jensrantil/gorewind 22 | https://github.com/jetbasrawi/go.geteventstore 23 | https://github.com/jetbasrawi/go.geteventstore.testfeed 24 | https://github.com/jostly/cqrs-bookstore-go 25 | https://github.com/looplab/eventhorizon 26 | https://github.com/mbucc/cqrs 27 | https://github.com/mcveat/event-sourcing-cqrs 28 | https://github.com/mishudark/eventhus 29 | https://github.com/moul/cleanarch 30 | https://github.com/nicdex/goes 31 | https://github.com/pjvds/go-cqrs 32 | https://github.com/robertreppel/hist 33 | https://github.com/rogerclotet/cqrs 34 | https://github.com/rogerclotet/graceful-restart 35 | https://github.com/saem/afterme 36 | https://github.com/sclasen/swfsm 37 | https://github.com/sunrongya/eventsourcing 38 | https://github.com/sunrongya/milife 39 | https://github.com/thebookofeveryone/cqrs 40 | https://github.com/uber-go/dig 41 | https://github.com/vizidrix/eventstore 42 | https://github.com/vizidrix/gocqrs 43 | https://github.com/xozrc/cqrs 44 | https://github.com/xozrc/eventsourcing 45 | https://github.com/xtracdev/es-atom-data 46 | https://github.com/xtracdev/es-atom-pub 47 | https://github.com/xtracdev/es-data-pub 48 | https://github.com/xtracdev/goes 49 | https://github.com/xtracdev/oraeventstore 50 | https://github.com/xtracdev/orapub 51 | https://github.com/xtraclabs/appreg 52 | https://github.com/xtraclabs/es-atom-feed-data 53 | https://github.com/yuukanoo/go-toolbelt -------------------------------------------------------------------------------- /go/stats/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "path/filepath" 9 | "regexp" 10 | "sort" 11 | "strconv" 12 | "strings" 13 | ) 14 | 15 | var ( 16 | readmeFile = "Readme.md" 17 | ) 18 | 19 | func main() { 20 | topLevel() 21 | } 22 | 23 | func topLevel() { 24 | folders := getGitRepos("src/") 25 | repos := []repo{} 26 | for _, f := range folders { 27 | if isDir(f) { 28 | repo := newRepoForPath(f) 29 | repos = append(repos, repo) 30 | } 31 | } 32 | readmeHandler{}.replaceProjects(repos) 33 | for _, repo := range repos { 34 | fmt.Println(repo.asString()) 35 | } 36 | } 37 | 38 | func newRepoForPath(dirPath string) repo { 39 | fullSize := DirSizeMB(dirPath) 40 | gitSize := DirSizeMB(dirPath + "/.git") 41 | codeSize := fullSize - gitSize 42 | return repo{ 43 | name: dirPath, 44 | fullSize: fullSize, 45 | gitSize: gitSize, 46 | codeSize: codeSize, 47 | } 48 | } 49 | 50 | /* 51 | REPO logic 52 | */ 53 | type repo struct { 54 | name string 55 | fullSize float64 56 | gitSize float64 57 | codeSize float64 58 | } 59 | 60 | func (r repo) asString() string { 61 | name := strings.Replace(r.name, "src/github.com/", "", -1) 62 | return fmt.Sprintf("%s: %s MB\n (%s MB git / %s MB code)", 63 | name, 64 | floatAsString(r.fullSize), 65 | floatAsString(r.gitSize), 66 | floatAsString(r.codeSize), 67 | ) 68 | } 69 | 70 | func (r repo) asMarkdown() string { 71 | name := strings.Replace(r.name, "src/github.com/", "", -1) 72 | link := fmt.Sprintf("[%s](%s)", name, "https://github.com/"+name) 73 | return fmt.Sprintf("- %s: %s MB
(%s MB git / %s MB code)", 74 | link, 75 | floatAsString(r.fullSize), 76 | floatAsString(r.gitSize), 77 | floatAsString(r.codeSize), 78 | ) 79 | } 80 | 81 | func floatAsString(f float64) string { 82 | return strconv.FormatFloat(f, 'f', 2, 64) 83 | } 84 | 85 | // DirSizeMB returns the MB size of a folder 86 | func DirSizeMB(path string) float64 { 87 | var dirSize int64 88 | 89 | readSize := func(path string, file os.FileInfo, err error) error { 90 | if !file.IsDir() { 91 | dirSize += file.Size() 92 | } 93 | return nil 94 | } 95 | 96 | filepath.Walk(path, readSize) 97 | sizeMB := float64(dirSize) / 1024.0 / 1024.0 98 | return sizeMB 99 | } 100 | 101 | func getGitRepos(path string) []string { 102 | repos := []string{} 103 | r := regexp.MustCompile("/.git$") 104 | 105 | findRepos := func(path string, file os.FileInfo, err error) error { 106 | if file.IsDir() && file.Name() == ".git" { 107 | newpath := r.ReplaceAllString(path, "") 108 | repos = append(repos, newpath) 109 | } 110 | return nil 111 | } 112 | 113 | filepath.Walk(path, findRepos) 114 | return repos 115 | } 116 | 117 | func isDir(filePath string) bool { 118 | fi, err := os.Stat(filePath) 119 | check(err) 120 | if fi.IsDir() { 121 | return true 122 | } 123 | return false 124 | } 125 | 126 | func check(err error) { 127 | if err != nil { 128 | log.Fatal(err) 129 | } 130 | } 131 | 132 | type reposByFullSize []repo 133 | 134 | func (ris reposByFullSize) Len() int { return len(ris) } 135 | func (ris reposByFullSize) Less(i, j int) bool { return ris[i].fullSize > ris[j].fullSize } 136 | func (ris reposByFullSize) Swap(i, j int) { ris[i], ris[j] = ris[j], ris[i] } 137 | 138 | /* 139 | readmeHandler logic 140 | rough translation of https://github.com/mindreframer/techwatcher/blob/master/_sh/logic.rb 141 | */ 142 | 143 | type readmeHandler struct{} 144 | 145 | func (rh readmeHandler) replaceProjects(repos []repo) { 146 | pattern := `(?s)(.*)` 147 | regexStart := `` 148 | regexEnd := `` 149 | 150 | sort.Sort(reposByFullSize(repos)) 151 | lines := []string{} 152 | lines = append(lines, regexStart) 153 | for _, repo := range repos { 154 | lines = append(lines, repo.asMarkdown()) 155 | } 156 | lines = append(lines, regexEnd) 157 | 158 | r := regexp.MustCompile(pattern) 159 | 160 | data, err := ioutil.ReadFile(readmeFile) 161 | check(err) 162 | res := r.ReplaceAllString(string(data), strings.Join(lines, "\n")) 163 | ioutil.WriteFile(readmeFile, []byte(res), 0777) 164 | } 165 | -------------------------------------------------------------------------------- /go/downloader/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | "os/exec" 9 | "strings" 10 | "sync" 11 | ) 12 | 13 | func check(e error) { 14 | if e != nil { 15 | log.Println(e) 16 | panic(e) 17 | } 18 | } 19 | 20 | func checkMsg(e error, msg string) { 21 | if e != nil { 22 | log.Println(msg) 23 | log.Println(e) 24 | panic(e) 25 | } 26 | } 27 | 28 | func main() { 29 | s := newSemaphore(20) 30 | var wg sync.WaitGroup 31 | urls := loadUrls() 32 | for _, url := range urls { 33 | s.Acquire(1) 34 | wg.Add(1) 35 | a := url 36 | go func() { 37 | defer wg.Done() 38 | defer s.Release(1) 39 | checkRepo(a) 40 | }() 41 | } 42 | wg.Wait() 43 | } 44 | 45 | func loadUrls() []string { 46 | return file2lines("data/urls.txt") 47 | } 48 | 49 | func checkRepo(url string) error { 50 | repo := newRepo(url) 51 | return repo.Run() 52 | } 53 | 54 | /***************************************************************** 55 | 56 | Repo logic 57 | 58 | ******************************************************************/ 59 | 60 | type repo struct { 61 | url string 62 | } 63 | 64 | func newRepo(url string) *repo { 65 | return &repo{url: url} 66 | } 67 | 68 | // Run is the only public method for repos 69 | func (r *repo) Run() error { 70 | if r.exists() { 71 | return r.refresh() 72 | } 73 | return r.checkout() 74 | } 75 | 76 | // initial git checkout 77 | func (r *repo) checkout() error { 78 | fmt.Printf("checking out %s\n", r.fullPath()) 79 | cmd := fmt.Sprintf("git clone %s %s", r.url, r.fullPath()) 80 | out, err := exec.Command("sh", "-c", cmd).Output() 81 | checkMsg(err, "For "+r.url) 82 | fmt.Println(r.projectName(), "\n---\n", string(out)) 83 | return nil 84 | } 85 | 86 | // refresh existing repo 87 | func (r *repo) refresh() error { 88 | fmt.Printf("refreshing %s\n", r.fullPath()) 89 | cmd := fmt.Sprintf("cd %s; git pull", r.fullPath()) 90 | out, err := exec.Command("sh", "-c", cmd).Output() 91 | checkMsg(err, r.url) 92 | fmt.Println(r.projectName(), "\n---\n", string(out)) 93 | return nil 94 | } 95 | 96 | // does this project exist? 97 | func (r *repo) exists() bool { 98 | if _, err := os.Stat(r.fullPath()); err == nil { 99 | return true 100 | } 101 | return false 102 | } 103 | 104 | // the name of the resulting folder (unique) 105 | func (r *repo) projectName() string { 106 | parts := strings.Split(r.url, "/") 107 | user := parts[len(parts)-2] 108 | name := parts[len(parts)-1] 109 | name = strings.Replace(name, ".git", "", -1) 110 | res := fmt.Sprintf("%s--%s", user, name) 111 | return res 112 | } 113 | 114 | // full path to repo folder 115 | func (r *repo) fullPath() string { 116 | parts := strings.SplitN(r.url, "github.com/", 2) 117 | return "src/github.com/" + parts[1] 118 | } 119 | 120 | /***************************************************************** 121 | 122 | Semaphore provides a semaphore synchronization primitive 123 | (vendored for simplicity) 124 | 125 | ******************************************************************/ 126 | 127 | // Semaphore controls access to a finite number of resources. 128 | type Semaphore chan struct{} 129 | 130 | // New creates a Semaphore that controls access to `n` resources. 131 | func newSemaphore(n int) Semaphore { 132 | return Semaphore(make(chan struct{}, n)) 133 | } 134 | 135 | // Acquire `n` resources. 136 | func (s Semaphore) Acquire(n int) { 137 | for i := 0; i < n; i++ { 138 | s <- struct{}{} 139 | } 140 | } 141 | 142 | // Release `n` resources. 143 | func (s Semaphore) Release(n int) { 144 | for i := 0; i < n; i++ { 145 | <-s 146 | } 147 | } 148 | 149 | /* 150 | simple lines reader 151 | */ 152 | func file2lines(filePath string) []string { 153 | f, err := os.Open(filePath) 154 | if err != nil { 155 | panic(err) 156 | } 157 | defer f.Close() 158 | 159 | var lines []string 160 | scanner := bufio.NewScanner(f) 161 | for scanner.Scan() { 162 | if t := scanner.Text(); validURL(t) { 163 | lines = append(lines, t) 164 | } 165 | } 166 | if err := scanner.Err(); err != nil { 167 | fmt.Fprintln(os.Stderr, err) 168 | } 169 | 170 | return lines 171 | } 172 | 173 | func validURL(l string) bool { 174 | return !strings.Contains(l, " ") && len(l) != 0 175 | } 176 | -------------------------------------------------------------------------------- /go/crawler/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "regexp" 10 | "sort" 11 | "strings" 12 | "sync" 13 | 14 | "github.com/PuerkitoBio/goquery" 15 | ) 16 | 17 | var ( 18 | urlFile = "data/urls.txt" 19 | readmeFile = "Readme.md" 20 | ) 21 | 22 | func main() { 23 | var wg sync.WaitGroup 24 | urls := loadUrls() 25 | repos := []repoInfo{} 26 | for _, url := range urls { 27 | wg.Add(1) 28 | a := url 29 | go func() { 30 | defer wg.Done() 31 | repo := process(a) 32 | repos = append(repos, repo) 33 | fmt.Print(".") 34 | }() 35 | } 36 | wg.Wait() 37 | printSortedAlpha(repos) 38 | printSortedLastcommit(repos) 39 | rh := readmeHandler{} 40 | rh.replaceProjects(repos) 41 | rh.replaceActivity(repos) 42 | } 43 | 44 | func printSortedAlpha(repos []repoInfo) { 45 | sort.Sort(reposByURL(repos)) 46 | fmt.Print("\n\n") 47 | for _, r := range repos { 48 | fmt.Println(r.MarkdownProject()) 49 | } 50 | } 51 | 52 | func printSortedLastcommit(repos []repoInfo) { 53 | sort.Sort(reposByLastcommit(repos)) 54 | fmt.Print("\n\n") 55 | for _, r := range repos { 56 | fmt.Println(r.MarkdownActivity()) 57 | } 58 | } 59 | 60 | func process(url string) repoInfo { 61 | parser := repoParser{} 62 | doc := parser.getDoc(url) 63 | repo := repoInfo{ 64 | url: strings.ToLower(url), 65 | description: parser.getDescription(doc), 66 | lastcommit: parser.getLastcommit(doc), 67 | commitsCount: parser.getCommitsCount(doc), 68 | stars: parser.getStarsCount(doc), 69 | } 70 | return repo 71 | } 72 | 73 | func check(err error) { 74 | if err != nil { 75 | log.Fatal(err) 76 | } 77 | } 78 | func checkMsg(e error, msg string) { 79 | if e != nil { 80 | log.Println(msg) 81 | log.Println(e) 82 | panic(e) 83 | } 84 | } 85 | 86 | /* 87 | readmeHandler logic 88 | rough translation of https://github.com/mindreframer/techwatcher/blob/master/_sh/logic.rb 89 | */ 90 | 91 | type readmeHandler struct{} 92 | 93 | func (rh readmeHandler) replaceProjects(repos []repoInfo) { 94 | pattern := `(?s)(.*)` 95 | regexStart := `` 96 | regexEnd := `` 97 | 98 | sort.Sort(reposByURL(repos)) 99 | lines := []string{} 100 | lines = append(lines, regexStart) 101 | for _, repo := range repos { 102 | lines = append(lines, repo.MarkdownProject()) 103 | } 104 | lines = append(lines, regexEnd) 105 | 106 | r := regexp.MustCompile(pattern) 107 | 108 | data, err := ioutil.ReadFile(readmeFile) 109 | checkMsg(err, readmeFile) 110 | res := r.ReplaceAllString(string(data), strings.Join(lines, "\n")) 111 | ioutil.WriteFile(readmeFile, []byte(res), 0777) 112 | } 113 | 114 | func (rh readmeHandler) replaceActivity(repos []repoInfo) { 115 | pattern := `(?s)(.*)` 116 | regexStart := `` 117 | regexEnd := `` 118 | 119 | sort.Sort(reposByLastcommit(repos)) 120 | lines := []string{} 121 | lines = append(lines, regexStart) 122 | for _, repo := range repos { 123 | lines = append(lines, repo.MarkdownActivity()) 124 | } 125 | lines = append(lines, regexEnd) 126 | r := regexp.MustCompile(pattern) 127 | 128 | data, err := ioutil.ReadFile(readmeFile) 129 | check(err) 130 | res := r.ReplaceAllString(string(data), strings.Join(lines, "\n")) 131 | ioutil.WriteFile(readmeFile, []byte(res), 0777) 132 | } 133 | 134 | /* 135 | Repo Parser logic 136 | */ 137 | type repoParser struct{} 138 | 139 | func (r repoParser) getDescription(doc *goquery.Document) string { 140 | var content string 141 | doc.Find("meta").Each(func(i int, s *goquery.Selection) { 142 | name, _ := s.Attr("name") 143 | if name == "description" { 144 | content, _ = s.Attr("content") 145 | } 146 | }) 147 | var parts []string 148 | if strings.Contains(content, " - ") { 149 | parts = strings.SplitN(content, " - ", 2) 150 | content = parts[1] 151 | } 152 | if strings.Contains(content, "by creating an account on GitHub") { 153 | content = "---" 154 | } 155 | 156 | return strings.TrimSpace(content) 157 | } 158 | 159 | func (r repoParser) getCommitsCount(doc *goquery.Document) string { 160 | return r.getSelectorText(doc, ".numbers-summary .commits .num") 161 | } 162 | 163 | func (r repoParser) getStarsCount(doc *goquery.Document) string { 164 | return r.getSelectorText(doc, ".social-count") 165 | } 166 | 167 | func (r repoParser) getLastcommit(doc *goquery.Document) string { 168 | if r.hasIncludedLastcommit(doc) { 169 | return r.getLastcommitIncluded(doc) 170 | } 171 | return r.getLastcommitAjax(doc) 172 | } 173 | 174 | func (r repoParser) hasIncludedLastcommit(doc *goquery.Document) bool { 175 | found := true 176 | doc.Find(".commit-loader").Each(func(i int, s *goquery.Selection) { 177 | found = false 178 | }) 179 | return found 180 | } 181 | 182 | func (r repoParser) getLastcommitIncluded(doc *goquery.Document) string { 183 | var datetime string 184 | doc.Find(".commit-tease relative-time").Each(func(i int, s *goquery.Selection) { 185 | datetime, _ = s.Attr("datetime") 186 | }) 187 | return datetime 188 | } 189 | 190 | func (r repoParser) getLastcommitAjax(doc *goquery.Document) string { 191 | // extract the ajax url 192 | // e.g.: 193 | s := doc.Find(".commit-loader") 194 | path, _ := s.Attr("src") 195 | url := "https://github.com" + path 196 | ajaxDoc := r.urlDoc(url) 197 | return r.getLastcommit(ajaxDoc) 198 | } 199 | 200 | func (r repoParser) getSelectorText(doc *goquery.Document, selector string) string { 201 | var content string 202 | doc.Find(selector).Each(func(i int, s *goquery.Selection) { 203 | content = strings.TrimSpace(s.Text()) 204 | }) 205 | return content 206 | } 207 | 208 | func (r repoParser) getDoc(url string) *goquery.Document { 209 | return r.urlDoc(url) 210 | // return r.localDoc() 211 | } 212 | 213 | func (r repoParser) urlDoc(url string) *goquery.Document { 214 | doc, err := goquery.NewDocument(url) 215 | checkMsg(err, url) 216 | return doc 217 | } 218 | 219 | func (r repoParser) localDoc() *goquery.Document { 220 | filename := "crawler/fixture.html" 221 | file, err := os.Open(filename) 222 | check(err) 223 | doc, err := goquery.NewDocumentFromReader(file) 224 | check(err) 225 | return doc 226 | } 227 | 228 | /* 229 | repoInfo logic 230 | */ 231 | type repoInfo struct { 232 | url string 233 | description string 234 | lastcommit string 235 | commitsCount string 236 | stars string 237 | } 238 | 239 | func (ri repoInfo) MarkdownProject() string { 240 | return fmt.Sprintf("- %s - %s
( %s / %s commits / %s stars )", 241 | ri.mdLink(), 242 | ri.description, 243 | ri.lastcommitShort(), 244 | ri.commitsCount, 245 | ri.stars, 246 | ) 247 | } 248 | 249 | func (ri repoInfo) MarkdownActivity() string { 250 | return fmt.Sprintf("- %s: %s
%s", 251 | ri.mdLink(), 252 | ri.lastcommitShort(), 253 | ri.description, 254 | ) 255 | } 256 | 257 | func (ri repoInfo) shorturl() string { 258 | return strings.Replace(ri.url, "https://github.com/", "", -1) 259 | } 260 | 261 | func (ri repoInfo) mdLink() string { 262 | return fmt.Sprintf("[%s](%s)", ri.shorturl(), ri.url) 263 | } 264 | 265 | func (ri repoInfo) lastcommitShort() string { 266 | return ri.lastcommit[0:10] 267 | } 268 | 269 | type reposByLastcommit []repoInfo 270 | 271 | func (ris reposByLastcommit) Len() int { return len(ris) } 272 | func (ris reposByLastcommit) Less(i, j int) bool { return ris[i].lastcommit > ris[j].lastcommit } 273 | func (ris reposByLastcommit) Swap(i, j int) { ris[i], ris[j] = ris[j], ris[i] } 274 | 275 | type reposByURL []repoInfo 276 | 277 | func (ris reposByURL) Len() int { return len(ris) } 278 | func (ris reposByURL) Less(i, j int) bool { return ris[i].url < ris[j].url } 279 | func (ris reposByURL) Swap(i, j int) { ris[i], ris[j] = ris[j], ris[i] } 280 | 281 | /* 282 | data loading (simple lines reader) 283 | */ 284 | 285 | func loadUrls() []string { 286 | return file2lines(urlFile) 287 | } 288 | 289 | func file2lines(filePath string) []string { 290 | f, err := os.Open(filePath) 291 | if err != nil { 292 | panic(err) 293 | } 294 | defer f.Close() 295 | 296 | var lines []string 297 | scanner := bufio.NewScanner(f) 298 | for scanner.Scan() { 299 | if t := scanner.Text(); validURL(t) { 300 | lines = append(lines, t) 301 | } 302 | } 303 | if err := scanner.Err(); err != nil { 304 | fmt.Fprintln(os.Stderr, err) 305 | } 306 | 307 | return lines 308 | } 309 | 310 | func validURL(l string) bool { 311 | return !strings.Contains(l, " ") && len(l) != 0 && !strings.Contains(l, "#") 312 | } 313 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## GoCQRS-All-In-One: meta-collection of CQRS examples in GO 2 | 3 | A handy reference of common idioms and patterns how to implement CQRS / ES in GO. 4 | The main purpose is reading / learning / teaching. 5 | 6 | ### Background 7 | - Making Badass Developers - Kathy Sierra (Serious Pony) - https://www.youtube.com/watch?v=FKTxC9pl-WM 8 | - `It isn’t about what skills you have but how quickly you learn.` 9 | 10 | ### Setup 11 | 12 | $ make run 13 | 14 | ### Update Readme with current stats 15 | 16 | $ make crawl 17 | 18 | ### Navigation 19 | 20 | - [By Size](#by-size) 21 | - [By Activity](#by-activity) 22 | 23 | ### Projects 24 | 25 | - [altairsix/eventsource](https://github.com/altairsix/eventsource) - Serverless Go event sourcing library built on top of dynamodb
( 2017-08-15 / 55 commits / 15 stars ) 26 | - [andrewwebber/cqrs](https://github.com/andrewwebber/cqrs) - cqrs framework in go
( 2017-08-29 / 73 commits / 14 stars ) 27 | - [andrewwebber/cqrs-scaleout](https://github.com/andrewwebber/cqrs-scaleout) - CQRS multi worker example
( 2015-06-02 / 8 commits / 0 stars ) 28 | - [atitsbest/go_cqrs](https://github.com/atitsbest/go_cqrs) - CQRS Test in Go
( 2014-06-06 / 18 commits / 1 stars ) 29 | - [berkaroad/ddd](https://github.com/berkaroad/ddd) - Domain Driven Design by golang
( 2015-12-20 / 2 commits / 0 stars ) 30 | - [berkaroad/ioc](https://github.com/berkaroad/ioc) - Inversion of Control (IoC)
( 2016-08-31 / 32 commits / 1 stars ) 31 | - [botchniaque/eventsourcing-cqrs-go](https://github.com/botchniaque/eventsourcing-cqrs-go) - Example event sourcing and CQRS implementation in golang
( 2016-02-26 / 25 commits / 5 stars ) 32 | - [cloudnativego/drones-cmds](https://github.com/cloudnativego/drones-cmds) - Command Handler Service for Drone Army Sample
( 2016-05-23 / 45 commits / 3 stars ) 33 | - [cloudnativego/drones-events](https://github.com/cloudnativego/drones-events) - Event Processing Microservice for the Drones Sample
( 2016-05-24 / 20 commits / 2 stars ) 34 | - [cloudnativego/drones-query](https://github.com/cloudnativego/drones-query) - Implementation of the Query portion of CQRS for the drones sample
( 2016-05-24 / 13 commits / 2 stars ) 35 | - [customerio/esdb](https://github.com/customerio/esdb) - Event-stream flat file database - Immutable storage for timestamped event streams
( 2017-09-15 / 154 commits / 4 stars ) 36 | - [dc0d/sector](https://github.com/dc0d/sector) - Simple Injector; Dependency Injection
( 2017-03-06 / 6 commits / 3 stars ) 37 | - [diegogub/esgo](https://github.com/diegogub/esgo) - Eventstoring generic driver
( 2016-07-15 / 6 commits / 0 stars ) 38 | - [diegogub/gocqrs](https://github.com/diegogub/gocqrs) - CQRS bootstrap framework for Go. Basic CRUD events already included.
( 2017-10-03 / 24 commits / 2 stars ) 39 | - [duskhacker/cqrsnu](https://github.com/duskhacker/cqrsnu) - ---
( 2017-04-23 / 27 commits / 0 stars ) 40 | - [egonelbre/guestlist](https://github.com/egonelbre/guestlist) - Go CQRS/ES application reference
( 2016-05-10 / 7 commits / 2 stars ) 41 | - [eventsourcedb/eventsourcedb](https://github.com/eventsourcedb/eventsourcedb) - EventSourcing storage made easy
( 2016-05-19 / 19 commits / 1 stars ) 42 | - [f2prateek/coi](https://github.com/f2prateek/coi) - ---
( 2016-04-21 / 20 commits / 1 stars ) 43 | - [hellofresh/goengine](https://github.com/hellofresh/goengine) - Engine provides you all the capabilities to build an Event sourced application in go
( 2017-06-26 / 49 commits / 4 stars ) 44 | - [isuruceanu/gocqrs](https://github.com/isuruceanu/gocqrs) - Golang implementation of CQRS architectural patern with Event Sourcing
( 2016-06-29 / 6 commits / 0 stars ) 45 | - [jensrantil/gorewind](https://github.com/jensrantil/gorewind) - This is a port of Rewind to the Go programming language.
( 2015-10-20 / 160 commits / 1 stars ) 46 | - [jetbasrawi/go.geteventstore](https://github.com/jetbasrawi/go.geteventstore) - A Go Client for EventStore HTTP API
( 2017-08-13 / 103 commits / 9 stars ) 47 | - [jetbasrawi/go.geteventstore.testfeed](https://github.com/jetbasrawi/go.geteventstore.testfeed) - A mock handler simulating GetEventStore Atom feeds for event streams.
( 2016-08-08 / 1 commits / 0 stars ) 48 | - [jostly/cqrs-bookstore-go](https://github.com/jostly/cqrs-bookstore-go) - ---
( 2014-12-13 / 3 commits / 0 stars ) 49 | - [looplab/eventhorizon](https://github.com/looplab/eventhorizon) - CQRS/ES toolkit for Go
( 2018-02-08 / 355 commits / 70 stars ) 50 | - [mbucc/cqrs](https://github.com/mbucc/cqrs) - A golang starter kit for working with CQRS. http://cqrs.nu/
( 2015-07-19 / 176 commits / 1 stars ) 51 | - [mcveat/event-sourcing-cqrs](https://github.com/mcveat/event-sourcing-cqrs) - Example of Event Sourcing and CQRS in golang
( 2016-02-05 / 29 commits / 0 stars ) 52 | - [mishudark/eventhus](https://github.com/mishudark/eventhus) - Go - CQRS / Event Sourcing made easy - Go
( 2017-12-27 / 89 commits / 10 stars ) 53 | - [moul/cleanarch](https://github.com/moul/cleanarch) - :shower: the clean architecture, optimised for Golang
( 2016-09-21 / 60 commits / 0 stars ) 54 | - [nicdex/goes](https://github.com/nicdex/goes) - GoLang implementation of simple EventStore
( 2017-02-12 / 34 commits / 2 stars ) 55 | - [pjvds/go-cqrs](https://github.com/pjvds/go-cqrs) - Example of CQRS on domain level in Go
( 2015-04-28 / 159 commits / 9 stars ) 56 | - [robertreppel/hist](https://github.com/robertreppel/hist) - A simple event store for event sourcing in Go.
( 2017-04-12 / 47 commits / 1 stars ) 57 | - [rogerclotet/cqrs](https://github.com/rogerclotet/cqrs) - Basic CQRS implementation in go
( 2016-08-16 / 8 commits / 1 stars ) 58 | - [rogerclotet/graceful-restart](https://github.com/rogerclotet/graceful-restart) - This is an effort to show a way of doing live code deployment with 0 downtime in a CQRS environment
( 2016-08-16 / 15 commits / 0 stars ) 59 | - [saem/afterme](https://github.com/saem/afterme) - ---
( 2014-01-14 / 28 commits / 1 stars ) 60 | - [sclasen/swfsm](https://github.com/sclasen/swfsm) - [golang] simple workflow finite state machines
( 2017-04-25 / 512 commits / 14 stars ) 61 | - [sunrongya/eventsourcing](https://github.com/sunrongya/eventsourcing) - cqrs+eventsourcing
( 2017-01-05 / 11 commits / 0 stars ) 62 | - [sunrongya/milife](https://github.com/sunrongya/milife) - 商品交易项目,演示DDD+TDD+CQRS+Event Sourcing技术
( 2017-01-05 / 12 commits / 1 stars ) 63 | - [thebookofeveryone/cqrs](https://github.com/thebookofeveryone/cqrs) - CQRS Example
( 2016-01-12 / 34 commits / 2 stars ) 64 | - [uber-go/dig](https://github.com/uber-go/dig) - A reflection based dependency injection toolkit for Go.
( 2017-12-27 / 165 commits / 7 stars ) 65 | 66 | 67 | ### By Activity 68 | 69 | - [looplab/eventhorizon](https://github.com/looplab/eventhorizon): 2018-02-08
CQRS/ES toolkit for Go 70 | - [uber-go/dig](https://github.com/uber-go/dig): 2017-12-27
A reflection based dependency injection toolkit for Go. 71 | - [mishudark/eventhus](https://github.com/mishudark/eventhus): 2017-12-27
Go - CQRS / Event Sourcing made easy - Go 72 | - [diegogub/gocqrs](https://github.com/diegogub/gocqrs): 2017-10-03
CQRS bootstrap framework for Go. Basic CRUD events already included. 73 | - [customerio/esdb](https://github.com/customerio/esdb): 2017-09-15
Event-stream flat file database - Immutable storage for timestamped event streams 74 | - [andrewwebber/cqrs](https://github.com/andrewwebber/cqrs): 2017-08-29
cqrs framework in go 75 | - [altairsix/eventsource](https://github.com/altairsix/eventsource): 2017-08-15
Serverless Go event sourcing library built on top of dynamodb 76 | - [jetbasrawi/go.geteventstore](https://github.com/jetbasrawi/go.geteventstore): 2017-08-13
A Go Client for EventStore HTTP API 77 | - [hellofresh/goengine](https://github.com/hellofresh/goengine): 2017-06-26
Engine provides you all the capabilities to build an Event sourced application in go 78 | - [sclasen/swfsm](https://github.com/sclasen/swfsm): 2017-04-25
[golang] simple workflow finite state machines 79 | - [duskhacker/cqrsnu](https://github.com/duskhacker/cqrsnu): 2017-04-23
--- 80 | - [robertreppel/hist](https://github.com/robertreppel/hist): 2017-04-12
A simple event store for event sourcing in Go. 81 | - [dc0d/sector](https://github.com/dc0d/sector): 2017-03-06
Simple Injector; Dependency Injection 82 | - [nicdex/goes](https://github.com/nicdex/goes): 2017-02-12
GoLang implementation of simple EventStore 83 | - [sunrongya/milife](https://github.com/sunrongya/milife): 2017-01-05
商品交易项目,演示DDD+TDD+CQRS+Event Sourcing技术 84 | - [sunrongya/eventsourcing](https://github.com/sunrongya/eventsourcing): 2017-01-05
cqrs+eventsourcing 85 | - [moul/cleanarch](https://github.com/moul/cleanarch): 2016-09-21
:shower: the clean architecture, optimised for Golang 86 | - [berkaroad/ioc](https://github.com/berkaroad/ioc): 2016-08-31
Inversion of Control (IoC) 87 | - [rogerclotet/cqrs](https://github.com/rogerclotet/cqrs): 2016-08-16
Basic CQRS implementation in go 88 | - [rogerclotet/graceful-restart](https://github.com/rogerclotet/graceful-restart): 2016-08-16
This is an effort to show a way of doing live code deployment with 0 downtime in a CQRS environment 89 | - [jetbasrawi/go.geteventstore.testfeed](https://github.com/jetbasrawi/go.geteventstore.testfeed): 2016-08-08
A mock handler simulating GetEventStore Atom feeds for event streams. 90 | - [diegogub/esgo](https://github.com/diegogub/esgo): 2016-07-15
Eventstoring generic driver 91 | - [isuruceanu/gocqrs](https://github.com/isuruceanu/gocqrs): 2016-06-29
Golang implementation of CQRS architectural patern with Event Sourcing 92 | - [cloudnativego/drones-query](https://github.com/cloudnativego/drones-query): 2016-05-24
Implementation of the Query portion of CQRS for the drones sample 93 | - [cloudnativego/drones-events](https://github.com/cloudnativego/drones-events): 2016-05-24
Event Processing Microservice for the Drones Sample 94 | - [cloudnativego/drones-cmds](https://github.com/cloudnativego/drones-cmds): 2016-05-23
Command Handler Service for Drone Army Sample 95 | - [eventsourcedb/eventsourcedb](https://github.com/eventsourcedb/eventsourcedb): 2016-05-19
EventSourcing storage made easy 96 | - [egonelbre/guestlist](https://github.com/egonelbre/guestlist): 2016-05-10
Go CQRS/ES application reference 97 | - [f2prateek/coi](https://github.com/f2prateek/coi): 2016-04-21
--- 98 | - [botchniaque/eventsourcing-cqrs-go](https://github.com/botchniaque/eventsourcing-cqrs-go): 2016-02-26
Example event sourcing and CQRS implementation in golang 99 | - [mcveat/event-sourcing-cqrs](https://github.com/mcveat/event-sourcing-cqrs): 2016-02-05
Example of Event Sourcing and CQRS in golang 100 | - [thebookofeveryone/cqrs](https://github.com/thebookofeveryone/cqrs): 2016-01-12
CQRS Example 101 | - [berkaroad/ddd](https://github.com/berkaroad/ddd): 2015-12-20
Domain Driven Design by golang 102 | - [jensrantil/gorewind](https://github.com/jensrantil/gorewind): 2015-10-20
This is a port of Rewind to the Go programming language. 103 | - [mbucc/cqrs](https://github.com/mbucc/cqrs): 2015-07-19
A golang starter kit for working with CQRS. http://cqrs.nu/ 104 | - [andrewwebber/cqrs-scaleout](https://github.com/andrewwebber/cqrs-scaleout): 2015-06-02
CQRS multi worker example 105 | - [pjvds/go-cqrs](https://github.com/pjvds/go-cqrs): 2015-04-28
Example of CQRS on domain level in Go 106 | - [jostly/cqrs-bookstore-go](https://github.com/jostly/cqrs-bookstore-go): 2014-12-13
--- 107 | - [atitsbest/go_cqrs](https://github.com/atitsbest/go_cqrs): 2014-06-06
CQRS Test in Go 108 | - [saem/afterme](https://github.com/saem/afterme): 2014-01-14
--- 109 | 110 | 111 | ### By size 112 | 113 | - [customerio/esdb](https://github.com/customerio/esdb): 92.35 MB
(13.13 MB git / 79.22 MB code) 114 | - [diegogub/gocqrs](https://github.com/diegogub/gocqrs): 6.46 MB
(1.18 MB git / 5.28 MB code) 115 | - [moul/cleanarch](https://github.com/moul/cleanarch): 3.84 MB
(1.87 MB git / 1.97 MB code) 116 | - [sclasen/swfsm](https://github.com/sclasen/swfsm): 3.69 MB
(1.59 MB git / 2.10 MB code) 117 | - [cloudnativego/drones-query](https://github.com/cloudnativego/drones-query): 3.39 MB
(3.38 MB git / 0.01 MB code) 118 | - [jetbasrawi/go.geteventstore](https://github.com/jetbasrawi/go.geteventstore): 3.36 MB
(3.26 MB git / 0.10 MB code) 119 | - [xtracdev/es-atom-pub](https://github.com/xtracdev/es-atom-pub): 3.05 MB
(2.98 MB git / 0.07 MB code) 120 | - [xozrc/cqrs](https://github.com/xozrc/cqrs): 2.75 MB
(2.71 MB git / 0.05 MB code) 121 | - [duskhacker/cqrsnu](https://github.com/duskhacker/cqrsnu): 2.64 MB
(0.62 MB git / 2.02 MB code) 122 | - [looplab/eventhorizon](https://github.com/looplab/eventhorizon): 2.35 MB
(1.22 MB git / 1.13 MB code) 123 | - [robertreppel/hist](https://github.com/robertreppel/hist): 1.89 MB
(1.85 MB git / 0.04 MB code) 124 | - [vizidrix/eventstore](https://github.com/vizidrix/eventstore): 1.76 MB
(1.47 MB git / 0.28 MB code) 125 | - [xtracdev/goes](https://github.com/xtracdev/goes): 1.24 MB
(1.18 MB git / 0.06 MB code) 126 | - [uber-go/dig](https://github.com/uber-go/dig): 0.55 MB
(0.37 MB git / 0.18 MB code) 127 | - [mbucc/cqrs](https://github.com/mbucc/cqrs): 0.33 MB
(0.29 MB git / 0.05 MB code) 128 | - [rogerclotet/graceful-restart](https://github.com/rogerclotet/graceful-restart): 0.31 MB
(0.09 MB git / 0.22 MB code) 129 | - [andrewwebber/cqrs](https://github.com/andrewwebber/cqrs): 0.28 MB
(0.15 MB git / 0.13 MB code) 130 | - [cloudnativego/drones-events](https://github.com/cloudnativego/drones-events): 0.28 MB
(0.25 MB git / 0.03 MB code) 131 | - [jensrantil/gorewind](https://github.com/jensrantil/gorewind): 0.24 MB
(0.15 MB git / 0.09 MB code) 132 | - [altairsix/eventsource](https://github.com/altairsix/eventsource): 0.23 MB
(0.11 MB git / 0.12 MB code) 133 | - [cloudnativego/drones-cmds](https://github.com/cloudnativego/drones-cmds): 0.20 MB
(0.17 MB git / 0.03 MB code) 134 | - [pjvds/go-cqrs](https://github.com/pjvds/go-cqrs): 0.19 MB
(0.14 MB git / 0.05 MB code) 135 | - [sunrongya/milife](https://github.com/sunrongya/milife): 0.18 MB
(0.07 MB git / 0.11 MB code) 136 | - [vizidrix/gocqrs](https://github.com/vizidrix/gocqrs): 0.17 MB
(0.14 MB git / 0.03 MB code) 137 | - [rogerclotet/cqrs](https://github.com/rogerclotet/cqrs): 0.14 MB
(0.10 MB git / 0.05 MB code) 138 | - [mishudark/eventhus](https://github.com/mishudark/eventhus): 0.13 MB
(0.09 MB git / 0.04 MB code) 139 | - [hellofresh/goengine](https://github.com/hellofresh/goengine): 0.13 MB
(0.09 MB git / 0.04 MB code) 140 | - [saem/afterme](https://github.com/saem/afterme): 0.12 MB
(0.07 MB git / 0.06 MB code) 141 | - [xtracdev/es-atom-data](https://github.com/xtracdev/es-atom-data): 0.12 MB
(0.07 MB git / 0.05 MB code) 142 | - [sunrongya/eventsourcing](https://github.com/sunrongya/eventsourcing): 0.12 MB
(0.05 MB git / 0.07 MB code) 143 | - [xtracdev/orapub](https://github.com/xtracdev/orapub): 0.11 MB
(0.08 MB git / 0.03 MB code) 144 | - [nicdex/goes](https://github.com/nicdex/goes): 0.10 MB
(0.06 MB git / 0.04 MB code) 145 | - [eventsourcedb/eventsourcedb](https://github.com/eventsourcedb/eventsourcedb): 0.09 MB
(0.06 MB git / 0.03 MB code) 146 | - [xtracdev/oraeventstore](https://github.com/xtracdev/oraeventstore): 0.09 MB
(0.06 MB git / 0.03 MB code) 147 | - [xozrc/eventsourcing](https://github.com/xozrc/eventsourcing): 0.09 MB
(0.05 MB git / 0.04 MB code) 148 | - [mcveat/event-sourcing-cqrs](https://github.com/mcveat/event-sourcing-cqrs): 0.09 MB
(0.06 MB git / 0.03 MB code) 149 | - [botchniaque/eventsourcing-cqrs-go](https://github.com/botchniaque/eventsourcing-cqrs-go): 0.09 MB
(0.06 MB git / 0.03 MB code) 150 | - [xtraclabs/appreg](https://github.com/xtraclabs/appreg): 0.08 MB
(0.04 MB git / 0.04 MB code) 151 | - [jetbasrawi/go.geteventstore.testfeed](https://github.com/jetbasrawi/go.geteventstore.testfeed): 0.08 MB
(0.03 MB git / 0.05 MB code) 152 | - [berkaroad/ioc](https://github.com/berkaroad/ioc): 0.07 MB
(0.06 MB git / 0.02 MB code) 153 | - [yuukanoo/go-toolbelt](https://github.com/yuukanoo/go-toolbelt): 0.07 MB
(0.05 MB git / 0.02 MB code) 154 | - [atitsbest/go_cqrs](https://github.com/atitsbest/go_cqrs): 0.06 MB
(0.04 MB git / 0.02 MB code) 155 | - [egonelbre/guestlist](https://github.com/egonelbre/guestlist): 0.06 MB
(0.04 MB git / 0.02 MB code) 156 | - [f2prateek/coi](https://github.com/f2prateek/coi): 0.06 MB
(0.05 MB git / 0.01 MB code) 157 | - [xtracdev/es-data-pub](https://github.com/xtracdev/es-data-pub): 0.05 MB
(0.04 MB git / 0.02 MB code) 158 | - [diegogub/esgo](https://github.com/diegogub/esgo): 0.05 MB
(0.04 MB git / 0.01 MB code) 159 | - [jostly/cqrs-bookstore-go](https://github.com/jostly/cqrs-bookstore-go): 0.05 MB
(0.03 MB git / 0.02 MB code) 160 | - [thebookofeveryone/cqrs](https://github.com/thebookofeveryone/cqrs): 0.05 MB
(0.04 MB git / 0.01 MB code) 161 | - [andrewwebber/cqrs-scaleout](https://github.com/andrewwebber/cqrs-scaleout): 0.05 MB
(0.04 MB git / 0.01 MB code) 162 | - [dc0d/sector](https://github.com/dc0d/sector): 0.04 MB
(0.03 MB git / 0.01 MB code) 163 | - [berkaroad/ddd](https://github.com/berkaroad/ddd): 0.04 MB
(0.03 MB git / 0.01 MB code) 164 | - [isuruceanu/gocqrs](https://github.com/isuruceanu/gocqrs): 0.03 MB
(0.02 MB git / 0.00 MB code) 165 | 166 | --------------------------------------------------------------------------------