├── 10-profiling
├── cmd
│ └── beers-cli
│ │ ├── beers.cpu.prof
│ │ ├── beers.mem.prof
│ │ └── main.go
├── internal
│ ├── storage
│ │ ├── ontario
│ │ │ ├── repository_test.go
│ │ │ ├── bench.new
│ │ │ ├── bench.old
│ │ │ └── repository.go
│ │ ├── inmem
│ │ │ └── repository.go
│ │ ├── csv
│ │ │ └── repository.go
│ │ └── mock
│ │ │ └── repository.go
│ ├── errors
│ │ └── errortypes.go
│ ├── fetching
│ │ ├── service.go
│ │ └── service_test.go
│ ├── cli
│ │ └── beers.go
│ ├── mock
│ │ └── repository.go
│ └── beer.go
└── data
│ └── beers.csv
├── 11-sharing_memory_concurrency
├── cmd
│ └── beers-cli
│ │ ├── beers.cpu.prof
│ │ ├── beers.mem.prof
│ │ └── main.go
├── internal
│ ├── storage
│ │ ├── ontario
│ │ │ ├── repository_test.go
│ │ │ ├── bench.new
│ │ │ ├── bench.old
│ │ │ └── repository.go
│ │ ├── inmem
│ │ │ └── repository.go
│ │ ├── csv
│ │ │ └── repository.go
│ │ └── mock
│ │ │ └── repository.go
│ ├── errors
│ │ └── errortypes.go
│ ├── cli
│ │ └── beers.go
│ ├── fetching
│ │ ├── service.go
│ │ └── service_test.go
│ ├── mock
│ │ └── repository.go
│ └── beer.go
└── data
│ └── beers.csv
├── .github
└── dependabot.yml
├── 09-benchmarking
├── internal
│ ├── storage
│ │ ├── ontario
│ │ │ ├── repository_test.go
│ │ │ ├── bench.new
│ │ │ ├── bench.old
│ │ │ └── repository.go
│ │ ├── inmem
│ │ │ └── repository.go
│ │ ├── csv
│ │ │ └── repository.go
│ │ └── mock
│ │ │ └── repository.go
│ ├── errors
│ │ └── errortypes.go
│ ├── fetching
│ │ ├── service.go
│ │ └── service_test.go
│ ├── cli
│ │ └── beers.go
│ ├── mock
│ │ └── repository.go
│ └── beer.go
├── data
│ └── beers.csv
└── cmd
│ └── beers-cli
│ └── main.go
├── 03-reading_files
├── internal
│ ├── beer.go
│ └── cli
│ │ └── beers.go
├── cmd
│ └── beers-cli
│ │ └── main.go
└── data
│ └── beers.csv
├── 06-error_handling
├── internal
│ ├── errors
│ │ └── errortypes.go
│ ├── storage
│ │ ├── csv
│ │ │ └── repository.go
│ │ └── ontario
│ │ │ └── repository.go
│ ├── cli
│ │ └── beers.go
│ └── beer.go
├── data
│ └── beers.csv
└── cmd
│ └── beers-cli
│ └── main.go
├── 02-refactor-to-cobra
├── cmd
│ └── beers-cli
│ │ └── main.go
└── internal
│ └── cli
│ └── beers.go
├── go.mod
├── mock
└── product.imp.json
├── ontario-mock
└── product.imp.json
├── 04-modeling_data
├── data
│ └── beers.csv
├── cmd
│ └── beers-cli
│ │ └── main.go
└── internal
│ ├── cli
│ └── beers.go
│ ├── storage
│ └── csv
│ │ └── repository.go
│ └── beer.go
├── 08-automated_tests
├── data
│ └── beers.csv
├── internal
│ ├── storage
│ │ ├── inmem
│ │ │ └── repository.go
│ │ ├── csv
│ │ │ └── repository.go
│ │ ├── ontario
│ │ │ └── repository.go
│ │ └── mock
│ │ │ └── repository.go
│ ├── errors
│ │ └── errortypes.go
│ ├── fetching
│ │ ├── service.go
│ │ └── service_test.go
│ ├── cli
│ │ └── beers.go
│ └── beer.go
└── cmd
│ └── beers-cli
│ └── main.go
├── 05-parsing_http_response
├── data
│ └── beers.csv
├── cmd
│ └── beers-cli
│ │ └── main.go
└── internal
│ ├── storage
│ ├── ontario
│ │ └── repository.go
│ └── csv
│ │ └── repository.go
│ ├── cli
│ └── beers.go
│ └── beer.go
├── 07-behaviour_error_handling
├── data
│ └── beers.csv
├── cmd
│ └── beers-cli
│ │ └── main.go
└── internal
│ ├── errors
│ └── errortypes.go
│ ├── storage
│ ├── csv
│ │ └── repository.go
│ └── ontario
│ │ └── repository.go
│ ├── cli
│ └── beers.go
│ └── beer.go
├── 01-go_flags
└── main.go
├── README.md
└── go.sum
/10-profiling/cmd/beers-cli/beers.cpu.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piraces/golang-examples/master/10-profiling/cmd/beers-cli/beers.cpu.prof
--------------------------------------------------------------------------------
/10-profiling/cmd/beers-cli/beers.mem.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piraces/golang-examples/master/10-profiling/cmd/beers-cli/beers.mem.prof
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/cmd/beers-cli/beers.cpu.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piraces/golang-examples/master/11-sharing_memory_concurrency/cmd/beers-cli/beers.cpu.prof
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/cmd/beers-cli/beers.mem.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piraces/golang-examples/master/11-sharing_memory_concurrency/cmd/beers-cli/beers.mem.prof
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gomod
4 | directory: "/"
5 | schedule:
6 | interval: weekly
7 | time: "08:00"
8 | timezone: Europe/Madrid
9 | open-pull-requests-limit: 2
10 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/ontario/repository_test.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import "testing"
4 |
5 | func BenchmarkGetBeers(b *testing.B) {
6 | repo := NewOntarioRepository()
7 | b.ResetTimer()
8 | for n := 0; n < b.N; n++ {
9 | repo.GetBeers()
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/ontario/repository_test.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import "testing"
4 |
5 | func BenchmarkGetBeers(b *testing.B) {
6 | repo := NewOntarioRepository()
7 | b.ResetTimer()
8 | for n := 0; n < b.N; n++ {
9 | repo.GetBeers()
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/ontario/repository_test.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import "testing"
4 |
5 | func BenchmarkGetBeers(b *testing.B) {
6 | repo := NewOntarioRepository()
7 | b.ResetTimer()
8 | for n := 0; n < b.N; n++ {
9 | repo.GetBeers()
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/03-reading_files/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | // Beer representation of beer into data struct
4 | type Beer struct {
5 | ProductID int
6 | Name string
7 | Price float64
8 | Category string
9 | Type string
10 | Brewer string
11 | Country string
12 | }
13 |
--------------------------------------------------------------------------------
/06-error_handling/internal/errors/errortypes.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import "fmt"
4 |
5 | type BadResponseErr struct {
6 | Msg string
7 | File string
8 | Line int
9 | }
10 |
11 | func (e *BadResponseErr) Error() string {
12 | return fmt.Sprintf("%s: %d: %s", e.File, e.Line, e.Msg)
13 | }
14 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/ontario/bench.new:
--------------------------------------------------------------------------------
1 | goos: darwin
2 | goarch: amd64
3 | pkg: github.com/CodelyTV/golang-examples/10-profiling/internal/storage/ontario
4 | BenchmarkGetBeers-8 200 8124287 ns/op
5 | PASS
6 | ok github.com/CodelyTV/golang-examples/10-profiling/internal/storage/ontario 2.476s
7 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/ontario/bench.old:
--------------------------------------------------------------------------------
1 | goos: darwin
2 | goarch: amd64
3 | pkg: github.com/CodelyTV/golang-examples/10-profiling/internal/storage/ontario
4 | BenchmarkGetBeers-8 50 25692443 ns/op
5 | PASS
6 | ok github.com/CodelyTV/golang-examples/10-profiling/internal/storage/ontario 1.333s
7 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/ontario/bench.new:
--------------------------------------------------------------------------------
1 | goos: darwin
2 | goarch: amd64
3 | pkg: github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/ontario
4 | BenchmarkGetBeers-8 200 8124287 ns/op
5 | PASS
6 | ok github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/ontario 2.476s
7 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/ontario/bench.old:
--------------------------------------------------------------------------------
1 | goos: darwin
2 | goarch: amd64
3 | pkg: github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/ontario
4 | BenchmarkGetBeers-8 50 25692443 ns/op
5 | PASS
6 | ok github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/ontario 1.333s
7 |
--------------------------------------------------------------------------------
/03-reading_files/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/CodelyTV/golang-examples/03-reading_files/internal/cli"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func main() {
9 | rootCmd := &cobra.Command{Use: "beers-cli"}
10 | rootCmd.AddCommand(cli.InitBeersCmd())
11 | rootCmd.Execute()
12 | }
13 |
--------------------------------------------------------------------------------
/02-refactor-to-cobra/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/CodelyTV/golang-examples/02-refactor-to-cobra/internal/cli"
5 | "github.com/spf13/cobra"
6 | )
7 |
8 | func main() {
9 | rootCmd := &cobra.Command{Use: "beers-cli"}
10 | rootCmd.AddCommand(cli.InitBeersCmd())
11 | rootCmd.Execute()
12 | }
13 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/ontario/bench.new:
--------------------------------------------------------------------------------
1 | goos: darwin
2 | goarch: amd64
3 | pkg: github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/ontario
4 | BenchmarkGetBeers-8 200 8124287 ns/op
5 | PASS
6 | ok github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/ontario 2.476s
7 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/ontario/bench.old:
--------------------------------------------------------------------------------
1 | goos: darwin
2 | goarch: amd64
3 | pkg: github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/ontario
4 | BenchmarkGetBeers-8 50 25692443 ns/op
5 | PASS
6 | ok github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/ontario 1.333s
7 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/CodelyTV/golang-examples
2 |
3 | go 1.12
4 |
5 | require (
6 | github.com/json-iterator/go v1.1.11
7 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
8 | github.com/modern-go/reflect2 v1.0.1 // indirect
9 | github.com/pkg/errors v0.9.1
10 | github.com/spf13/cobra v0.0.7
11 | github.com/stretchr/testify v1.7.0
12 | )
13 |
--------------------------------------------------------------------------------
/mock/product.imp.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "request": {
4 | "method": "GET",
5 | "endpoint": "/products"
6 | },
7 | "response": {
8 | "status": 200,
9 | "headers": {
10 | "Content-Type": "application/json"
11 | },
12 | "bodyFile": "responses/products.json"
13 | }
14 | }
15 | ]
--------------------------------------------------------------------------------
/ontario-mock/product.imp.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "request": {
4 | "method": "GET",
5 | "endpoint": "/products"
6 | },
7 | "response": {
8 | "status": 200,
9 | "headers": {
10 | "Content-Type": "application/json"
11 | },
12 | "bodyFile": "product_response.json"
13 | }
14 | }
15 | ]
16 |
--------------------------------------------------------------------------------
/04-modeling_data/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/09-benchmarking/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/10-profiling/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/03-reading_files/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Larger,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Larger,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Larger,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/06-error_handling/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/08-automated_tests/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/04-modeling_data/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/CodelyTV/golang-examples/04-modeling_data/internal/cli"
5 | "github.com/CodelyTV/golang-examples/04-modeling_data/internal/storage/csv"
6 | "github.com/spf13/cobra"
7 | )
8 |
9 | func main() {
10 |
11 | csvRepo := csv.NewRepository()
12 |
13 | rootCmd := &cobra.Command{Use: "beers-cli"}
14 | rootCmd.AddCommand(cli.InitBeersCmd(csvRepo))
15 | rootCmd.Execute()
16 | }
17 |
--------------------------------------------------------------------------------
/05-parsing_http_response/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/data/beers.csv:
--------------------------------------------------------------------------------
1 | 127,Mad Jack Mixer,Domestic Specialty,23.95,Lager,Molson,Canada
2 | 128,Mad Jack Hard Root Beer,Domestic Specialty,15.25,Lager,Molson,Canada
3 | 131,Keystone Ice,Value,49.65,Lager,Molson,Canada
4 | 133,Mad Jack,Domestic Specialty,15.25,Malt,Molson,Canada
5 | 8431,Lake Wilcox Bandit Apa,Ontario Craft,63.60,Ale,Lake Wilcox Brewing,Canada
6 | 8520130,Grolsch 0.0,Non-Alcoholic Beer,49.50,Non-Alcoholic Beer,Grolsch Export B.V.,Canada
7 |
--------------------------------------------------------------------------------
/01-go_flags/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "log"
7 | "os"
8 | )
9 |
10 | var beers = map[string]string{
11 | "01D9X58E7NPXX5MVCR9QN794CH": "Mad Jack Mixer",
12 | "01D9X5BQ5X48XMMVZ2F2G3R5MS": "Keystone Ice",
13 | "01D9X5CVS1M9VR5ZD627XDF6ND": "Belgian Moon",
14 | }
15 |
16 | func main() {
17 |
18 | beersCmd := flag.NewFlagSet("beers", flag.ExitOnError)
19 | flag.Parse()
20 |
21 | if flag.NArg() == 0 {
22 | log.Fatal("You must specified a command beers")
23 | os.Exit(2)
24 | }
25 |
26 | switch flag.Arg(0) {
27 | case "beers":
28 | ID := beersCmd.String("id", "", "find by ID")
29 | beersCmd.Parse(os.Args[2:])
30 |
31 | if *ID != "" {
32 | fmt.Println(beers[*ID])
33 | } else {
34 | fmt.Println(beers)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/06-error_handling/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | "github.com/CodelyTV/golang-examples/06-error_handling/internal/storage/ontario"
7 |
8 | beerscli "github.com/CodelyTV/golang-examples/06-error_handling/internal"
9 | "github.com/CodelyTV/golang-examples/06-error_handling/internal/cli"
10 | "github.com/CodelyTV/golang-examples/06-error_handling/internal/storage/csv"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | func main() {
15 |
16 | csvData := flag.Bool("csv", false, "load data from csv")
17 | flag.Parse()
18 | var repo beerscli.BeerRepo
19 | repo = csv.NewRepository()
20 |
21 | if !*csvData {
22 | repo = ontario.NewOntarioRepository()
23 | }
24 |
25 | rootCmd := &cobra.Command{Use: "beers-cli"}
26 | rootCmd.AddCommand(cli.InitBeersCmd(repo))
27 | rootCmd.Execute()
28 | }
29 |
--------------------------------------------------------------------------------
/05-parsing_http_response/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal/storage/ontario"
7 |
8 | beerscli "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal"
9 | "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal/cli"
10 | "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal/storage/csv"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | func main() {
15 |
16 | csvData := flag.Bool("csv", false, "load data from csv")
17 | flag.Parse()
18 |
19 | var repo beerscli.BeerRepo
20 | repo = csv.NewRepository()
21 |
22 | if !*csvData {
23 | repo = ontario.NewOntarioRepository()
24 | }
25 |
26 | rootCmd := &cobra.Command{Use: "beers-cli"}
27 | rootCmd.AddCommand(cli.InitBeersCmd(repo))
28 | rootCmd.Execute()
29 | }
30 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/storage/ontario"
7 |
8 | beerscli "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal"
9 | "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/cli"
10 | "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/storage/csv"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | func main() {
15 |
16 | csvData := flag.Bool("csv", false, "load data from csv")
17 | flag.Parse()
18 | var repo beerscli.BeerRepo
19 | repo = csv.NewRepository()
20 |
21 | if !*csvData {
22 | repo = ontario.NewOntarioRepository()
23 | }
24 |
25 | rootCmd := &cobra.Command{Use: "beers-cli"}
26 | rootCmd.AddCommand(cli.InitBeersCmd(repo))
27 | rootCmd.Execute()
28 | }
29 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/inmem/repository.go:
--------------------------------------------------------------------------------
1 | package inmem
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
5 | )
6 |
7 | type repository struct {
8 | }
9 |
10 | // NewRepository initialize csv repository
11 | func NewRepository() beerscli.BeerRepo {
12 | return &repository{}
13 | }
14 |
15 | // GetBeers fetch beers data from memory
16 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
17 | return []beerscli.Beer{
18 | beerscli.NewBeer(
19 | 127,
20 | "Mad Jack Mixer",
21 | "Domestic Specialty",
22 | "Molson",
23 | "Canada",
24 | "23.95",
25 | beerscli.NewBeerType("Lager"),
26 | ),
27 | beerscli.NewBeer(
28 | 8520130,
29 | "Grolsch 0.0",
30 | "Non-Alcoholic Beer",
31 | "Grolsch Export B.V.",
32 | "Canada",
33 | "49.50",
34 | beerscli.NewBeerType("Non-Alcoholic Beer"),
35 | ),
36 | }, nil
37 | }
38 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/inmem/repository.go:
--------------------------------------------------------------------------------
1 | package inmem
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
5 | )
6 |
7 | type repository struct {
8 | }
9 |
10 | // NewRepository initialize csv repository
11 | func NewRepository() beerscli.BeerRepo {
12 | return &repository{}
13 | }
14 |
15 | // GetBeers fetch beers data from memory
16 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
17 | return []beerscli.Beer{
18 | beerscli.NewBeer(
19 | 127,
20 | "Mad Jack Mixer",
21 | "Domestic Specialty",
22 | "Molson",
23 | "Canada",
24 | "23.95",
25 | beerscli.NewBeerType("Lager"),
26 | ),
27 | beerscli.NewBeer(
28 | 8520130,
29 | "Grolsch 0.0",
30 | "Non-Alcoholic Beer",
31 | "Grolsch Export B.V.",
32 | "Canada",
33 | "49.50",
34 | beerscli.NewBeerType("Non-Alcoholic Beer"),
35 | ),
36 | }, nil
37 | }
38 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/storage/inmem/repository.go:
--------------------------------------------------------------------------------
1 | package inmem
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
5 | )
6 |
7 | type repository struct {
8 | }
9 |
10 | // NewRepository initialize csv repository
11 | func NewRepository() beerscli.BeerRepo {
12 | return &repository{}
13 | }
14 |
15 | // GetBeers fetch beers data from memory
16 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
17 | return []beerscli.Beer{
18 | beerscli.NewBeer(
19 | 127,
20 | "Mad Jack Mixer",
21 | "Domestic Specialty",
22 | "Molson",
23 | "Canada",
24 | "23.95",
25 | beerscli.NewBeerType("Lager"),
26 | ),
27 | beerscli.NewBeer(
28 | 8520130,
29 | "Grolsch 0.0",
30 | "Non-Alcoholic Beer",
31 | "Grolsch Export B.V.",
32 | "Canada",
33 | "49.50",
34 | beerscli.NewBeerType("Non-Alcoholic Beer"),
35 | ),
36 | }, nil
37 | }
38 |
--------------------------------------------------------------------------------
/10-profiling/internal/errors/errortypes.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "github.com/pkg/errors"
5 | )
6 |
7 | type dataUnreacheable struct {
8 | error
9 | }
10 |
11 | // WrapDataUnreacheable returns an error which wraps err that satisfies
12 | // IsDataUnreacheable()
13 | func WrapDataUnreacheable(err error, format string, args ...interface{}) error {
14 | return &dataUnreacheable{errors.Wrapf(err, format, args...)}
15 | }
16 |
17 | // NewDataUnreacheable returns an error which satisfies IsDataUnreacheable()
18 | func NewDataUnreacheable(format string, args ...interface{}) error {
19 | return &dataUnreacheable{errors.Errorf(format, args...)}
20 | }
21 |
22 | // IsDataUnreacheable reports whether err was created with DataUnreacheablef() or
23 | // NewDataUnreacheable()
24 | func IsDataUnreacheable(err error) bool {
25 | err = errors.Cause(err)
26 | _, ok := err.(*dataUnreacheable)
27 | return ok
28 | }
29 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/errors/errortypes.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "github.com/pkg/errors"
5 | )
6 |
7 | type dataUnreacheable struct {
8 | error
9 | }
10 |
11 | // WrapDataUnreacheable returns an error which wraps err that satisfies
12 | // IsDataUnreacheable()
13 | func WrapDataUnreacheable(err error, format string, args ...interface{}) error {
14 | return &dataUnreacheable{errors.Wrapf(err, format, args...)}
15 | }
16 |
17 | // NewDataUnreacheable returns an error which satisfies IsDataUnreacheable()
18 | func NewDataUnreacheable(format string, args ...interface{}) error {
19 | return &dataUnreacheable{errors.Errorf(format, args...)}
20 | }
21 |
22 | // IsDataUnreacheable reports whether err was created with DataUnreacheablef() or
23 | // NewDataUnreacheable()
24 | func IsDataUnreacheable(err error) bool {
25 | err = errors.Cause(err)
26 | _, ok := err.(*dataUnreacheable)
27 | return ok
28 | }
29 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/errors/errortypes.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "github.com/pkg/errors"
5 | )
6 |
7 | type dataUnreacheable struct {
8 | error
9 | }
10 |
11 | // WrapDataUnreacheable returns an error which wraps err that satisfies
12 | // IsDataUnreacheable()
13 | func WrapDataUnreacheable(err error, format string, args ...interface{}) error {
14 | return &dataUnreacheable{errors.Wrapf(err, format, args...)}
15 | }
16 |
17 | // NewDataUnreacheable returns an error which satisfies IsDataUnreacheable()
18 | func NewDataUnreacheable(format string, args ...interface{}) error {
19 | return &dataUnreacheable{errors.Errorf(format, args...)}
20 | }
21 |
22 | // IsDataUnreacheable reports whether err was created with DataUnreacheablef() or
23 | // NewDataUnreacheable()
24 | func IsDataUnreacheable(err error) bool {
25 | err = errors.Cause(err)
26 | _, ok := err.(*dataUnreacheable)
27 | return ok
28 | }
29 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/internal/errors/errortypes.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "github.com/pkg/errors"
5 | )
6 |
7 | type dataUnreacheable struct {
8 | error
9 | }
10 |
11 | // WrapDataUnreacheable returns an error which wraps err that satisfies
12 | // IsDataUnreacheable()
13 | func WrapDataUnreacheable(err error, format string, args ...interface{}) error {
14 | return &dataUnreacheable{errors.Wrapf(err, format, args...)}
15 | }
16 |
17 | // NewDataUnreacheable returns an error which satisfies IsDataUnreacheable()
18 | func NewDataUnreacheable(format string, args ...interface{}) error {
19 | return &dataUnreacheable{errors.Errorf(format, args...)}
20 | }
21 |
22 | // IsDataUnreacheable reports whether err was created with DataUnreacheablef() or
23 | // NewDataUnreacheable()
24 | func IsDataUnreacheable(err error) bool {
25 | err = errors.Cause(err)
26 | _, ok := err.(*dataUnreacheable)
27 | return ok
28 | }
29 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/errors/errortypes.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "github.com/pkg/errors"
5 | )
6 |
7 | type dataUnreacheable struct {
8 | error
9 | }
10 |
11 | // WrapDataUnreacheable returns an error which wraps err that satisfies
12 | // IsDataUnreacheable()
13 | func WrapDataUnreacheable(err error, format string, args ...interface{}) error {
14 | return &dataUnreacheable{errors.Wrapf(err, format, args...)}
15 | }
16 |
17 | // NewDataUnreacheable returns an error which satisfies IsDataUnreacheable()
18 | func NewDataUnreacheable(format string, args ...interface{}) error {
19 | return &dataUnreacheable{errors.Errorf(format, args...)}
20 | }
21 |
22 | // IsDataUnreacheable reports whether err was created with DataUnreacheablef() or
23 | // NewDataUnreacheable()
24 | func IsDataUnreacheable(err error) bool {
25 | err = errors.Cause(err)
26 | _, ok := err.(*dataUnreacheable)
27 | return ok
28 | }
29 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/inmem/repository.go:
--------------------------------------------------------------------------------
1 | package inmem
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
5 | )
6 |
7 | type repository struct {
8 | }
9 |
10 | // NewRepository initialize csv repository
11 | func NewRepository() beerscli.BeerRepo {
12 | return &repository{}
13 | }
14 |
15 | // GetBeers fetch beers data from memory
16 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
17 | return []beerscli.Beer{
18 | beerscli.NewBeer(
19 | 127,
20 | "Mad Jack Mixer",
21 | "Domestic Specialty",
22 | "Molson",
23 | "Canada",
24 | "23.95",
25 | beerscli.NewBeerType("Lager"),
26 | ),
27 | beerscli.NewBeer(
28 | 8520130,
29 | "Grolsch 0.0",
30 | "Non-Alcoholic Beer",
31 | "Grolsch Export B.V.",
32 | "Canada",
33 | "49.50",
34 | beerscli.NewBeerType("Non-Alcoholic Beer"),
35 | ),
36 | }, nil
37 | }
38 |
--------------------------------------------------------------------------------
/09-benchmarking/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/fetching"
7 |
8 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/ontario"
9 |
10 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
11 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/cli"
12 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/csv"
13 | "github.com/spf13/cobra"
14 | )
15 |
16 | func main() {
17 |
18 | csvData := flag.Bool("csv", false, "load data from csv")
19 | flag.Parse()
20 | var repo beerscli.BeerRepo
21 | repo = csv.NewRepository()
22 |
23 | if !*csvData {
24 | repo = ontario.NewOntarioRepository()
25 | }
26 |
27 | fetchingService := fetching.NewService(repo)
28 |
29 | rootCmd := &cobra.Command{Use: "beers-cli"}
30 | rootCmd.AddCommand(cli.InitBeersCmd(fetchingService))
31 | rootCmd.Execute()
32 | }
33 |
--------------------------------------------------------------------------------
/08-automated_tests/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/fetching"
7 |
8 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/storage/ontario"
9 |
10 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
11 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/cli"
12 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/storage/csv"
13 | "github.com/spf13/cobra"
14 | )
15 |
16 | func main() {
17 |
18 | csvData := flag.Bool("csv", false, "load data from csv")
19 | flag.Parse()
20 | var repo beerscli.BeerRepo
21 | repo = csv.NewRepository()
22 |
23 | if !*csvData {
24 | repo = ontario.NewOntarioRepository()
25 | }
26 |
27 | fetchingService := fetching.NewService(repo)
28 |
29 | rootCmd := &cobra.Command{Use: "beers-cli"}
30 | rootCmd.AddCommand(cli.InitBeersCmd(fetchingService))
31 | rootCmd.Execute()
32 | }
33 |
--------------------------------------------------------------------------------
/05-parsing_http_response/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal"
10 | )
11 |
12 | const (
13 | productsEndpoint = "/products"
14 | ontarioURL = "http://ontariobeerapi.ca"
15 | )
16 |
17 | type beerRepo struct {
18 | url string
19 | }
20 |
21 | // NewOntarioRepository fetch beers data from csv
22 | func NewOntarioRepository() beerscli.BeerRepo {
23 | return &beerRepo{url: ontarioURL}
24 | }
25 |
26 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
27 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
28 | if err != nil {
29 | return nil, err
30 | }
31 |
32 | contents, err := ioutil.ReadAll(response.Body)
33 | if err != nil {
34 | return nil, err
35 | }
36 |
37 | err = json.Unmarshal(contents, &beers)
38 | if err != nil {
39 | return nil, err
40 | }
41 | return
42 | }
43 |
--------------------------------------------------------------------------------
/02-refactor-to-cobra/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/spf13/cobra"
7 | )
8 |
9 | // CobraFn function definion of run cobra command
10 | type CobraFn func(cmd *cobra.Command, args []string)
11 |
12 | var beers = map[string]string{
13 | "01D9X58E7NPXX5MVCR9QN794CH": "Mad Jack Mixer",
14 | "01D9X5BQ5X48XMMVZ2F2G3R5MS": "Keystone Ice",
15 | "01D9X5CVS1M9VR5ZD627XDF6ND": "Belgian Moon",
16 | }
17 |
18 | const idFlag = "id"
19 |
20 | // InitBeersCmd initialize beers command
21 | func InitBeersCmd() *cobra.Command {
22 | beersCmd := &cobra.Command{
23 | Use: "beers",
24 | Short: "Print data about beers",
25 | Run: runBeersFn(),
26 | }
27 |
28 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
29 |
30 | return beersCmd
31 | }
32 |
33 | func runBeersFn() CobraFn {
34 | return func(cmd *cobra.Command, args []string) {
35 | id, _ := cmd.Flags().GetString(idFlag)
36 |
37 | if id != "" {
38 | fmt.Println(beers[id])
39 | } else {
40 | fmt.Println(beers)
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/04-modeling_data/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/04-modeling_data/internal"
8 | "github.com/spf13/cobra"
9 | )
10 |
11 | // CobraFn function definion of run cobra command
12 | type CobraFn func(cmd *cobra.Command, args []string)
13 |
14 | const idFlag = "id"
15 |
16 | // InitBeersCmd initialize beers command
17 | func InitBeersCmd(repository beerscli.BeerRepo) *cobra.Command {
18 | beersCmd := &cobra.Command{
19 | Use: "beers",
20 | Short: "Print data about beers",
21 | Run: runBeersFn(repository),
22 | }
23 |
24 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
25 |
26 | return beersCmd
27 | }
28 |
29 | func runBeersFn(repository beerscli.BeerRepo) CobraFn {
30 | return func(cmd *cobra.Command, args []string) {
31 | beers, _ := repository.GetBeers()
32 |
33 | id, _ := cmd.Flags().GetString(idFlag)
34 |
35 | if id != "" {
36 | i, _ := strconv.Atoi(id)
37 | for _, beer := range beers {
38 | if beer.ProductID == i {
39 | fmt.Println(beer)
40 | return
41 | }
42 | }
43 | } else {
44 | fmt.Println(beers)
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/10-profiling/internal/fetching/service.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
5 | "github.com/pkg/errors"
6 | )
7 |
8 | // Service provides beer fetching operations
9 | type Service interface {
10 | // FetchBeers fetch all beers from repository
11 | FetchBeers() ([]beerscli.Beer, error)
12 | // FetchByID filter all beers and get only the beer that match with given id
13 | FetchByID(id int) (beerscli.Beer, error)
14 | }
15 |
16 | type service struct {
17 | bR beerscli.BeerRepo
18 | }
19 |
20 | // NewService creates an adding service with the necessary dependencies
21 | func NewService(r beerscli.BeerRepo) Service {
22 | return &service{r}
23 | }
24 |
25 | func (s *service) FetchBeers() ([]beerscli.Beer, error) {
26 | return s.bR.GetBeers()
27 | }
28 |
29 | func (s *service) FetchByID(id int) (beerscli.Beer, error) {
30 | beers, err := s.FetchBeers()
31 | if err != nil {
32 | return beerscli.Beer{}, err
33 | }
34 |
35 | for _, beer := range beers {
36 | if beer.ProductID == id {
37 | return beer, nil
38 | }
39 | }
40 |
41 | return beerscli.Beer{}, errors.Errorf("Beer %d not found", id)
42 | }
43 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/fetching/service.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
5 | "github.com/pkg/errors"
6 | )
7 |
8 | // Service provides beer fetching operations
9 | type Service interface {
10 | // FetchBeers fetch all beers from repository
11 | FetchBeers() ([]beerscli.Beer, error)
12 | // FetchByID filter all beers and get only the beer that match with given id
13 | FetchByID(id int) (beerscli.Beer, error)
14 | }
15 |
16 | type service struct {
17 | bR beerscli.BeerRepo
18 | }
19 |
20 | // NewService creates an adding service with the necessary dependencies
21 | func NewService(r beerscli.BeerRepo) Service {
22 | return &service{r}
23 | }
24 |
25 | func (s *service) FetchBeers() ([]beerscli.Beer, error) {
26 | return s.bR.GetBeers()
27 | }
28 |
29 | func (s *service) FetchByID(id int) (beerscli.Beer, error) {
30 | beers, err := s.FetchBeers()
31 | if err != nil {
32 | return beerscli.Beer{}, err
33 | }
34 |
35 | for _, beer := range beers {
36 | if beer.ProductID == id {
37 | return beer, nil
38 | }
39 | }
40 |
41 | return beerscli.Beer{}, errors.Errorf("Beer %d not found", id)
42 | }
43 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/fetching/service.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
5 | "github.com/pkg/errors"
6 | )
7 |
8 | // Service provides beer fetching operations
9 | type Service interface {
10 | // FetchBeers fetch all beers from repository
11 | FetchBeers() ([]beerscli.Beer, error)
12 | // FetchByID filter all beers and get only the beer that match with given id
13 | FetchByID(id int) (beerscli.Beer, error)
14 | }
15 |
16 | type service struct {
17 | bR beerscli.BeerRepo
18 | }
19 |
20 | // NewService creates an adding service with the necessary dependencies
21 | func NewService(r beerscli.BeerRepo) Service {
22 | return &service{r}
23 | }
24 |
25 | func (s *service) FetchBeers() ([]beerscli.Beer, error) {
26 | return s.bR.GetBeers()
27 | }
28 |
29 | func (s *service) FetchByID(id int) (beerscli.Beer, error) {
30 | beers, err := s.FetchBeers()
31 | if err != nil {
32 | return beerscli.Beer{}, err
33 | }
34 |
35 | for _, beer := range beers {
36 | if beer.ProductID == id {
37 | return beer, nil
38 | }
39 | }
40 |
41 | return beerscli.Beer{}, errors.Errorf("Beer %d not found", id)
42 | }
43 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("10-profiling/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/05-parsing_http_response/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal"
8 | "github.com/spf13/cobra"
9 | )
10 |
11 | // CobraFn function definion of run cobra command
12 | type CobraFn func(cmd *cobra.Command, args []string)
13 |
14 | const idFlag = "id"
15 |
16 | // InitBeersCmd initialize beers command
17 | func InitBeersCmd(repository beerscli.BeerRepo) *cobra.Command {
18 | beersCmd := &cobra.Command{
19 | Use: "beers",
20 | Short: "Print data about beers",
21 | Run: runBeersFn(repository),
22 | }
23 |
24 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
25 |
26 | return beersCmd
27 | }
28 |
29 | func runBeersFn(repository beerscli.BeerRepo) CobraFn {
30 | return func(cmd *cobra.Command, args []string) {
31 | beers, _ := repository.GetBeers()
32 |
33 | id, _ := cmd.Flags().GetString(idFlag)
34 |
35 | if id != "" {
36 | i, _ := strconv.Atoi(id)
37 | for _, beer := range beers {
38 | if beer.ProductID == i {
39 | fmt.Println(beer)
40 | return
41 | }
42 | }
43 | } else {
44 | fmt.Println(beers)
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("09-benchmarking/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/06-error_handling/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/06-error_handling/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("06-error_handling/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("08-automated_tests/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/06-error_handling/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/06-error_handling/internal"
10 | "github.com/pkg/errors"
11 | )
12 |
13 | const (
14 | productsEndpoint = "/products"
15 | ontarioURL = "http://ontariobeerapi.ca"
16 | )
17 |
18 | type beerRepo struct {
19 | url string
20 | }
21 |
22 | // NewOntarioRepository fetch beers data from csv
23 | func NewOntarioRepository() beerscli.BeerRepo {
24 | return &beerRepo{url: ontarioURL}
25 | }
26 |
27 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
28 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
29 | if err != nil {
30 | return nil, errors.Wrapf(err, "Something happened when call the endpoint: %s", productsEndpoint)
31 | }
32 |
33 | contents, err := ioutil.ReadAll(response.Body)
34 | if err != nil {
35 | return nil, errors.Wrap(err, "Something happened when read the content")
36 | }
37 |
38 | err = json.Unmarshal(contents, &beers)
39 | if err != nil {
40 | return nil, errors.Wrap(err, "Something happened when unmarshal the content")
41 | }
42 | return
43 | }
44 |
--------------------------------------------------------------------------------
/10-profiling/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "strconv"
7 |
8 | "github.com/CodelyTV/golang-examples/10-profiling/internal/fetching"
9 | "github.com/spf13/cobra"
10 | )
11 |
12 | // CobraFn function definion of run cobra command
13 | type CobraFn func(cmd *cobra.Command, args []string)
14 |
15 | const idFlag = "id"
16 |
17 | // InitBeersCmd initialize beers command
18 | func InitBeersCmd(service fetching.Service) *cobra.Command {
19 | beersCmd := &cobra.Command{
20 | Use: "beers",
21 | Short: "Print data about beers",
22 | Run: runBeersFn(service),
23 | }
24 |
25 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
26 |
27 | return beersCmd
28 | }
29 |
30 | func runBeersFn(service fetching.Service) CobraFn {
31 | return func(cmd *cobra.Command, args []string) {
32 |
33 | id, _ := cmd.Flags().GetString(idFlag)
34 | if id != "" {
35 | i, _ := strconv.Atoi(id)
36 | beer, err := service.FetchByID(i)
37 | if err != nil {
38 | log.Fatal(err)
39 | }
40 |
41 | fmt.Println(beer)
42 | return
43 | }
44 |
45 | beers, err := service.FetchBeers()
46 | if err != nil {
47 | log.Fatal(err)
48 | }
49 | fmt.Println(beers)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/05-parsing_http_response/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/05-parsing_http_response/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("05-parsing_http_response/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "strconv"
7 |
8 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/fetching"
9 |
10 | "github.com/spf13/cobra"
11 | )
12 |
13 | // CobraFn function definion of run cobra command
14 | type CobraFn func(cmd *cobra.Command, args []string)
15 |
16 | const idFlag = "id"
17 |
18 | // InitBeersCmd initialize beers command
19 | func InitBeersCmd(service fetching.Service) *cobra.Command {
20 | beersCmd := &cobra.Command{
21 | Use: "beers",
22 | Short: "Print data about beers",
23 | Run: runBeersFn(service),
24 | }
25 |
26 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
27 |
28 | return beersCmd
29 | }
30 |
31 | func runBeersFn(service fetching.Service) CobraFn {
32 | return func(cmd *cobra.Command, args []string) {
33 |
34 | id, _ := cmd.Flags().GetString(idFlag)
35 | if id != "" {
36 | i, _ := strconv.Atoi(id)
37 | beer, err := service.FetchByID(i)
38 | if err != nil {
39 | log.Fatal(err)
40 | }
41 |
42 | fmt.Println(beer)
43 | return
44 | }
45 |
46 | beers, err := service.FetchBeers()
47 | if err != nil {
48 | log.Fatal(err)
49 | }
50 | fmt.Println(beers)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("07-behaviour_error_handling/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "strconv"
7 |
8 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/fetching"
9 |
10 | "github.com/spf13/cobra"
11 | )
12 |
13 | // CobraFn function definion of run cobra command
14 | type CobraFn func(cmd *cobra.Command, args []string)
15 |
16 | const idFlag = "id"
17 |
18 | // InitBeersCmd initialize beers command
19 | func InitBeersCmd(service fetching.Service) *cobra.Command {
20 | beersCmd := &cobra.Command{
21 | Use: "beers",
22 | Short: "Print data about beers",
23 | Run: runBeersFn(service),
24 | }
25 |
26 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
27 |
28 | return beersCmd
29 | }
30 |
31 | func runBeersFn(service fetching.Service) CobraFn {
32 | return func(cmd *cobra.Command, args []string) {
33 |
34 | id, _ := cmd.Flags().GetString(idFlag)
35 | if id != "" {
36 | i, _ := strconv.Atoi(id)
37 | beer, err := service.FetchByID(i)
38 | if err != nil {
39 | log.Fatal(err)
40 | }
41 |
42 | fmt.Println(beer)
43 | return
44 | }
45 |
46 | beers, err := service.FetchBeers()
47 | if err != nil {
48 | log.Fatal(err)
49 | }
50 | fmt.Println(beers)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("11-sharing_memory_concurrency/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 |
32 | beer := beerscli.NewBeer(
33 | productID,
34 | values[1],
35 | values[2],
36 | values[5],
37 | values[6],
38 | values[3],
39 | beerscli.NewBeerType(values[4]),
40 | )
41 |
42 | beers = append(beers, beer)
43 | }
44 |
45 | return beers, nil
46 | }
47 |
48 | func readLine(reader *bufio.Reader) (line []byte) {
49 | line, _, _ = reader.ReadLine()
50 | return
51 | }
52 |
--------------------------------------------------------------------------------
/04-modeling_data/internal/storage/csv/repository.go:
--------------------------------------------------------------------------------
1 | package csv
2 |
3 | import (
4 | "bufio"
5 | "os"
6 | "strconv"
7 | "strings"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/04-modeling_data/internal"
10 | )
11 |
12 | type repository struct {
13 | }
14 |
15 | // NewRepository initialize csv repository
16 | func NewRepository() beerscli.BeerRepo {
17 | return &repository{}
18 | }
19 |
20 | // GetBeers fetch beers data from csv
21 | func (r *repository) GetBeers() ([]beerscli.Beer, error) {
22 | f, _ := os.Open("04-modeling_data/data/beers.csv")
23 | reader := bufio.NewReader(f)
24 |
25 | var beers []beerscli.Beer
26 |
27 | for line := readLine(reader); line != nil; line = readLine(reader) {
28 | values := strings.Split(string(line), ",")
29 |
30 | productID, _ := strconv.Atoi(values[0])
31 | price, _ := strconv.ParseFloat(values[3], 64)
32 |
33 | beer := beerscli.NewBeer(
34 | productID,
35 | values[1],
36 | values[2],
37 | values[5],
38 | values[6],
39 | beerscli.NewBeerType(values[4]),
40 | price,
41 | )
42 |
43 | beers = append(beers, beer)
44 | }
45 |
46 | return beers, nil
47 | }
48 |
49 | func readLine(reader *bufio.Reader) (line []byte) {
50 | line, _, _ = reader.ReadLine()
51 | return
52 | }
53 |
--------------------------------------------------------------------------------
/06-error_handling/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "strconv"
7 |
8 | beerscli "github.com/CodelyTV/golang-examples/06-error_handling/internal"
9 | "github.com/spf13/cobra"
10 | )
11 |
12 | // CobraFn function definion of run cobra command
13 | type CobraFn func(cmd *cobra.Command, args []string)
14 |
15 | const idFlag = "id"
16 |
17 | // InitBeersCmd initialize beers command
18 | func InitBeersCmd(repository beerscli.BeerRepo) *cobra.Command {
19 | beersCmd := &cobra.Command{
20 | Use: "beers",
21 | Short: "Print data about beers",
22 | Run: runBeersFn(repository),
23 | }
24 |
25 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
26 |
27 | return beersCmd
28 | }
29 |
30 | func runBeersFn(repository beerscli.BeerRepo) CobraFn {
31 | return func(cmd *cobra.Command, args []string) {
32 | beers, err := repository.GetBeers()
33 | if err != nil {
34 | log.Fatal(err)
35 | }
36 |
37 | id, _ := cmd.Flags().GetString(idFlag)
38 |
39 | if id != "" {
40 | i, _ := strconv.Atoi(id)
41 | for _, beer := range beers {
42 | if beer.ProductID == i {
43 | fmt.Println(beer)
44 | return
45 | }
46 | }
47 | } else {
48 | fmt.Println(beers)
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "strconv"
7 |
8 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/fetching"
9 | "github.com/spf13/cobra"
10 | )
11 |
12 | // CobraFn function definion of run cobra command
13 | type CobraFn func(cmd *cobra.Command, args []string)
14 |
15 | const idFlag = "id"
16 |
17 | // InitBeersCmd initialize beers command
18 | func InitBeersCmd(service fetching.Service) *cobra.Command {
19 | beersCmd := &cobra.Command{
20 | Use: "beers",
21 | Short: "Print data about beers",
22 | Run: runBeersFn(service),
23 | }
24 |
25 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
26 |
27 | return beersCmd
28 | }
29 |
30 | func runBeersFn(service fetching.Service) CobraFn {
31 | return func(cmd *cobra.Command, args []string) {
32 |
33 | id, _ := cmd.Flags().GetString(idFlag)
34 | if id != "" {
35 | i, _ := strconv.Atoi(id)
36 | beer, err := service.FetchByID(i)
37 | if err != nil {
38 | log.Fatal(err)
39 | }
40 |
41 | fmt.Println(beer)
42 | return
43 | }
44 |
45 | beers, err := service.FetchBeers()
46 | if err != nil {
47 | log.Fatal(err)
48 | }
49 | fmt.Println(beers)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
10 | "github.com/CodelyTV/golang-examples/10-profiling/internal/errors"
11 | )
12 |
13 | const (
14 | productsEndpoint = "/products"
15 | ontarioURL = "http://localhost:3000"
16 | )
17 |
18 | type beerRepo struct {
19 | url string
20 | }
21 |
22 | // NewOntarioRepository fetch beers data from csv
23 | func NewOntarioRepository() beerscli.BeerRepo {
24 | return &beerRepo{url: ontarioURL}
25 | }
26 |
27 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
28 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
29 | if err != nil {
30 | return nil, errors.WrapDataUnreacheable(err, "error getting response to %s", productsEndpoint)
31 | }
32 |
33 | contents, err := ioutil.ReadAll(response.Body)
34 | if err != nil {
35 | return nil, errors.WrapDataUnreacheable(err, "error reading the response from %s", productsEndpoint)
36 | }
37 |
38 | err = json.Unmarshal(contents, &beers)
39 | if err != nil {
40 | return nil, errors.WrapDataUnreacheable(err, "can't parsing response into beers")
41 | }
42 | return
43 | }
44 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
10 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/errors"
11 | )
12 |
13 | const (
14 | productsEndpoint = "/products"
15 | ontarioURL = "http://ontariobeerapi.ca"
16 | )
17 |
18 | type beerRepo struct {
19 | url string
20 | }
21 |
22 | // NewOntarioRepository fetch beers data from csv
23 | func NewOntarioRepository() beerscli.BeerRepo {
24 | return &beerRepo{url: ontarioURL}
25 | }
26 |
27 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
28 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
29 | if err != nil {
30 | return nil, errors.WrapDataUnreacheable(err, "error getting response to %s", productsEndpoint)
31 | }
32 |
33 | contents, err := ioutil.ReadAll(response.Body)
34 | if err != nil {
35 | return nil, errors.WrapDataUnreacheable(err, "error reading the response from %s", productsEndpoint)
36 | }
37 |
38 | err = json.Unmarshal(contents, &beers)
39 | if err != nil {
40 | return nil, errors.WrapDataUnreacheable(err, "can't parsing response into beers")
41 | }
42 | return
43 | }
44 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal"
10 | "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/errors"
11 | )
12 |
13 | const (
14 | productsEndpoint = "/products"
15 | ontarioURL = "http://ontariobeerapi.ca"
16 | )
17 |
18 | type beerRepo struct {
19 | url string
20 | }
21 |
22 | // NewOntarioRepository fetch beers data from csv
23 | func NewOntarioRepository() beerscli.BeerRepo {
24 | return &beerRepo{url: ontarioURL}
25 | }
26 |
27 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
28 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
29 | if err != nil {
30 | return nil, errors.WrapDataUnreacheable(err, "error getting response to %s", productsEndpoint)
31 | }
32 |
33 | contents, err := ioutil.ReadAll(response.Body)
34 | if err != nil {
35 | return nil, errors.WrapDataUnreacheable(err, "error reading the response from %s", productsEndpoint)
36 | }
37 |
38 | err = json.Unmarshal(contents, &beers)
39 | if err != nil {
40 | return nil, errors.WrapDataUnreacheable(err, "can't parsing response into beers")
41 | }
42 | return
43 | }
44 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
10 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/errors"
11 | )
12 |
13 | const (
14 | productsEndpoint = "/products"
15 | ontarioURL = "http://localhost:3000"
16 | )
17 |
18 | type beerRepo struct {
19 | url string
20 | }
21 |
22 | // NewOntarioRepository fetch beers data from csv
23 | func NewOntarioRepository() beerscli.BeerRepo {
24 | return &beerRepo{url: ontarioURL}
25 | }
26 |
27 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
28 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
29 | if err != nil {
30 | return nil, errors.WrapDataUnreacheable(err, "error getting response to %s", productsEndpoint)
31 | }
32 |
33 | contents, err := ioutil.ReadAll(response.Body)
34 | if err != nil {
35 | return nil, errors.WrapDataUnreacheable(err, "error reading the response from %s", productsEndpoint)
36 | }
37 |
38 | err = json.Unmarshal(contents, &beers)
39 | if err != nil {
40 | return nil, errors.WrapDataUnreacheable(err, "can't parsing response into beers")
41 | }
42 | return
43 | }
44 |
--------------------------------------------------------------------------------
/10-profiling/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
7 | "github.com/CodelyTV/golang-examples/10-profiling/internal/cli"
8 | "github.com/CodelyTV/golang-examples/10-profiling/internal/fetching"
9 | "github.com/CodelyTV/golang-examples/10-profiling/internal/storage/csv"
10 | "github.com/CodelyTV/golang-examples/10-profiling/internal/storage/ontario"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | func main() {
15 | // CPU profiling code starts here
16 | //f, _ := os.Create("beers.cpu.prof")
17 | //defer f.Close()
18 | //pprof.StartCPUProfile(f)
19 | //defer pprof.StopCPUProfile()
20 | // CPU profiling code ends here
21 |
22 | csvData := flag.Bool("csv", false, "load data from csv")
23 | flag.Parse()
24 | var repo beerscli.BeerRepo
25 | repo = csv.NewRepository()
26 |
27 | if !*csvData {
28 | repo = ontario.NewOntarioRepository()
29 | }
30 |
31 | fetchingService := fetching.NewService(repo)
32 |
33 | rootCmd := &cobra.Command{Use: "beers-cli"}
34 | rootCmd.AddCommand(cli.InitBeersCmd(fetchingService))
35 | rootCmd.Execute()
36 |
37 | // Memory profiling code starts here
38 | //f2, _ := os.Create("beers.mem.prof")
39 | //defer f2.Close()
40 | //pprof.WriteHeapProfile(f2)
41 | // Memory profiling code ends here
42 | }
43 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "strconv"
7 |
8 | "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/errors"
9 |
10 | beerscli "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | // CobraFn function definion of run cobra command
15 | type CobraFn func(cmd *cobra.Command, args []string)
16 |
17 | const idFlag = "id"
18 |
19 | // InitBeersCmd initialize beers command
20 | func InitBeersCmd(repository beerscli.BeerRepo) *cobra.Command {
21 | beersCmd := &cobra.Command{
22 | Use: "beers",
23 | Short: "Print data about beers",
24 | Run: runBeersFn(repository),
25 | }
26 |
27 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
28 |
29 | return beersCmd
30 | }
31 |
32 | func runBeersFn(repository beerscli.BeerRepo) CobraFn {
33 | return func(cmd *cobra.Command, args []string) {
34 | beers, err := repository.GetBeers()
35 | if errors.IsDataUnreacheable(err) {
36 | log.Fatal(err)
37 | }
38 |
39 | id, _ := cmd.Flags().GetString(idFlag)
40 |
41 | if id != "" {
42 | i, _ := strconv.Atoi(id)
43 | for _, beer := range beers {
44 | if beer.ProductID == i {
45 | fmt.Println(beer)
46 | return
47 | }
48 | }
49 | } else {
50 | fmt.Println(beers)
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/03-reading_files/internal/cli/beers.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "os"
7 | "strconv"
8 | "strings"
9 |
10 | "github.com/spf13/cobra"
11 | )
12 |
13 | // CobraFn function definion of run cobra command
14 | type CobraFn func(cmd *cobra.Command, args []string)
15 |
16 | const idFlag = "id"
17 |
18 | // InitBeersCmd initialize beers command
19 | func InitBeersCmd() *cobra.Command {
20 | beersCmd := &cobra.Command{
21 | Use: "beers",
22 | Short: "Print data about beers",
23 | Run: runBeersFn(),
24 | }
25 |
26 | beersCmd.Flags().StringP(idFlag, "i", "", "id of the beer")
27 |
28 | return beersCmd
29 | }
30 |
31 | func runBeersFn() CobraFn {
32 | return func(cmd *cobra.Command, args []string) {
33 |
34 | f, _ := os.Open("03-reading_files/data/beers.csv")
35 | reader := bufio.NewReader(f)
36 |
37 | var beers = make(map[int]string)
38 |
39 | for line := readLine(reader); line != nil; line = readLine(reader) {
40 | values := strings.Split(string(line), ",")
41 |
42 | productID, _ := strconv.Atoi(values[0])
43 | beers[productID] = values[1]
44 | }
45 |
46 | id, _ := cmd.Flags().GetString(idFlag)
47 |
48 | if id != "" {
49 | i, _ := strconv.Atoi(id)
50 | fmt.Println(beers[i])
51 | } else {
52 | fmt.Println(beers)
53 | }
54 | }
55 | }
56 |
57 | func readLine(reader *bufio.Reader) (line []byte) {
58 | line, _, _ = reader.ReadLine()
59 | return
60 | }
61 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/cmd/beers-cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
7 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/cli"
8 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/fetching"
9 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/csv"
10 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/ontario"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | func main() {
15 | // CPU profiling code starts here
16 | //f, _ := os.Create("beers.cpu.prof")
17 | //defer f.Close()
18 | //pprof.StartCPUProfile(f)
19 | //defer pprof.StopCPUProfile()
20 | // CPU profiling code ends here
21 |
22 | csvData := flag.Bool("csv", false, "load data from csv")
23 | flag.Parse()
24 | var repo beerscli.BeerRepo
25 | repo = csv.NewRepository()
26 |
27 | if !*csvData {
28 | repo = ontario.NewOntarioRepository()
29 | }
30 |
31 | fetchingService := fetching.NewService(repo)
32 |
33 | rootCmd := &cobra.Command{Use: "beers-cli"}
34 | rootCmd.AddCommand(cli.InitBeersCmd(fetchingService))
35 | rootCmd.Execute()
36 |
37 | // Memory profiling code starts here
38 | //f2, _ := os.Create("beers.mem.prof")
39 | //defer f2.Close()
40 | //pprof.WriteHeapProfile(f2)
41 | // Memory profiling code ends here
42 | }
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodelyTV and Friends of Go Present: Go Command Line Tool
2 |
3 |
4 |
5 |
6 | Project showing up how you could implement a entire command line application with **GO**.
7 |
8 | With this project you will be capable of implementing an application with **Go**. For this project you don't need previous experience on the language, but you do need a minimal background as a developer.
9 |
10 | We will explain all the features that go with it including the famous `goroutines`.
11 |
12 | ## Contents
13 |
14 | **Lesson 1.** Go Flags: introduction to "flags" package.
15 |
16 | **Lesson 2.** Cobra: refactor from "flags" package to Cobra library.
17 |
18 | **Lesson 3.** Reading files: retrieving beers from file.
19 |
20 | **Lesson 4.** Modeling data: modeling our beers (structs, defined types, etc).
21 |
22 |
23 | ## Environment setup
24 |
25 | See the environment setup instructions below.
26 |
27 | ### Requirements
28 |
29 | To compile & run the source code of this project you just need to have [Go](https://golang.org/) properly installed.
30 |
31 | ### Installation
32 |
33 | Binary distributions of Go are [available](https://golang.org/dl/) for Linux, macOS, Windows and more.
34 |
35 | Otherwise you can [download](https://dl.google.com/go/go1.12.5.src.tar.gz) the source code and compile it for your platform.
36 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/fetching/service.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | "math"
5 | "sync"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
8 | )
9 |
10 | // Service provides beer fetching operations
11 | type Service interface {
12 | // FetchBeers fetch all beers from repository
13 | FetchBeers() ([]beerscli.Beer, error)
14 | // FetchByID filter all beers and get only the beer that match with given id
15 | FetchByID(id int) (beerscli.Beer, error)
16 | }
17 |
18 | type service struct {
19 | bR beerscli.BeerRepo
20 | }
21 |
22 | // NewService creates an adding service with the necessary dependencies
23 | func NewService(r beerscli.BeerRepo) Service {
24 | return &service{r}
25 | }
26 |
27 | func (s *service) FetchBeers() ([]beerscli.Beer, error) {
28 | return s.bR.GetBeers()
29 | }
30 |
31 | func (s *service) FetchByID(id int) (beerscli.Beer, error) {
32 | beers, err := s.FetchBeers()
33 | if err != nil {
34 | return beerscli.Beer{}, err
35 | }
36 |
37 | beersPerRoutine := 10
38 | numRoutines := numOfRoutines(len(beers), beersPerRoutine)
39 |
40 | wg := &sync.WaitGroup{}
41 | wg.Add(numRoutines)
42 |
43 | var b beerscli.Beer
44 |
45 | for i := 0; i < numRoutines; i++ {
46 | go func(id, begin, end int, beers []beerscli.Beer, b *beerscli.Beer, wg *sync.WaitGroup) {
47 | for i := begin; i <= end; i++ {
48 | if beers[i].ProductID == id {
49 | *b = beers[i]
50 | }
51 | }
52 | wg.Done()
53 | }(id, i, i+beersPerRoutine, beers, &b, wg)
54 | }
55 |
56 | wg.Wait()
57 |
58 | return b, nil
59 | }
60 |
61 | func numOfRoutines(numOfBeers, beersPerRoutine int) int {
62 | return int(math.Ceil(float64(numOfBeers) / float64(beersPerRoutine)))
63 | }
64 |
--------------------------------------------------------------------------------
/04-modeling_data/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | // Beer representation of beer into data struct
4 | type Beer struct {
5 | ProductID int
6 | Name string
7 | Price float64
8 | Category string
9 | Type *BeerType
10 | Brewer string
11 | Country string
12 | }
13 |
14 | type BeerType int
15 |
16 | const (
17 | Unknown BeerType = iota
18 | Lager
19 | Malt
20 | Ale
21 | FlavouredMalt
22 | Stout
23 | Porter
24 | NonAlcoholic
25 | )
26 |
27 | func (t BeerType) String() string {
28 | return toString[t]
29 | }
30 |
31 | // NewBeerType initialize a type from enum beerTypes
32 | func NewBeerType(t string) *BeerType {
33 | beerType := toID[t]
34 | return &beerType
35 | }
36 |
37 | var toString = map[BeerType]string{
38 | Lager: "Lager",
39 | Malt: "Malt",
40 | Ale: "Ale",
41 | FlavouredMalt: "Flavoured Malt",
42 | Stout: "Stout",
43 | Porter: "Stout",
44 | NonAlcoholic: "Non-Alcoholic",
45 | Unknown: "unknown",
46 | }
47 |
48 | var toID = map[string]BeerType{
49 | "Lager": Lager,
50 | "Malt": Malt,
51 | "Ale": Ale,
52 | "Flavoured Malt": FlavouredMalt,
53 | "Stout": Stout,
54 | "Porter": Porter,
55 | "Non-Alcoholic": NonAlcoholic,
56 | "unknown": Unknown,
57 | }
58 |
59 | // BeerRepo definiton of methods to access a data beer
60 | type BeerRepo interface {
61 | GetBeers() ([]Beer, error)
62 | }
63 |
64 | // NewBeer initialize struct beer
65 | func NewBeer(productID int, name, category, brewer, country string, beerType *BeerType, price float64) (b Beer) {
66 | b = Beer{
67 | ProductID: productID,
68 | Name: name,
69 | Category: category,
70 | Type: beerType,
71 | Brewer: brewer,
72 | Country: country,
73 | Price: price,
74 | }
75 | return
76 | }
77 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/ontario/repository.go:
--------------------------------------------------------------------------------
1 | package ontario
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
10 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/errors"
11 | jsoniter "github.com/json-iterator/go"
12 | )
13 |
14 | const (
15 | productsEndpoint = "/products"
16 | ontarioURL = "http://localhost:3000"
17 | )
18 |
19 | type beerRepo struct {
20 | url string
21 | }
22 |
23 | // NewOntarioRepository fetch beers data from csv
24 | func NewOntarioRepository() beerscli.BeerRepo {
25 | return &beerRepo{url: ontarioURL}
26 | }
27 |
28 | func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) {
29 | response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint))
30 | if err != nil {
31 | return nil, errors.WrapDataUnreacheable(err, "error getting response to %s", productsEndpoint)
32 | }
33 |
34 | contents, err := ioutil.ReadAll(response.Body)
35 | if err != nil {
36 | return nil, errors.WrapDataUnreacheable(err, "error reading the response from %s", productsEndpoint)
37 | }
38 |
39 | err = b.betterUnmarshal(contents, &beers)
40 | if err != nil {
41 | return nil, errors.WrapDataUnreacheable(err, "can't parsing response into beers")
42 | }
43 | return
44 | }
45 |
46 | func (b *beerRepo) standardUnmarshal(data []byte, beers *[]beerscli.Beer) error {
47 | err := json.Unmarshal(data, &beers)
48 | if err != nil {
49 | return errors.WrapDataUnreacheable(err, "can't parsing response into beers")
50 | }
51 | return nil
52 | }
53 |
54 | func (b *beerRepo) betterUnmarshal(data []byte, beers *[]beerscli.Beer) error {
55 | var js = jsoniter.ConfigCompatibleWithStandardLibrary
56 |
57 | err := js.Unmarshal(data, &beers)
58 | if err != nil {
59 | return errors.WrapDataUnreacheable(err, "can't parsing response into beers")
60 | }
61 |
62 | return nil
63 | }
64 |
--------------------------------------------------------------------------------
/10-profiling/internal/fetching/service_test.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
8 | "github.com/CodelyTV/golang-examples/10-profiling/internal/storage/mock"
9 | "github.com/stretchr/testify/assert"
10 | )
11 |
12 | func TestFetchByID(t *testing.T) {
13 |
14 | tests := map[string]struct {
15 | repo beerscli.BeerRepo
16 | input int
17 | want int
18 | err error
19 | }{
20 | "valid beer": {repo: buildMockBeers(), input: 127, want: 127, err: nil},
21 | "not found beer": {repo: buildMockBeers(), input: 99999, err: errors.New("error")},
22 | "error with repository": {repo: buildMockError(), err: errors.New("error")},
23 | }
24 |
25 | for name, tc := range tests {
26 | t.Run(name, func(t *testing.T) {
27 | service := NewService(tc.repo)
28 |
29 | b, err := service.FetchByID(tc.input)
30 |
31 | if tc.err != nil {
32 | assert.Error(t, err)
33 | }
34 |
35 | if tc.err == nil {
36 | assert.Nil(t, err)
37 | }
38 |
39 | assert.Equal(t, tc.want, b.ProductID)
40 | })
41 | }
42 | }
43 |
44 | func buildMockBeers() beerscli.BeerRepo {
45 | mockedRepo := &mock.BeerRepoMock{
46 | GetBeersFunc: func() ([]beerscli.Beer, error) {
47 | return []beerscli.Beer{
48 | beerscli.NewBeer(
49 | 127,
50 | "Mad Jack Mixer",
51 | "Domestic Specialty",
52 | "Molson",
53 | "Canada",
54 | "23.95",
55 | beerscli.NewBeerType("Lager"),
56 | ),
57 | beerscli.NewBeer(
58 | 8520130,
59 | "Grolsch 0.0",
60 | "Non-Alcoholic Beer",
61 | "Grolsch Export B.V.",
62 | "Canada",
63 | "49.50",
64 | beerscli.NewBeerType("Non-Alcoholic Beer"),
65 | ),
66 | }, nil
67 | },
68 | }
69 |
70 | return mockedRepo
71 | }
72 |
73 | func buildMockError() beerscli.BeerRepo {
74 | mockedRepo := &mock.BeerRepoMock{
75 | GetBeersFunc: func() ([]beerscli.Beer, error) {
76 | return []beerscli.Beer{}, errors.New("error")
77 | },
78 | }
79 |
80 | return mockedRepo
81 | }
82 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/fetching/service_test.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
8 | "github.com/CodelyTV/golang-examples/09-benchmarking/internal/storage/mock"
9 |
10 | "github.com/stretchr/testify/assert"
11 | )
12 |
13 | func TestFetchByID(t *testing.T) {
14 |
15 | tests := map[string]struct {
16 | repo beerscli.BeerRepo
17 | input int
18 | want int
19 | err error
20 | }{
21 | "valid beer": {repo: buildMockBeers(), input: 127, want: 127, err: nil},
22 | "not found beer": {repo: buildMockBeers(), input: 99999, err: errors.New("error")},
23 | "error with repository": {repo: buildMockError(), err: errors.New("error")},
24 | }
25 |
26 | for name, tc := range tests {
27 | t.Run(name, func(t *testing.T) {
28 | service := NewService(tc.repo)
29 |
30 | b, err := service.FetchByID(tc.input)
31 |
32 | if tc.err != nil {
33 | assert.Error(t, err)
34 | }
35 |
36 | if tc.err == nil {
37 | assert.Nil(t, err)
38 | }
39 |
40 | assert.Equal(t, tc.want, b.ProductID)
41 | })
42 | }
43 | }
44 |
45 | func buildMockBeers() beerscli.BeerRepo {
46 | mockedRepo := &mock.BeerRepoMock{
47 | GetBeersFunc: func() ([]beerscli.Beer, error) {
48 | return []beerscli.Beer{
49 | beerscli.NewBeer(
50 | 127,
51 | "Mad Jack Mixer",
52 | "Domestic Specialty",
53 | "Molson",
54 | "Canada",
55 | "23.95",
56 | beerscli.NewBeerType("Lager"),
57 | ),
58 | beerscli.NewBeer(
59 | 8520130,
60 | "Grolsch 0.0",
61 | "Non-Alcoholic Beer",
62 | "Grolsch Export B.V.",
63 | "Canada",
64 | "49.50",
65 | beerscli.NewBeerType("Non-Alcoholic Beer"),
66 | ),
67 | }, nil
68 | },
69 | }
70 |
71 | return mockedRepo
72 | }
73 |
74 | func buildMockError() beerscli.BeerRepo {
75 | mockedRepo := &mock.BeerRepoMock{
76 | GetBeersFunc: func() ([]beerscli.Beer, error) {
77 | return []beerscli.Beer{}, errors.New("error")
78 | },
79 | }
80 |
81 | return mockedRepo
82 | }
83 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/fetching/service_test.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
8 | "github.com/CodelyTV/golang-examples/08-automated_tests/internal/storage/mock"
9 |
10 | "github.com/stretchr/testify/assert"
11 | )
12 |
13 | func TestFetchByID(t *testing.T) {
14 |
15 | tests := map[string]struct {
16 | repo beerscli.BeerRepo
17 | input int
18 | want int
19 | err error
20 | }{
21 | "valid beer": {repo: buildMockBeers(), input: 127, want: 127, err: nil},
22 | "not found beer": {repo: buildMockBeers(), input: 99999, err: errors.New("error")},
23 | "error with repository": {repo: buildMockError(), err: errors.New("error")},
24 | }
25 |
26 | for name, tc := range tests {
27 | t.Run(name, func(t *testing.T) {
28 | service := NewService(tc.repo)
29 |
30 | b, err := service.FetchByID(tc.input)
31 |
32 | if tc.err != nil {
33 | assert.Error(t, err)
34 | }
35 |
36 | if tc.err == nil {
37 | assert.Nil(t, err)
38 | }
39 |
40 | assert.Equal(t, tc.want, b.ProductID)
41 | })
42 | }
43 | }
44 |
45 | func buildMockBeers() beerscli.BeerRepo {
46 | mockedRepo := &mock.BeerRepoMock{
47 | GetBeersFunc: func() ([]beerscli.Beer, error) {
48 | return []beerscli.Beer{
49 | beerscli.NewBeer(
50 | 127,
51 | "Mad Jack Mixer",
52 | "Domestic Specialty",
53 | "Molson",
54 | "Canada",
55 | "23.95",
56 | beerscli.NewBeerType("Lager"),
57 | ),
58 | beerscli.NewBeer(
59 | 8520130,
60 | "Grolsch 0.0",
61 | "Non-Alcoholic Beer",
62 | "Grolsch Export B.V.",
63 | "Canada",
64 | "49.50",
65 | beerscli.NewBeerType("Non-Alcoholic Beer"),
66 | ),
67 | }, nil
68 | },
69 | }
70 |
71 | return mockedRepo
72 | }
73 |
74 | func buildMockError() beerscli.BeerRepo {
75 | mockedRepo := &mock.BeerRepoMock{
76 | GetBeersFunc: func() ([]beerscli.Beer, error) {
77 | return []beerscli.Beer{}, errors.New("error")
78 | },
79 | }
80 |
81 | return mockedRepo
82 | }
83 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/fetching/service_test.go:
--------------------------------------------------------------------------------
1 | package fetching
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
8 | "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal/storage/mock"
9 | "github.com/stretchr/testify/assert"
10 | )
11 |
12 | func TestFetchByID(t *testing.T) {
13 |
14 | tests := map[string]struct {
15 | repo beerscli.BeerRepo
16 | input int
17 | want int
18 | err error
19 | }{
20 | "valid beer": {repo: buildMockBeers(), input: 127, want: 127, err: nil},
21 | "not found beer": {repo: buildMockBeers(), input: 99999, err: errors.New("error")},
22 | "error with repository": {repo: buildMockError(), err: errors.New("error")},
23 | }
24 |
25 | for name, tc := range tests {
26 | t.Run(name, func(t *testing.T) {
27 | service := NewService(tc.repo)
28 |
29 | b, err := service.FetchByID(tc.input)
30 |
31 | if tc.err != nil {
32 | assert.Error(t, err)
33 | }
34 |
35 | if tc.err == nil {
36 | assert.Nil(t, err)
37 | }
38 |
39 | assert.Equal(t, tc.want, b.ProductID)
40 | })
41 | }
42 | }
43 |
44 | func buildMockBeers() beerscli.BeerRepo {
45 | mockedRepo := &mock.BeerRepoMock{
46 | GetBeersFunc: func() ([]beerscli.Beer, error) {
47 | return []beerscli.Beer{
48 | beerscli.NewBeer(
49 | 127,
50 | "Mad Jack Mixer",
51 | "Domestic Specialty",
52 | "Molson",
53 | "Canada",
54 | "23.95",
55 | beerscli.NewBeerType("Lager"),
56 | ),
57 | beerscli.NewBeer(
58 | 8520130,
59 | "Grolsch 0.0",
60 | "Non-Alcoholic Beer",
61 | "Grolsch Export B.V.",
62 | "Canada",
63 | "49.50",
64 | beerscli.NewBeerType("Non-Alcoholic Beer"),
65 | ),
66 | }, nil
67 | },
68 | }
69 |
70 | return mockedRepo
71 | }
72 |
73 | func buildMockError() beerscli.BeerRepo {
74 | mockedRepo := &mock.BeerRepoMock{
75 | GetBeersFunc: func() ([]beerscli.Beer, error) {
76 | return []beerscli.Beer{}, errors.New("error")
77 | },
78 | }
79 |
80 | return mockedRepo
81 | }
82 |
--------------------------------------------------------------------------------
/10-profiling/internal/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/10-profiling/internal/storage/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/10-profiling/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/storage/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/09-benchmarking/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/storage/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/08-automated_tests/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/storage/mock/repository.go:
--------------------------------------------------------------------------------
1 | // Code generated by moq; DO NOT EDIT.
2 | // github.com/matryer/moq
3 |
4 | package mock
5 |
6 | import (
7 | "sync"
8 |
9 | beerscli "github.com/CodelyTV/golang-examples/11-sharing_memory_concurrency/internal"
10 | )
11 |
12 | var (
13 | lockBeerRepoMockGetBeers sync.RWMutex
14 | )
15 |
16 | // Ensure, that BeerRepoMock does implement BeerRepo.
17 | // If this is not the case, regenerate this file with moq.
18 | var _ beerscli.BeerRepo = &BeerRepoMock{}
19 |
20 | // BeerRepoMock is a mock implementation of BeerRepo.
21 | //
22 | // func TestSomethingThatUsesBeerRepo(t *testing.T) {
23 | //
24 | // // make and configure a mocked BeerRepo
25 | // mockedBeerRepo := &BeerRepoMock{
26 | // GetBeersFunc: func() ([]beerscli.Beer, error) {
27 | // panic("mock out the GetBeers method")
28 | // },
29 | // }
30 | //
31 | // // use mockedBeerRepo in code that requires BeerRepo
32 | // // and then make assertions.
33 | //
34 | // }
35 | type BeerRepoMock struct {
36 | // GetBeersFunc mocks the GetBeers method.
37 | GetBeersFunc func() ([]beerscli.Beer, error)
38 |
39 | // calls tracks calls to the methods.
40 | calls struct {
41 | // GetBeers holds details about calls to the GetBeers method.
42 | GetBeers []struct {
43 | }
44 | }
45 | }
46 |
47 | // GetBeers calls GetBeersFunc.
48 | func (mock *BeerRepoMock) GetBeers() ([]beerscli.Beer, error) {
49 | if mock.GetBeersFunc == nil {
50 | panic("BeerRepoMock.GetBeersFunc: method is nil but BeerRepo.GetBeers was just called")
51 | }
52 | callInfo := struct {
53 | }{}
54 | lockBeerRepoMockGetBeers.Lock()
55 | mock.calls.GetBeers = append(mock.calls.GetBeers, callInfo)
56 | lockBeerRepoMockGetBeers.Unlock()
57 | return mock.GetBeersFunc()
58 | }
59 |
60 | // GetBeersCalls gets all the calls that were made to GetBeers.
61 | // Check the length with:
62 | // len(mockedBeerRepo.GetBeersCalls())
63 | func (mock *BeerRepoMock) GetBeersCalls() []struct {
64 | } {
65 | var calls []struct {
66 | }
67 | lockBeerRepoMockGetBeers.RLock()
68 | calls = mock.calls.GetBeers
69 | lockBeerRepoMockGetBeers.RUnlock()
70 | return calls
71 | }
72 |
--------------------------------------------------------------------------------
/10-profiling/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/06-error_handling/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/08-automated_tests/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/09-benchmarking/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/05-parsing_http_response/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/07-behaviour_error_handling/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/11-sharing_memory_concurrency/internal/beer.go:
--------------------------------------------------------------------------------
1 | package beerscli
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | // Beer representation of beer into data struct
8 | type Beer struct {
9 | ProductID int `json:"product_id"`
10 | Name string `json:"name"`
11 | Price string `json:"price"`
12 | BeerID int `json:"beer_id"`
13 | Category string `json:"category"`
14 | Type *BeerType `json:"type"`
15 | Brewer string `json:"brewer"`
16 | Country string `json:"country"`
17 | }
18 |
19 | type BeerType int
20 |
21 | const (
22 | Unknown BeerType = iota
23 | Lager
24 | Malt
25 | Ale
26 | FlavouredMalt
27 | Stout
28 | Porter
29 | NonAlcoholic
30 | )
31 |
32 | func (t BeerType) String() string {
33 | return toString[t]
34 | }
35 |
36 | // NewBeerType initialize a type from enum beerTypes
37 | func NewBeerType(t string) *BeerType {
38 | beerType := toID[t]
39 | return &beerType
40 | }
41 |
42 | var toString = map[BeerType]string{
43 | Lager: "Lager",
44 | Malt: "Malt",
45 | Ale: "Ale",
46 | FlavouredMalt: "Flavoured Malt",
47 | Stout: "Stout",
48 | Porter: "Stout",
49 | NonAlcoholic: "Non-Alcoholic",
50 | Unknown: "unknown",
51 | }
52 |
53 | var toID = map[string]BeerType{
54 | "Lager": Lager,
55 | "Malt": Malt,
56 | "Ale": Ale,
57 | "Flavoured Malt": FlavouredMalt,
58 | "Stout": Stout,
59 | "Porter": Porter,
60 | "Non-Alcoholic": NonAlcoholic,
61 | "unknown": Unknown,
62 | }
63 |
64 | // UnmarshalJSON convert type from json to beerType
65 | func (t *BeerType) UnmarshalJSON(b []byte) error {
66 | var j string
67 | err := json.Unmarshal(b, &j)
68 | if err != nil {
69 | return err
70 | }
71 | *t = toID[j]
72 | return nil
73 | }
74 |
75 | // BeerRepo definiton of methods to access a data beer
76 | type BeerRepo interface {
77 | GetBeers() ([]Beer, error)
78 | }
79 |
80 | // NewBeer initialize struct beer
81 | func NewBeer(productID int, name, category, brewer, country, price string, beerType *BeerType) (b Beer) {
82 | b = Beer{
83 | ProductID: productID,
84 | Name: name,
85 | Category: category,
86 | Type: beerType,
87 | Brewer: brewer,
88 | Country: country,
89 | Price: price,
90 | }
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
3 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
4 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
5 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
6 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
7 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
8 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
9 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
10 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
11 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
12 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
13 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
14 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
15 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
16 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
17 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
18 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
19 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
20 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
21 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
22 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
23 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
24 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
25 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
26 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
27 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
28 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
29 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
30 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
31 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
32 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
33 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
34 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
35 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
36 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
37 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
38 | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
39 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
40 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
41 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
42 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
43 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
44 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
45 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
46 | github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
47 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
48 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
49 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
50 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
51 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
52 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
53 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
54 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
55 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
56 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
57 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
58 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
59 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
60 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
61 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
62 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
63 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
64 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
65 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
66 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
67 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
68 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
69 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
70 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
71 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
72 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
73 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
74 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
75 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
76 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
77 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
78 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
79 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
80 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
81 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
82 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
83 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
84 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
85 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
86 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
87 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
88 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
89 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
90 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
91 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
92 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
93 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
94 | github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
95 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
96 | github.com/spf13/cobra v0.0.7 h1:FfTH+vuMXOas8jmfb5/M7dzEYx7LpcLb7a0LPe34uOU=
97 | github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
98 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
99 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
100 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
101 | github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
102 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
103 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
104 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
105 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
106 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
107 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
108 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
109 | github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
110 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
111 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
112 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
113 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
114 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
115 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
116 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
117 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
118 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
119 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
120 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
121 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
122 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
123 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
124 | golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
125 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
126 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
127 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
128 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
129 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
130 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
131 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
132 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
133 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
134 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
135 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
136 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
137 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
138 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
139 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
140 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
141 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
142 | google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
143 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
144 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
145 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
146 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
147 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
148 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
149 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
150 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
151 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
152 |
--------------------------------------------------------------------------------