golangでtemplate(html)の確認
ページを表示する際はテンプレートを使用する
標準では"text/template"と"html/template"が存在する
※他にもあるかもしれないけどあとでやる
参考
Go言語でhttpサーバーを立ち上げてHello Worldをする - Qiita
template - The Go Programming Language
golang で html/template でのテンプレートの継承と、HTML エスケープしないで変数を出力する方法 (Django, Jinja みたいに) - Qiita
[Go言語] templateパッケージでtwigとかのextends的なあれをやるにはどうしようか - Qiita
シンプルなテンプレート
構造
$ tree . ├── main.go └── templates └── index.tpl $
templates/index.tpl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link}} </div> </body> </html>
※テンプレートは中括弧("{}")で挟むようです
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // テンプレート用のファイルを読み込む tpl, err1 := template.ParseFiles("templates/index.tpl") if err1 != nil { panic(err1) } // テンプレートを出力 err2 := tpl.Execute(w, struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
ページをひらくとこうなる
一部のデータを加工する
templates/index.tpl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link | safe}} </div> <div> Link: {{.Link | lock}} </div> </body> </html>
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // 独自関数でエスケープを解除 funcMap := template.FuncMap{ "safe": func(text string) template.HTML { return template.HTML(text) }, "lock": func(text string) string { return "@@[" + text + "]@@" }, } // テンプレート用のファイルを読み込む tpl, _:= template.New("index.tpl").Funcs(funcMap).ParseFiles("templates/index.tpl") // テンプレートを出力 err2 := tpl.Execute(w, struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
結果
複数のテンプレートをファイルを使用する
構成
. ├── main.go └── templates ├── base.tpl └── contents.tpl
templates/base.tpl
{{ define "base" }} <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> {{ template "contents" . }} </div> </body> </html> {{ end }}
templates/contents.tpl
{{ define "contents" }} <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link | safe}} </div> <div> Link: {{.Link | lock}} </div> {{ end }}
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // 独自関数でエスケープを解除 funcMap := template.FuncMap{ "safe": func(text string) template.HTML { return template.HTML(text) }, "lock": func(text string) string { return "@@[" + text + "]@@" }, } // テンプレート用のファイルを読み込む tpl := template.Must(template.New("hoge").Funcs(funcMap).ParseFiles("templates/base.tpl", "templates/contents.tpl")) // テンプレートを出力 err2 := tpl.ExecuteTemplate(w, "base", struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
頭パンクしそう(´・ω・`)
所感
やり方自体はパターンがあるからそのうち理解出来ていくと思うけどgo言語の書き方に慣れていないことや日本語のマニュアルがないのかエラーの意味をうまく理解できていないことがある。
いろいろ参考になりそうなソースがネットで検索したら出てくるので参考にしながらやっていくしかない
golangで超簡単なサーバ
実装
sample
package main import ( "fmt" "net/http" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "Golang Http Server") }) http.ListenAndServe(":8080", nil) }
↓
こんだけ
所感
やり方はnodejsと同じイメージかな…
jsonとかを扱う方法とかもちょっと調べておく
golangの学習(time)
日時に関する情報を制御する
timeパッケージを使用する
参考
https://golang.org/pkg/time/#Now
http://ashitani.jp/golangtips/tips_time.html
http://tdoc.info/blog/2013/04/10/go_time.html
現在日時を取得する
sample
package main import ( "fmt" "time" ) func main(){ _now := time.Now() fmt.Println(_now) }
↓
$ go run time1.go 2016-01-19 22:46:07.181469119 +0900 JST $
日時を任意のフォーマットで表示する
https://golang.org/src/time/format.go
※フォーマットの指定値がややこしいので気をつけないといけない
sample
package main import ( "fmt" "time" ) func main(){ // 現在日時を取得 _now := time.Now() // format const YYYYMMDDHHMISS1 = "2006/01/02 15:04:05" const YYYYMMDDHHMISS2 = "06-1-2 3:4:5" fmt.Println(_now.Format(YYYYMMDDHHMISS1)) fmt.Println(_now.Format(YYYYMMDDHHMISS2)) fmt.Println(_now.Format(time.RFC3339)) }
↓
$ go run time2.go 2016/01/19 22:56:21 16-1-19 10:56:21 2016-01-19T22:56:21+09:00 $
Unixタイムスタンプの秒数を取得
ちょっと意味は違うかも…
sanmple
package main import ( "fmt" "time" ) func main(){ _now := time.Now() fmt.Println(_now.Unix()) fmt.Println(_now.UnixNano()) }
↓
$ go run time3.go 1453212000 1453212000553662868 $
日付加算
日数、月数、年数を指定して加算、減算を行う
sample
package main import ( "fmt" "time" ) func main(){ // 現在の日時を取得 _now := time.Now() fmt.Println(_now) fmt.Println("") // 日付計算 fmt.Println(_now.AddDate(0, 0, 10).Format(time.RFC3339)) fmt.Println(_now.AddDate(0, 2, 0).Format(time.RFC3339)) fmt.Println(_now.AddDate(5, 0, 0).Format(time.RFC3339)) fmt.Println("") fmt.Println(_now.AddDate(0, 0, -10).Format(time.RFC3339)) fmt.Println(_now.AddDate(0, -2, 0).Format(time.RFC3339)) fmt.Println(_now.AddDate(-5, 0, 0).Format(time.RFC3339)) }
↓
$ go run time5.go 2016-01-19 23:06:58.719504358 +0900 JST 2016-01-29T23:06:58+09:00 2016-03-19T23:06:58+09:00 2021-01-19T23:06:58+09:00 2016-01-09T23:06:58+09:00 2015-11-19T23:06:58+09:00 2011-01-19T23:06:58+09:00 $
時間加算
時間を指定して加算、減算を行う
sample
package main import ( "fmt" "time" ) func main(){ // 現在の日時を取得 _now := time.Now() fmt.Println(_now) fmt.Println("") // 日付計算 fmt.Println(_now.Add(time.Duration(25) * time.Second).Format(time.RFC3339)) fmt.Println(_now.Add(time.Duration(12) * time.Minute).Format(time.RFC3339)) fmt.Println(_now.Add(time.Duration(05) * time.Hour).Format(time.RFC3339)) fmt.Println("") fmt.Println(_now.Add(time.Duration(-25) * time.Second).Format(time.RFC3339)) fmt.Println(_now.Add(time.Duration(-12) * time.Minute).Format(time.RFC3339)) fmt.Println(_now.Add(time.Duration(-05) * time.Hour).Format(time.RFC3339)) }
↓
$ go run time6.go 2016-01-19 23:13:56.686245405 +0900 JST 2016-01-19T23:14:21+09:00 2016-01-19T23:25:56+09:00 2016-01-20T04:13:56+09:00 2016-01-19T23:13:31+09:00 2016-01-19T23:01:56+09:00 2016-01-19T18:13:56+09:00 $
文字列を任意のレイアウトより日付に変換
sample
package main import ( "fmt" "time" ) func main(){ _date, _err := time.Parse("2006-01-02 15:04:05", "2001-10-23 15:54:20") if _err != nil { panic(_err) } fmt.Println(_date) }
↓
$ go run time7.go 2001-10-23 15:54:20 +0000 UTC $
2つの日時より差を取得する
sample
package main import ( "fmt" "time" ) func main(){ // 2つの日時を設定 _date1, _ := time.Parse("2006-01-02 15:04:05", "2001-10-23 15:54:20") _date2, _ := time.Parse("2006-01-02 15:04:05", "2002-10-23 15:54:20") // 差を取得する _d := _date2.Sub(_date1) // 差を出力する fmt.Println(_d) }
↓
$ go run time8.go 8760h0m0s $
まあ、こんな感じ
所感
使いそうなものをとりあえず、調べてみた。
日付のフォーマットでちょっとつまづきそうだけど基本は抑えた感じ…多分
基本、手続き型言語の仕事が多すぎた分、慣れるのがちょっと大変かも
golangでExcelのファイルへ書き込み
使用するパッケージ
サンプルコード
package main import ( "fmt" "github.com/tealeg/xlsx" ) func main(){ // ファイル var file *xlsx.File // シート var sheet *xlsx.Sheet // var row *xlsx.Row var cell *xlsx.Cell var err error var fileName = "テストファイル.xlsx" file = xlsx.NewFile() sheet, err = file.AddSheet("サンプル1") if err != nil { fmt.Printf(err.Error()) } for i:=0;i < 10;i++ { row = sheet.AddRow() for j:=0;j<10;j++ { cell = row.AddCell() cell.Value = fmt.Sprintf("%d行目,%d列目", i, j) } } // ファイルを保存 err = file.Save(fileName) if err != nil { fmt.Printf(err.Error()) } }
goでライブラリのテストを試す
” testing”パッケージがある
これを使用してテストすることができるみたい
テスト対象
$ tree $GOPATH/src/github.com/mshige1979/ $GOPATH/src/github.com/mshige1979/ ├── compute │ └── add.go └── hello └── hello.go 2 directories, 2 files $
※computeとかいうサンプルライブラリ
テストコード
add_test.go
package compute import ( "testing" ) func TestAdd(t *testing.T){ const in1 = 10 const in2 = 20 const out = 30 x := Add(in1, in2) if x != out { t.Error("Add(%d, %d) = %d\n Error!!!", in1, in2, x) } }
※ファイル名に"_test"を付与するらしい
テスト
$ go test PASS ok github.com/mshige1979/compute 0.009s $
テストちょっと詳しく
$ go test -v === RUN TestAdd --- PASS: TestAdd (0.00s) PASS ok github.com/mshige1979/compute 0.008s $
こんな感じらしい
GOPATHを使用してgo installとかする
実行環境?
macです。ディスク容量がやばいのでもうそろそろ家のやつはminiに移行しようかと考え中
GOPATHってなん
go言語で使用する際のworkディレクトリみたいなものパッケージを取得する場合などやフレームワークを使いたい場合は必須
どこに作成するのか?
基本的に制限はないらしい
一般的にはgocodeとか別途バージョン番号とかで分けたりしていることもあるらしいけど
ディレクトリ構成は?
こうなった
$ tree . ├── bin ├── pkg └── src └── github.com └── mshige1979 5 directories, 0 files $
bin:go installした際に配置される場所
pkg:中間ビルドされた時のファイルなどが配置されている感じ
src:ソースコードを置く
※go getコマンドで実行した際もここのディレクトリをベースに配置されるとのこと
サンプルになんかを作成する
hello的なやる
ディレクトリ作成
$ cd src/github.com/mshige1979/ $ mkdir hello $ cd hello/
hello.go
package main import ( "fmt" ) func main(){ fmt.Printf("Hello, World!\n") }
スクリプト実行
$ go run hello.go Hello, World! $
go install
$ go install $ tree $GOPATH/bin $GOPATH/bin └── hello 0 directories, 1 file $
※作成されていること
実行
$ $GOPATH/bin/hello Hello, World! $
ライブラリを作成する
computeとか…
ディレクトリ作成
$ mkdir compute cd compute/
add.go
package compute func Add(a int, b int) int { return a + b }
※まあ、超適当で…
さっきのhello.goを修正する
package main import ( "fmt" "github.com/mshige1979/compute" ) func main(){ fmt.Printf("Hello, World!\n") a := 10 b := 20 c := compute.Add(a, b) fmt.Printf("%d + %d = %d\n!", a, b, c) }
インストールして実行
$ go install $ $GOPATH/bin/hello Hello, World! 10 + 20 = 30 $
pkgの中身
$ tree $GOPATH/pkg $GOPATH/pkg └── darwin_amd64 └── github.com └── mshige1979 └── compute.a 3 directories, 1 file $
所感
goは使っていない変数とかパッケージの名前がおかしいと警告や想定案みたいなものをだすので原因をそこそこ見つけやすい
ちょっとテスト方法とかも調べてみる
SonarQubeをJenkinsで実行
Jenkinsインストール
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key sudo yum install jenkins -y sudo chkconfig jenkins on sudo service jenkins start
※プラグインとか初期設定は適当にする
SonarQubeのJenkinsプラグインをインストールする
https://wiki.jenkins-ci.org/display/JENKINS/SonarQube+plugin
Jenkinsの「Jenkinsの管理」→「システム設定」を開き、SonarQubeの設定を確認する
Runner
Server
ジョブを設定
プロジェクトの作成
ビルドの「Invoke Standalone SonarQube Analysis」を選択
パラメータを指定
ビルド結果
おわり
所感
コマンドで実行する場合とjenkinsで実行する方法はまあなんとかこれでいい感じ。
除外するデータなどはパラメータを調べてから除外していく。
ルール自体はまあそのうち見てみよう。覚えるのがキツイのでちょっと後回し