Skip to content

Commit

Permalink
Issue 1
Browse files Browse the repository at this point in the history
- fix typo in documentation
- add golint image
- add golint to Makefile
- add comments to source code for golint
- fix goreport badge link
  • Loading branch information
insidieux committed Dec 18, 2020
1 parent 308fa19 commit d2d5100
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 12 deletions.
24 changes: 22 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,34 @@ wire:
wire:custom \
/project/...

.PHONY: lint
lint:
.PHONY: lint-golangci-lint
lint-golangci-lint:
@docker run --rm \
-v ${PWD}:/project \
-w /project \
golangci/golangci-lint:v1.33.0 \
golangci-lint run -v

.PHONY: lint-golint
lint-golint:
@docker build \
--build-arg GO_VERSION=${GO_VERSION} \
-f ${PWD}/build/docker/utils/golint/Dockerfile \
-t golint:custom \
build/docker/utils/golint
@docker run --rm \
-v ${PWD}:/project \
-w /project \
golint:custom \
/project/pkg/... \
/project/internal/... \
/project/cmd/...

.PHONY: lint
lint:
@make lint-golangci-lint
@make lint-golint

.PHONY: test
test:
@rm -r ${PWD}/test/coverage.out || true
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Service discovering and registry bridge.

[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/insidieux/pinchy/CI?style=flat-square)](https://github.com/insidieux/pinchy/actions?query=workflow%3ACI)
[![Go Report Card](https://goreportcard.com/badge/github.com/insidieux/pinchy?style=flat-square)](https://goreportcard.com/report/github.com/insidieux/pinchy)
[![Go Report Card](https://goreportcard.com/badge/github.com/insidieux/pinchy)](https://goreportcard.com/report/github.com/insidieux/pinchy)
[![codecov](https://codecov.io/gh/insidieux/pinchy/branch/master/graph/badge.svg?token=BI6HEMPLB1)](https://codecov.io/gh/insidieux/pinchy/branch/master)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/insidieux/pinchy)

Expand All @@ -20,7 +20,7 @@ Supported pluggable service registries:
Install Pinchy by running:

```shell
go get github.com/insidiuex/pinchy/cmd/pinchy
go get github.com/insidieux/pinchy/cmd/pinchy
```

Ensure that `$GOPATH/bin` is added to your `$PATH`.
Expand All @@ -37,4 +37,4 @@ Ensure that `$GOPATH/bin` is added to your `$PATH`.

[Apache][]

[Apache]: ./LICENSE
[Apache]: ./LICENSE
6 changes: 6 additions & 0 deletions build/docker/utils/golint/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ARG GO_VERSION=1.15
FROM golang:${GO_VERSION}

RUN go get -u -t golang.org/x/lint/golint

ENTRYPOINT ["/go/bin/golint"]
2 changes: 2 additions & 0 deletions cmd/pinchy/internal/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const (
name = `pinchy`
)

// NewCommand provide root cobra.Command
// Root command contains pre-generated subcommands for all registered core.Source and core.Registry
func NewCommand(version string) *cobra.Command {
rootCommand := &cobra.Command{
Use: name,
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ docker pull docker.pkg.github.com/insidieux/pinchy
Alternatively, you can use the go get method:

```shell
go get github.com/insidiuex/pinchy/cmd/pinchy
go get github.com/insidieux/pinchy/cmd/pinchy
```

Ensure that `$GOPATH/bin` is added to your `$PATH`.
Expand Down
3 changes: 3 additions & 0 deletions internal/extension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
)

type (
// RegisterError is custom implementation of error interface
RegisterError []error
)

// String return all error message like string with ";" delimiter
func (re RegisterError) String() string {
var slice []string
for _, err := range re {
Expand All @@ -16,6 +18,7 @@ func (re RegisterError) String() string {
return strings.Join(slice, `; `)
}

// Error is implementation of error interface
func (re RegisterError) Error() string {
return re.String()
}
26 changes: 24 additions & 2 deletions internal/extension/registry/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,24 @@ const (
)

type (
Factory func(*viper.Viper) (core.Registry, func(), error)
// Factory is helper function to provide core.Registry implementation.
// Function MUST return (core.Registry, func(), error) for further call with google.wire
Factory func(*viper.Viper) (core.Registry, func(), error)

// ProviderInterface contains main information about extension.
// Name is used for unique registration and validation
// Flags used for provide cobra.Command flags
// Factory used in generation main command source code with google.wire
ProviderInterface interface {
Name() string
Flags() *pflag.FlagSet
Factory() Factory
}

// ProviderList is helper custom type for handle registration and lookup for slice of ProviderInterface
ProviderList []ProviderInterface
provider struct {

provider struct {
name string
flags *pflag.FlagSet
factory Factory
Expand All @@ -34,18 +44,24 @@ var (
providerList = newProviderList()
)

// newProviderList return new empty ProviderList
func newProviderList() *ProviderList {
return new(ProviderList)
}

// GetProviderList return internal ProviderList with pre-registered slice of ProviderInterface
func GetProviderList() ProviderList {
return *providerList
}

// MakeFlagName is helper for generation valid flag name
func MakeFlagName(name string) string {
return fmt.Sprintf(`%s.%s`, flagPrefix, name)
}

// Register new ProviderInterface implementation by name, flags and factory
// Register returns error if ProviderInterface already registered with same name
// Register returns error if ProviderInterface provide flags with incorrect name prefix
func Register(name string, flags *pflag.FlagSet, factory Factory) error {
return providerList.register(&provider{
name: name,
Expand All @@ -54,14 +70,17 @@ func Register(name string, flags *pflag.FlagSet, factory Factory) error {
})
}

// Name return ProviderInterface implementation name
func (p *provider) Name() string {
return p.name
}

// Name return ProviderInterface implementation flags
func (p *provider) Flags() *pflag.FlagSet {
return p.flags
}

// Name return ProviderInterface implementation factory
func (p *provider) Factory() Factory {
return p.factory
}
Expand All @@ -83,6 +102,8 @@ func (pl *ProviderList) register(p ProviderInterface) error {
return nil
}

// Lookup return registered ProviderInterface by name
// Lookup return error if ProviderInterface was not registered with called name
func (pl ProviderList) Lookup(name string) (ProviderInterface, error) {
for _, p := range pl {
if p.Name() == name {
Expand All @@ -92,6 +113,7 @@ func (pl ProviderList) Lookup(name string) (ProviderInterface, error) {
return nil, errors.Errorf(`registry provider with name "%s" was not registered`, name)
}

// Get return slice of registered ProviderInterface's
func (pl ProviderList) Get() []ProviderInterface {
return pl
}
26 changes: 24 additions & 2 deletions internal/extension/source/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,24 @@ const (
)

type (
Factory func(*viper.Viper) (core.Source, func(), error)
// Factory is helper function to provide core.Source implementation.
// Function MUST return (core.Source, func(), error) for further call with google.wire
Factory func(*viper.Viper) (core.Source, func(), error)

// ProviderInterface contains main information about extension.
// Name is used for unique registration and validation
// Flags used for provide cobra.Command flags
// Factory used in generation main command source code with google.wire
ProviderInterface interface {
Name() string
Flags() *pflag.FlagSet
Factory() Factory
}

// ProviderList is helper custom type for handle registration and lookup for slice of ProviderInterface
ProviderList []ProviderInterface
provider struct {

provider struct {
name string
flags *pflag.FlagSet
factory Factory
Expand All @@ -34,18 +44,24 @@ var (
providerList = newProviderList()
)

// newProviderList return new empty ProviderList
func newProviderList() *ProviderList {
return new(ProviderList)
}

// GetProviderList return internal ProviderList with pre-registered slice of ProviderInterface
func GetProviderList() ProviderList {
return *providerList
}

// MakeFlagName is helper for generation valid flag name
func MakeFlagName(name string) string {
return fmt.Sprintf(`%s.%s`, flagPrefix, name)
}

// Register new ProviderInterface implementation by name, flags and factory
// Register return error if ProviderInterface already registered with same name
// Register return error if ProviderInterface provide flags with incorrect name prefix
func Register(name string, flags *pflag.FlagSet, factory Factory) error {
return providerList.register(&provider{
name: name,
Expand All @@ -54,14 +70,17 @@ func Register(name string, flags *pflag.FlagSet, factory Factory) error {
})
}

// Name return ProviderInterface implementation name
func (p *provider) Name() string {
return p.name
}

// Name return ProviderInterface implementation flags
func (p *provider) Flags() *pflag.FlagSet {
return p.flags
}

// Name return ProviderInterface implementation factory
func (p *provider) Factory() Factory {
return p.factory
}
Expand All @@ -83,6 +102,8 @@ func (pl *ProviderList) register(p ProviderInterface) error {
return nil
}

// Lookup return registered ProviderInterface by name
// Lookup return error if ProviderInterface was not registered with called name
func (pl ProviderList) Lookup(name string) (ProviderInterface, error) {
for _, p := range pl {
if p.Name() == name {
Expand All @@ -92,6 +113,7 @@ func (pl ProviderList) Lookup(name string) (ProviderInterface, error) {
return nil, errors.Errorf(`source provider with name "%s" was not registered`, name)
}

// Get return slice of registered ProviderInterface's
func (pl ProviderList) Get() []ProviderInterface {
return pl
}
3 changes: 3 additions & 0 deletions pkg/core/logger.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

type (
// LoggerInterface provides common log methods. This is replica for logrus.FieldLogger.
LoggerInterface interface {
Debugf(format string, args ...interface{})
Infof(format string, args ...interface{})
Expand Down Expand Up @@ -29,6 +30,8 @@ type (
Fatalln(args ...interface{})
Panicln(args ...interface{})
}

// Loggable determine possibility to inject LoggerInterface. Can be used to wire Source and Registry implementations
Loggable interface {
WithLogger(LoggerInterface)
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/core/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,27 @@ import (
)

type (
// ManagerInterface is main unit between Source and Registry.
// Implementation must provide full cycle for fetch services from Source and register them into Registry.
ManagerInterface interface {
Run(ctx context.Context) error
}

// Manager is built-in ManagerInterface implementation.
Manager struct {
source Source
registry Registry
logger LoggerInterface
exitOnError ManagerExitOnError
}

// ManagerExitOnError provide information how to handle errors and panics during manager.Run process.
ManagerExitOnError bool
managerError []error

managerError []error
)

// NewManager provider built-in ManagerInterface implementation
func NewManager(source Source, registry Registry, logger LoggerInterface, exitOnError ManagerExitOnError) ManagerInterface {
return &Manager{
source: source,
Expand All @@ -32,6 +40,12 @@ func NewManager(source Source, registry Registry, logger LoggerInterface, exitOn
}
}

// Run contains next steps
// - Call Source.Fetch
// - Call Registry.Fetch
// - Check orphan Services fetched from Registry
// - Remove orphan Services
// - Register Services fetched from Source
func (m *Manager) Run(ctx context.Context) error {
incoming, err := m.source.Fetch(ctx)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions pkg/core/registry/consul/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,27 @@ import (
)

type (
// Agent interface provide common function for work with Consul HTTP API
Agent interface {
Services() (map[string]*api.AgentService, error)
ServiceRegister(service *api.AgentServiceRegistration) error
ServiceDeregister(serviceID string) error
}

// Registry is implementation of core.Registry interface
Registry struct {
agent Agent
}
)

// NewRegistry provide Registry as core.Registry implementation
func NewRegistry(agent Agent) *Registry {
return &Registry{
agent: agent,
}
}

// Fetch make request for Agent.Services and try to cast result to core.Services
func (r *Registry) Fetch(_ context.Context) (core.Services, error) {
registered, err := r.agent.Services()
if err != nil {
Expand All @@ -52,13 +57,15 @@ func (r *Registry) Fetch(_ context.Context) (core.Services, error) {
return result, nil
}

// Deregister make request for Agent.ServiceDeregister by core.Service RegistrationID
func (r *Registry) Deregister(_ context.Context, serviceID string) error {
if err := r.agent.ServiceDeregister(serviceID); err != nil {
return errors.Wrapf(err, `failed deregister service by service id "%s"`, serviceID)
}
return nil
}

// Register make request for Agent.ServiceRegister for core.Service
func (r *Registry) Register(ctx context.Context, service *core.Service) error {
if err := service.Validate(ctx); err != nil {
return errors.Wrap(err, `service has validation error before registration`)
Expand Down
Loading

0 comments on commit d2d5100

Please sign in to comment.