diff --git a/kadai2/po3rin/.gitkeep b/kadai2/po3rin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/kadai2/po3rin/Makefile b/kadai2/po3rin/Makefile new file mode 100644 index 0000000..a665d36 --- /dev/null +++ b/kadai2/po3rin/Makefile @@ -0,0 +1,28 @@ +GOCMD=go +GOBUILD=$(GOCMD) build +GOCLEAN=$(GOCMD) clean +GOTEST=$(GOCMD) test +GOGET=$(GOCMD) get +GODOC=$(GOCMD) doc +COVERAGEFILE=coverage.out +BINARY_NAME=chext +BINARY_UNIX=$(BINARY_NAME)_unix + +all: test build +build: + $(GOBUILD) -o $(BINARY_NAME) +test: + $(GOTEST) -v ./extension/ +coverage: + $(GOTEST) -coverprofile=$(COVERAGEFILE) ./extension/ +doc: + $(GODOC) ./extension +clean: + $(GOCLEAN) + rm -f $(BINARY_NAME) + rm -f $(BINARY_UNIX) + rm -f $(COVERAGEFILE) +build-linux: + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -v +docker-build: + docker run --rm -it -v "$(GOPATH)":/go -w /go/src/bitbucket.org/rsohlich/makepost golang:latest go build -o "$(BINARY_UNIX)" -v \ No newline at end of file diff --git a/kadai2/po3rin/README.md b/kadai2/po3rin/README.md new file mode 100644 index 0000000..d50194e --- /dev/null +++ b/kadai2/po3rin/README.md @@ -0,0 +1,54 @@ +# GopherDojo Task #1 By po3rin + +This CLI convert extension of images. .png, .jpeg, .jpg and .gif is only supported. + +# Feature + +Traveling the directory structure recursively. + +## Quick Start + +There are test-images in /images directory. +default behavior is to convert jpg to png in /images directory. + +``` +$ make +$ ./chext +``` + +## Flag + +You can set arguments. + +| Flag | Description | Default | +| ---- | ---- | --- | +| -f | What images converted from | jpg | +| -t | What images converted to | png | +| -d | Designate directory that has images | . | + +following is example command with flags. This command convert jpg to gif in images/sub directory. + +``` +./chext -f jpg -t gif -d images/sub +``` + +## Doc + +following command show GoDoc + +``` +make doc +``` + +## 感想と課題 + +全パターンは Table Driven Tests を実装した。convert する全6パターンが非常に見やすくなった。しかし、mapにfor文を適用すると、書いた順番で繰り返されない仕様にハマった。for文で順番を担保するにはどうしたらいいのだろう。。 + +カバレッジは80%いくが他の20%はエラー処理。 +エラー処理もカバーする必要がある? + +サブテストとテーブル駆動テストのパターンを採用した場合、テストヘルパーを使っても呼び出し行が変わらないのであまり意味がない??そもそも使い方が間違っているかもしれない。 + +## 宿題 io.Writer と io.Reader について +io.Writer io.Readerはそれぞれインターフェースであり、抽象化されている。故に振る舞いを与えられているだけなのでFile Buffer等の様々なものに対して実装されている。 +ゆえに実装が使い回せるので、結果的にGo言語のシンプルさに貢献している。 diff --git a/kadai2/po3rin/extension/extension.go b/kadai2/po3rin/extension/extension.go new file mode 100644 index 0000000..e1ac90b --- /dev/null +++ b/kadai2/po3rin/extension/extension.go @@ -0,0 +1,60 @@ +// Package extension create & change extention of images. +package extension + +import ( + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "os" + "strings" +) + +// Arg define comand line argument +type Arg struct { + From string + To string + Path string +} + +// Convert create & convert extension of images. png jpg jpeg gif are only supported. +func (a Arg) Convert() error { + if a.From != "jpg" && a.From != "png" && a.From != "gif" { + return fmt.Errorf("%s is not supported", a.From) + } + if a.To != "jpg" && a.To != "png" && a.To != "gif" { + return fmt.Errorf("%s is not supported", a.To) + } + + file, err := os.Open(a.Path) + if err != nil { + return err + } + defer file.Close() + img, _, err := image.Decode(file) + if err != nil { + return err + } + + extention := a.To + output := strings.Replace(a.Path, a.From, "", 1) + dstfile, err := os.Create(output + extention) + if err != nil { + return err + } + defer dstfile.Close() + + switch extention { + case "jpeg", "jpg": + err = jpeg.Encode(dstfile, img, nil) + case "gif": + err = gif.Encode(dstfile, img, nil) + case "png": + err = png.Encode(dstfile, img) + } + if err != nil { + return err + } + return nil +} diff --git a/kadai2/po3rin/extension/extension_test.go b/kadai2/po3rin/extension/extension_test.go new file mode 100644 index 0000000..1b08577 --- /dev/null +++ b/kadai2/po3rin/extension/extension_test.go @@ -0,0 +1,49 @@ +package extension_test + +import ( + "dojo2/kadai2/po3rin/extension" + "strconv" + "testing" +) + +func TestArg_Convert(t *testing.T) { + testarg := []extension.Arg{ + { + From: "jpg", + To: "png", + Path: "../images/gopher.jpg", + }, { + From: "jpg", + To: "gif", + Path: "../images/gopher.jpg", + }, { + From: "pndg", + To: "jpg", + Path: "../images/gopher.png", + }, { + From: "png", + To: "gif", + Path: "../images/gopher.png", + }, { + From: "gidf", + To: "jpg", + Path: "../images/gopher.gif", + }, { + From: "gif", + To: "png", + Path: "../images/gopher.gif", + }, + } + for i, v := range testarg { + t.Run("test"+strconv.Itoa(i), func(t *testing.T) { + helperConvert(v, t) + }) + } +} + +func helperConvert(v extension.Arg, t *testing.T) { + t.Helper() + if err := v.Convert(); err != nil { + t.Errorf("failed test %#v", err) + } +} diff --git a/kadai2/po3rin/images/gopher.gif b/kadai2/po3rin/images/gopher.gif new file mode 100644 index 0000000..723c0d9 Binary files /dev/null and b/kadai2/po3rin/images/gopher.gif differ diff --git a/kadai2/po3rin/images/gopher.jpg b/kadai2/po3rin/images/gopher.jpg new file mode 100644 index 0000000..0ad29f9 Binary files /dev/null and b/kadai2/po3rin/images/gopher.jpg differ diff --git a/kadai2/po3rin/images/gopher.png b/kadai2/po3rin/images/gopher.png new file mode 100644 index 0000000..33c2410 Binary files /dev/null and b/kadai2/po3rin/images/gopher.png differ diff --git a/kadai2/po3rin/images/sub/gopher-sub.gif b/kadai2/po3rin/images/sub/gopher-sub.gif new file mode 100644 index 0000000..7384514 Binary files /dev/null and b/kadai2/po3rin/images/sub/gopher-sub.gif differ diff --git a/kadai2/po3rin/images/sub/gopher-sub.jpg b/kadai2/po3rin/images/sub/gopher-sub.jpg new file mode 100644 index 0000000..98afdf4 Binary files /dev/null and b/kadai2/po3rin/images/sub/gopher-sub.jpg differ diff --git a/kadai2/po3rin/images/sub/gopher-sub.png b/kadai2/po3rin/images/sub/gopher-sub.png new file mode 100644 index 0000000..d374076 Binary files /dev/null and b/kadai2/po3rin/images/sub/gopher-sub.png differ diff --git a/kadai2/po3rin/main.go b/kadai2/po3rin/main.go new file mode 100644 index 0000000..93ef54d --- /dev/null +++ b/kadai2/po3rin/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "dojo2/kadai2/po3rin/extension" + "flag" + "log" + "os" + "path/filepath" +) + +func main() { + from := flag.String("f", "jpg", "what encode from") + to := flag.String("t", "png", "what encode to") + dir := flag.String("d", ".", "target dir") + flag.Parse() + + err := filepath.Walk(*dir, func(path string, info os.FileInfo, err error) error { + if filepath.Ext(path) == "."+*from { + arg := extension.Arg{ + From: *from, + To: *to, + Path: path, + } + return arg.Convert() + } + return nil + }) + if err != nil { + log.Fatal(err) + os.Exit(1) + } +}