Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce s3hub command interactive UI without logic #6

Merged
merged 11 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ linters:
- goconst
- gocritic
- goimports
- gomnd
- gosec
- ifshort
- misspell
Expand Down
2 changes: 1 addition & 1 deletion .octocov.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# generated by octocov init
coverage:
if: true
acceptable: 60%
# acceptable: 60%
diff:
datastores:
- artifact://${GITHUB_REPOSITORY}
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ VERSION = $(shell git describe --tags --abbrev=0)
GO = go
GO_BUILD = $(GO) build
GO_INSTALL = $(GO) install
GO_TEST = $(GO) test -v
GO_TEST = hottest -v
GO_TOOL = $(GO) tool
GO_DEP = $(GO) mod
GOOS = ""
Expand All @@ -29,6 +29,8 @@ changelog: ## Generate changelog

tools: ## Install dependency tools
$(GO_INSTALL) github.com/Songmu/ghch/cmd/ghch@latest
$(GO_INSTALL) github.com/nao1215/hottest@latest
$(GO_INSTALL) github.com/google/wire/cmd/wire@latest

.DEFAULT_GOAL := help
help:
Expand Down
Empty file removed app/.gitkeep
Empty file.
39 changes: 39 additions & 0 deletions app/di/wire.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//go:build wireinject
// +build wireinject

// Package di Inject dependence by wire command.
package di

import (
"context"

"github.com/google/wire"
"github.com/nao1215/rainbow/app/domain/model"
"github.com/nao1215/rainbow/app/external"
"github.com/nao1215/rainbow/app/interactor"
"github.com/nao1215/rainbow/app/usecase"
)

// S3App is the application service for S3.
type S3App struct {
// S3BucketCreator is the usecase for creating a new S3 bucket.
S3BucketCreator usecase.S3BucketCreator
}

// NewS3App creates a new S3App.
func NewS3App(ctx context.Context, profile model.AWSProfile, region model.Region) (*S3App, error) {
wire.Build(
model.NewAWSConfig,
external.NewS3Client,
external.S3BucketCreatorSet,
interactor.S3bucketCreatorSet,
newS3App,
)
return nil, nil
}

func newS3App(s3bucketCreator usecase.S3BucketCreator) *S3App {
return &S3App{
S3BucketCreator: s3bucketCreator,
}
}
47 changes: 47 additions & 0 deletions app/di/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions app/domain/model/aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package model

import (
"context"
"os"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
)

// AWSProfile is the name of the AWS profile.
type AWSProfile string

// NewAWSProfile returns a new AWSProfile.
// If p is empty, read $AWS_PROFILE and return it.
func NewAWSProfile(p string) AWSProfile {
if p == "" {
profile := os.Getenv("AWS_PROFILE")
if profile == "" {
return AWSProfile("default")
}
return AWSProfile(profile)
}
return AWSProfile(p)
}

// String returns the string representation of the AWSProfile.
func (p AWSProfile) String() string {
return string(p)
}

// AWSConfig is the AWS config.
type AWSConfig struct {
*aws.Config
}

// NewAWSConfig creates a new AWS config.
func NewAWSConfig(ctx context.Context, profile AWSProfile, region Region) (*AWSConfig, error) {
opts := []func(*config.LoadOptions) error{}
if profile.String() != "" {
opts = append(opts, config.WithSharedConfigProfile(profile.String()))
}
if region.String() != "" {
opts = append(opts, config.WithRegion(region.String()))
}

cfg, err := config.LoadDefaultConfig(ctx, opts...)
if err != nil {
return nil, err
}
return &AWSConfig{
Config: &cfg,
}, nil
}

// Region returns the AWS region.
func (c *AWSConfig) Region() Region {
if Region(c.Config.Region) == "" {
return RegionUSEast1
}
return Region(c.Config.Region)
}
76 changes: 76 additions & 0 deletions app/domain/model/aws_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package model

import (
"testing"
)

func TestNewAWSProfile(t *testing.T) { //nolint
type args struct {
p string
}
tests := []struct {
name string
args args
want AWSProfile
}{
{
name: "success",
args: args{
p: "test",
},
want: AWSProfile("test"),
},
{
name: "success. p is empty",
args: args{
p: "",
},
want: AWSProfile("from env"),
},
{
name: "success. p is empty and $AWS_PROFILE is empty",
args: args{
p: "",
},
want: AWSProfile("default"),
},
}
for _, tt := range tests { //nolint
if tt.name == "success. p is empty" {
t.Setenv("AWS_PROFILE", "from env")
} else if tt.name == "success. p is empty and $AWS_PROFILE is empty" {
t.Setenv("AWS_PROFILE", "")
}

t.Run(tt.name, func(t *testing.T) {
if got := NewAWSProfile(tt.args.p); got != tt.want {
t.Errorf("NewAWSProfile() = %v, want %v", got, tt.want)
}
})
}
}

func TestAWSProfileString(t *testing.T) {
t.Parallel()

tests := []struct {
name string
p AWSProfile
want string
}{
{
name: "success",
p: AWSProfile("test"),
want: "test",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.p.String(); got != tt.want {
t.Errorf("AWSProfile.String() = %v, want %v", got, tt.want)
}
})
}
}
12 changes: 12 additions & 0 deletions app/domain/model/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package model

import "errors"

var (
// ErrInvalidRegion is an error that occurs when the region is invalid.
ErrInvalidRegion = errors.New("invalid region")
// ErrEmptyRegion is an error that occurs when the region is empty.
ErrEmptyRegion = errors.New("region is empty")
// ErrInvalidBucketName is an error that occurs when the bucket name is invalid.
ErrInvalidBucketName = errors.New("bucket name is invalid")
)
10 changes: 10 additions & 0 deletions app/domain/model/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package model

// Validator is an interface that represents a validator.
type Validator interface {
// Validate validates the value.
Validate() error
}

// ValidationFunc is a type that represents a validation function.
type ValidationFunc func() error
Loading