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

【課題2】 #19

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
dcf9736
ディレクトリ構造の定義
nasjp Sep 4, 2019
40bd1cb
基本機能の実装
nasjp Sep 4, 2019
a0609ad
README を修正
nasjp Sep 4, 2019
fef87be
makefile の軽微な修正
nasjp Sep 4, 2019
7220a74
READMEの修正
nasjp Sep 4, 2019
7491341
再帰的な処理を追加
nasjp Sep 5, 2019
42b4229
テストデータを修正
nasjp Sep 5, 2019
6198663
file format のチェックを插入
nasjp Sep 5, 2019
9a727db
READMEを修正
nasjp Sep 5, 2019
6c8c679
変換部分を分離
nasjp Sep 6, 2019
2c9f4fc
バグを修正
nasjp Sep 6, 2019
f2c2275
decode 部分を切り出し
nasjp Sep 6, 2019
60b5580
関数名を修正
nasjp Sep 6, 2019
4f04858
ファイルタイプを大文字定数に
nasjp Sep 6, 2019
4acd90b
定数名を修正
nasjp Sep 6, 2019
6e17cda
絶対パス取得の役割をcmd配下に移管
nasjp Sep 6, 2019
39002c4
変換データを返す
nasjp Sep 6, 2019
16edc03
TODO を削除
nasjp Sep 6, 2019
11d72e9
存在しないパスを指定されたときの処理を修正
nasjp Sep 6, 2019
a33a43e
フラグを追加し、デバッグ用ログ処理を削除
nasjp Sep 6, 2019
18e2aa0
成功ログを修正
nasjp Sep 6, 2019
f6e4deb
gifに対応
nasjp Sep 6, 2019
4875c89
コメントを整備
nasjp Sep 6, 2019
5d3419a
flag を修正
nasjp Sep 6, 2019
159371e
コメント及び空行を整備
nasjp Sep 6, 2019
e32bce2
flag メッセージを修正
nasjp Sep 6, 2019
999092c
README を修正
nasjp Sep 6, 2019
c8897bf
README を修正
nasjp Sep 6, 2019
d3c9523
わかりにくい処理にコメントを追記
nasjp Sep 6, 2019
508cee9
画像のバイナリを変更
nasjp Sep 6, 2019
cacf35d
エラー処理の追加
nasjp Sep 9, 2019
17aeea2
コメントを追加
nasjp Sep 9, 2019
8c4a9d2
Makefile のGOMODULE修正
nasjp Sep 10, 2019
1a20f62
コメントを位置を修正
nasjp Sep 10, 2019
c0e3072
NewConfig にテストを追加
nasjp Sep 10, 2019
a84147d
TestGetImageFormatを作成
nasjp Sep 10, 2019
e8aaf4f
imachan package に testdata dir を追加
nasjp Sep 11, 2019
c4be7cc
TestConvert を追加
nasjp Sep 11, 2019
30810b6
TestConfigConvertRec の作成
nasjp Sep 11, 2019
404ae0d
バグ修正
nasjp Sep 11, 2019
4c244dc
関数名をパブリックに
nasjp Sep 11, 2019
f44430f
TestConvertTO... を作成
nasjp Sep 11, 2019
7cb5261
TestConfigConvertRec のサブテスト追加
nasjp Sep 11, 2019
8bbd2ef
SetupTest で Create Dir に対応する
nasjp Sep 11, 2019
67493c2
テストケースを追加
nasjp Sep 14, 2019
a91f5ae
ディレクリを修正
nasjp Sep 14, 2019
5f71a1d
課題2-1を追加
nasjp Sep 14, 2019
acea922
Helperメソッドを使用
nasjp Sep 14, 2019
56df0d5
大文字 format に対応する
nasjp Sep 14, 2019
d4cbc21
file create時にerr処理を実行
nasjp Sep 14, 2019
595fcd2
defer の err処理バグを修正
nasjp Sep 15, 2019
d5371cb
defer の err 処理でべつのエラーが入ってることを考慮
nasjp Sep 15, 2019
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
File renamed without changes.
35 changes: 35 additions & 0 deletions kadai2/nas/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# CONST
BINARYNAME=imachan

export GO111MODULE=auto

# command
.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

.PHONY: build
build: ## go build
go build -v ./cmd/${BINARYNAME}

.PHONY: test
test: ## go test
go test -v -cover ./pkg/${BINARYNAME}

.PHONY: clean
clean: ## go clean
go clean -cache -testcache

.PHONY: analyze
analyze: ## do static code analysis
goimports -l -w .
go vet ./...
golint ./...

.PHONY: remove
remove: ## remove binary and test output data
rm -f ./${BINARYNAME}
find testdata -type f -not -name *.jpg | xargs rm

.PHONY: all
all: remove clean test analyze build ## run 'build' with 'remove', 'clean', 'test' and 'analyze'
72 changes: 72 additions & 0 deletions kadai2/nas/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# imachan

## imachan is the CLI tool to convert images

## How to build

```sh
$ cd kadai1/nas
$ make build
```

## Can convert images under the directories

```sh
$ find .
.
./cmd
./cmd/imachan
./cmd/imachan/main.go
./testdata
./testdata/go2.jpg // jpg file
./testdata/sub
./testdata/sub/go3.jpg // jpg file
./testdata/go.jpg // jpg file
./Makefile
./README.md
./pkg
./pkg/imachan
./pkg/imachan/imachan_test.go
./pkg/imachan/imachan.go

$ ./imachan
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go.png
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go2.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go2.png
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/sub/go3.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/sub/go3.png
```

## Can choose the taget directory

```sh
$ ./imachan -d testdata
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go.png
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go2.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go2.png
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/sub/go3.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/sub/go3.png
```

## Can choose the image format
```sh
$ ./imachan -f jpg -t gif
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go.gif
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go2.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/go2.gif
success : path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/sub/go3.jpg -> path/to/github.com/gopherdojo/dojo7/kadai1/nas/testdata/sub/go3.gif
```

---

# 【TRY】画像変換コマンドを作ろう

## 次の仕様を満たすコマンドを作って下さい

- [x] ディレクトリを指定する
- [x] 指定したディレクトリ以下のJPGファイルをPNGに変換(デフォルト)
- [x] ディレクトリ以下は再帰的に処理する
- [x] 変換前と変換後の画像形式を指定できる(オプション)

## 以下を満たすように開発してください

- [x] mainパッケージと分離する
- [x] 自作パッケージと標準パッケージと準標準パッケージのみ使う
- 準標準パッケージ:golang.org/x以下のパッケージ
- [x] ユーザ定義型を作ってみる
- [x] GoDocを生成してみる
71 changes: 71 additions & 0 deletions kadai2/nas/cmd/imachan/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"flag"
"fmt"
"os"
"path/filepath"

"github.com/gopherdojo/dojo7/kadai2/nas/pkg/imachan"
)

// exit codes
const (
ExitCodeOK = 0
ExitCodeErr = 3
)

var usage = `imachanは指定のディレクトリ配下の画像を変換する CLI ツールです。
変換元の画像形式および変換先の画像形式を指定できます。

Usage:
imachan [flags]

Flags:
-d string select target file or directory (default: ./)
-f string select extension of image converted from (default: jpg)
-t string select extension of image converted to (default: png)
`

func main() {
err := run()
if err != nil {
os.Exit(ExitCodeErr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラーメッセージは出さない?

return
}
os.Exit(ExitCodeOK)
}

func run() error {
var (
dir string
fromFormat string
toFormat string
)

flag.Usage = func() {
fmt.Print(usage)
}

flag.StringVar(&dir, "d", ".", "target directory")
flag.StringVar(&fromFormat, "f", "jpg", "converted from")
flag.StringVar(&toFormat, "t", "png", "converted to")
flag.Parse()

path, err := filepath.Abs(dir)
if err != nil {
return err
}
c, err := imachan.NewConfig(path, fromFormat, toFormat)
if err != nil {
return err
}
data, err := c.ConvertRec()
if err != nil {
return err
}
for _, dd := range data {
fmt.Printf("success : %s -> %s\n", dd["from"], dd["to"])
}
return nil
}
157 changes: 157 additions & 0 deletions kadai2/nas/doc/homework.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# io.Readerとio.Writerについて調べてみよう

- 標準パッケージでどのように使われているか

- io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる

---

## 標準パッケージでどのように使われているか

### 1. `io.Reader`は下記のように定義されている

```go
type Reader interface {
Read(p []byte) (n int, err error)
}
```

`fmt.Fscan` は引数に `io.Reader` をとる

```go
func Fscan(r io.Reader, a ...interface{}) (n int, err error) {
s, old := newScanState(r, true, false)
n, err = s.doScan(a)
s.free(old)
return
}
```

`fmt.Scan`で`fmt.Fscan`に`os.Stdin`を渡している
```go
func Scan(a ...interface{}) (n int, err error) {
return Fscan(os.Stdin, a...)
}
```


`os.Stdin` は下記のように定義されている
```go
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
...
...
)
```

`os.NewFile` は `*os.File` を返す
```go
func NewFile(fd uintptr, name string) *File {
kind := kindNewFile
if nb, err := unix.IsNonblock(int(fd)); err == nil && nb {
kind = kindNonBlock
}
return newFile(fd, name, kind)
}
```

`*os.File` は `io.Reader` を実装している

```go
func (f *File) Read(b []byte) (n int, err error) {
if err := f.checkValid("read"); err != nil {
return 0, err
}
n, e := f.read(b)
return n, f.wrapErr("read", e)
}
```

そのため`fmt.Fscan` は引数に `os.Stdin` を取れる


### 2. `io.Writer`は下記のように定義されている

```go
type Writer interface {
Write(p []byte) (n int, err error)
}
```

`fmt.Fprint`は`io.Writer`を引数に取る

```go
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
p := newPrinter()
p.doPrint(a)
n, err = w.Write(p.buf)
p.free()
return
}
```

`fmt.Print`で`fmt.Fprint`に`os.Stdout`を渡している

```go
func Print(a ...interface{}) (n int, err error) {
return Fprint(os.Stdout, a...)
}
```


`os.Stdout` は下記のように定義されている

```go
var (
...
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
...
)
```

`os.NewFile` は `*os.File` を返す
```go
func NewFile(fd uintptr, name string) *File {
kind := kindNewFile
if nb, err := unix.IsNonblock(int(fd)); err == nil && nb {
kind = kindNonBlock
}
return newFile(fd, name, kind)
}
```

`*os.File` は `io.Reader` を実装している

```go
func (f *File) Write(b []byte) (n int, err error) {
if err := f.checkValid("write"); err != nil {
return 0, err
}
n, e := f.write(b)
if n < 0 {
n = 0
}
if n != len(b) {
err = io.ErrShortWrite
}

epipecheck(f, e)

if e != nil {
err = f.wrapErr("write", e)
}

return n, err
}
```

そのため`fmt.Fprint` は引数に `os.Stdout` を取れる


## io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる

- 幅広い箇所に拡張が可能
- `http`パッケージや`bytes`パッケージ 、`strings`パッケージで使用されている

- Mock テストが用意になる
- 標準入出力の代わりにバイトで渡すということが可能
Binary file added kadai2/nas/godoc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading