Replace the spellings of github/Github with GitHub

This commit is contained in:
TAKAHASHI Shuuji
2019-06-17 06:52:04 +09:00
parent f939c7e6cb
commit 02bf9fc253
50 changed files with 3675 additions and 3675 deletions

View File

@@ -1,176 +1,176 @@
# 1.2 GOPATHとワーキングディレクトリ
さきほどGoをインストールする際はGOPATH変数を設定する必要があるとご説明しました。Goはバージョン1.1から必ずこの変数を設定するようになっており、Goのインストールディレクトリと同じにはできません。このディレクトリは、GoのソースコードやGoの実行可能ファイル、並びにコンパイル済みのパッケージファイルを保存する為に使用します。そのためこのディレクトリにはつのサブディレクトリが存在しますsrc、bin、pkgです。
## GOPATH設定
go コマンドは、ある重要な環境変数に依存しています:$GOPATH<sup>1</sup>
Windowsシステムにおいて環境変数の形式は`%GOPATH%`です。この本の中では主にUnix形式を使用します。Windowsユーザは適時置き換えてください。
*これはGoのインストールディレクトリではありません。以下では筆者のワーキングディレクトリで説明します。もし異なるディレクトリを使用する場合はGOPATHをあなたのワーキングディレクトリに置き換えてください。*
Unix に似た環境であれば大体以下のような設定になります:
```sh
export GOPATH=/home/apple/mygo
```
上のディレクトリを新たに作成し、上の一行を`.bashrc`または`.zshrc`もしくは自分の`sh`の設定ファイルに加えます。
Windows では以下のように設定します。新しくGOPATHと呼ばれる環境変数を作成します
```sh
GOPATH=c:\mygo
```
GOPATHは複数のディレクトリを許容します。複数のディレクトリがある場合、デリミタに気をつけてください。複数のディレクトリがある場合Windowsはセミコロン、Linuxはコロンを使います。複数のGOPATHがある場合は、デフォルトでgo getの内容が第一ディレクトリとされます。
上の $GOPATH ディレクトリには3つのディレクトリがあります:
- src にはソースコードを保存します(例えば:.go .c .h .s等
- pkg にはコンパイル後に生成されるファイル(例えば:.a
- bin にはコンパイル後に生成される実行可能ファイル(このまま $PATH 変数に加えてもかまいません。もしいくつもgopathがある場合は、`${GOPATH//://bin:}/bin`を使って全てのbinディレクトリを追加してください
以降私はすべての例でmygoを私のgopathディレクトリとします。
## ソースコードディレクトリ構成
GOPATH内のsrcディレクトリはこれから開発するプログラムにとってメインとなるディレクトリです。全てのソースコードはこのディレクトリに置くことになります。一般的な方法では一つのプロジェクトが一つのディレクトリが割り当てられます、例えば$GOPATH/src/mymath はmymathというアプリケーションパッケージか実行アプリケーションになります。これはpackageがmainかそうでないかによって決定します。mainであれば実行可能アプリケーションで、そうでなければアプリケーションパッケージになります。これに関してはpackageを後ほどご紹介する予定です。
新しくアプリケーションやソースパッケージを作成するときは、srcディレクトリの中にディレクトリを作るところから始めます。ディレクトリ名は一般的にソースパッケージ名になります。もちろんネストしたディレクトリも可能です。例えばsrcの中に$GOPATH/src/github.com/astaxie/beedbというディレクトリを作ったとすると、このパッケージパスは"github.com/astaxie/beedb"になり、パッケージ名は最後のディレクトリであるbeedbになります。
以下ではmymathを例にどのようにアプリケーションパッケージをコーディングするかご説明します。以下のコードを実行します。
```sh
cd $GOPATH/src
mkdir mymath
```
sqrt.goというファイルを作成し、内容を以下のようにします。
```go
// $GOPATH/src/mymath/sqrt.goコードは以下の通り
package mymath
func Sqrt(x float64) float64 {
z := 0.0
for i := 0; i < 1000; i++ {
z -= (z*z - x) / (2 * x)
}
return z
}
```
このように私のアプリケーションパッケージディレクトリとコードが作成されました。注意一般的にpackageの名前とディレクトリ名は一致させるべきです。
## コンパイルアプリケーション
上のとおり、我々はすでに自分のアプリケーションパッケージを作成しましたが、どのようにコンパイル/インストールすべきでしょうか?2種類の方法が存在します。
1、対応するアプリケーションパッケージディレクトリに入り、`go install`を実行すればインストールできます。
2任意のディレクトリで以下のコード`go install mymath`を実行します。
インストールが終われば、以下のディレクトリに入り
```sh
cd $GOPATH/pkg/${GOOS}_${GOARCH}
//以下のファイルが現れるはずです。
mymath.a
```
この.aファイルはアプリケーションパッケージです。ならば我々はどのように実行できるでしょうか
次にアプリケーション・プログラムを作成してこのアプリケーションパッケージをコールします。
アプリケーションパッケージmathappを作ります。
```sh
cd $GOPATH/src
mkdir mathapp
cd mathapp
vim main.go
```
`$GOPATH/src/mathapp/main.go`コード:
```go
package main
import (
"mymath"
"fmt"
)
func main() {
fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2))
}
```
このパッケージは`main`であることが分かると思います。importにおいてコールするパッケージは`mymath`であり、これが`$GOPATH/src`のパスに対応します。もしネストしたディレクトリであれば、importの中でネストしたディレクトリをインポートします。例えばいくつものGOPATHがあった場合も同じで、Goは自動的に複数の`$GOPATH/src`の中から探し出します。
さて、どのようにプログラムをコンパイルするのでしょうか?このアプリケーションディレクトリに入り、`go build`を実行すれば、このディレクトリの下にmathappの実行可能ファイルが生成されます。
```sh
./mathapp
```
以下のように出力されます。
```sh
Hello, world. Sqrt(2) = 1.414213562373095
```
どのようにアプリケーションをインストールするのでしょうか。このディレクトリに入り、`go install`を実行すると、$GOPATH/bin/の下に実行可能ファイルmathappが作成されます。`$GOPATH/bin`が我々のPATHに追加されていることを思い出して下さい、コマンドラインから以下のように入力することで実行することができます。
```sh
mathapp
```
この場合も以下のように出力されます。
Hello, world. Sqrt(2) = 1.414213562373095
ここではどのように実行可能アプリケーションをコンパイル/インストールし、ディレクトリ構造を設計するかについてご紹介しました。
## リモートパッケージの取得
go言語はリモートパッケージを取得するツール`go get`を持っています。現在go getは多数のオープンソースリポジトリをサポートしていますgithub、googlecode、bitbucket、Launchpad
go get github.com/astaxie/beedb
>go get -u オプションはパッケージの自動更新を行います。また、go get時に自動的に当該のパッケージの依存する他のサードパーティパッケージを取得します。
このコマンドでふさわしいコードを取得し、対応するオープンソースプラットホームに対し異なるソースコントロールツールを利用します。例えばgithubではgit、googlecodeではhg。そのためこれらのコードを取得したい場合は、先に対応するソースコードコントロールツールをインストールしておく必要があります。
上述の方法で取得したコードはローカルの以下の場所に配置されます。
$GOPATH
src
|--github.com
|-astaxie
|-beedb
pkg
|--対応プラットフォーム
|-github.com
|--astaxie
|beedb.a
go getは以下のような手順を踏みます。まずはじめにソースコードツールでコードをsrcの下にcloneします。その後`go install`を実行します。
コードの中でリモートパッケージが使用される場合、単純にローカルのパッケージと同じように頭のimportに対応するパスを添えるだけです。
import "github.com/astaxie/beedb"
## プログラムの全体構成
上記で作成したローカルのmygoのディレクトリ構造は以下のようになっています。
bin/
mathapp
pkg/
プラットフォーム名/ 例darwin_amd64、linux_amd64
mymath.a
github.com/
astaxie/
beedb.a
src/
mathapp
main.go
mymath/
sqrt.go
github.com/
astaxie/
beedb/
beedb.go
util.go
上述の構成から明確に判断できるのは、binディレクトリの下にコンパイル後の実行可能ファイルが保存され、pkgの下に関数パッケージが保存され、srcの下にアプリケーションのソースコードが保存されているということです。
## links
* [目次](<preface.md>)
* 前へ: [GOのインストール](<01.1.md>)
* 次へ: [GOのコマンド](<01.3.md>)
# 1.2 GOPATHとワーキングディレクトリ
さきほどGoをインストールする際はGOPATH変数を設定する必要があるとご説明しました。Goはバージョン1.1から必ずこの変数を設定するようになっており、Goのインストールディレクトリと同じにはできません。このディレクトリは、GoのソースコードやGoの実行可能ファイル、並びにコンパイル済みのパッケージファイルを保存する為に使用します。そのためこのディレクトリにはつのサブディレクトリが存在しますsrc、bin、pkgです。
## GOPATH設定
go コマンドは、ある重要な環境変数に依存しています:$GOPATH<sup>1</sup>
Windowsシステムにおいて環境変数の形式は`%GOPATH%`です。この本の中では主にUnix形式を使用します。Windowsユーザは適時置き換えてください。
*これはGoのインストールディレクトリではありません。以下では筆者のワーキングディレクトリで説明します。もし異なるディレクトリを使用する場合はGOPATHをあなたのワーキングディレクトリに置き換えてください。*
Unix に似た環境であれば大体以下のような設定になります:
```sh
export GOPATH=/home/apple/mygo
```
上のディレクトリを新たに作成し、上の一行を`.bashrc`または`.zshrc`もしくは自分の`sh`の設定ファイルに加えます。
Windows では以下のように設定します。新しくGOPATHと呼ばれる環境変数を作成します
```sh
GOPATH=c:\mygo
```
GOPATHは複数のディレクトリを許容します。複数のディレクトリがある場合、デリミタに気をつけてください。複数のディレクトリがある場合Windowsはセミコロン、Linuxはコロンを使います。複数のGOPATHがある場合は、デフォルトでgo getの内容が第一ディレクトリとされます。
上の $GOPATH ディレクトリには3つのディレクトリがあります:
- src にはソースコードを保存します(例えば:.go .c .h .s等
- pkg にはコンパイル後に生成されるファイル(例えば:.a
- bin にはコンパイル後に生成される実行可能ファイル(このまま $PATH 変数に加えてもかまいません。もしいくつもgopathがある場合は、`${GOPATH//://bin:}/bin`を使って全てのbinディレクトリを追加してください
以降私はすべての例でmygoを私のgopathディレクトリとします。
## ソースコードディレクトリ構成
GOPATH内のsrcディレクトリはこれから開発するプログラムにとってメインとなるディレクトリです。全てのソースコードはこのディレクトリに置くことになります。一般的な方法では一つのプロジェクトが一つのディレクトリが割り当てられます、例えば$GOPATH/src/mymath はmymathというアプリケーションパッケージか実行アプリケーションになります。これはpackageがmainかそうでないかによって決定します。mainであれば実行可能アプリケーションで、そうでなければアプリケーションパッケージになります。これに関してはpackageを後ほどご紹介する予定です。
新しくアプリケーションやソースパッケージを作成するときは、srcディレクトリの中にディレクトリを作るところから始めます。ディレクトリ名は一般的にソースパッケージ名になります。もちろんネストしたディレクトリも可能です。例えばsrcの中に$GOPATH/src/github.com/astaxie/beedbというディレクトリを作ったとすると、このパッケージパスは"github.com/astaxie/beedb"になり、パッケージ名は最後のディレクトリであるbeedbになります。
以下ではmymathを例にどのようにアプリケーションパッケージをコーディングするかご説明します。以下のコードを実行します。
```sh
cd $GOPATH/src
mkdir mymath
```
sqrt.goというファイルを作成し、内容を以下のようにします。
```go
// $GOPATH/src/mymath/sqrt.goコードは以下の通り
package mymath
func Sqrt(x float64) float64 {
z := 0.0
for i := 0; i < 1000; i++ {
z -= (z*z - x) / (2 * x)
}
return z
}
```
このように私のアプリケーションパッケージディレクトリとコードが作成されました。注意一般的にpackageの名前とディレクトリ名は一致させるべきです。
## コンパイルアプリケーション
上のとおり、我々はすでに自分のアプリケーションパッケージを作成しましたが、どのようにコンパイル/インストールすべきでしょうか?2種類の方法が存在します。
1、対応するアプリケーションパッケージディレクトリに入り、`go install`を実行すればインストールできます。
2任意のディレクトリで以下のコード`go install mymath`を実行します。
インストールが終われば、以下のディレクトリに入り
```sh
cd $GOPATH/pkg/${GOOS}_${GOARCH}
//以下のファイルが現れるはずです。
mymath.a
```
この.aファイルはアプリケーションパッケージです。ならば我々はどのように実行できるでしょうか
次にアプリケーション・プログラムを作成してこのアプリケーションパッケージをコールします。
アプリケーションパッケージmathappを作ります。
```sh
cd $GOPATH/src
mkdir mathapp
cd mathapp
vim main.go
```
`$GOPATH/src/mathapp/main.go`コード:
```go
package main
import (
"mymath"
"fmt"
)
func main() {
fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2))
}
```
このパッケージは`main`であることが分かると思います。importにおいてコールするパッケージは`mymath`であり、これが`$GOPATH/src`のパスに対応します。もしネストしたディレクトリであれば、importの中でネストしたディレクトリをインポートします。例えばいくつものGOPATHがあった場合も同じで、Goは自動的に複数の`$GOPATH/src`の中から探し出します。
さて、どのようにプログラムをコンパイルするのでしょうか?このアプリケーションディレクトリに入り、`go build`を実行すれば、このディレクトリの下にmathappの実行可能ファイルが生成されます。
```sh
./mathapp
```
以下のように出力されます。
```sh
Hello, world. Sqrt(2) = 1.414213562373095
```
どのようにアプリケーションをインストールするのでしょうか。このディレクトリに入り、`go install`を実行すると、$GOPATH/bin/の下に実行可能ファイルmathappが作成されます。`$GOPATH/bin`が我々のPATHに追加されていることを思い出して下さい、コマンドラインから以下のように入力することで実行することができます。
```sh
mathapp
```
この場合も以下のように出力されます。
Hello, world. Sqrt(2) = 1.414213562373095
ここではどのように実行可能アプリケーションをコンパイル/インストールし、ディレクトリ構造を設計するかについてご紹介しました。
## リモートパッケージの取得
go言語はリモートパッケージを取得するツール`go get`を持っています。現在go getは多数のオープンソースリポジトリをサポートしていますGitHub、googlecode、bitbucket、Launchpad
go get github.com/astaxie/beedb
>go get -u オプションはパッケージの自動更新を行います。また、go get時に自動的に当該のパッケージの依存する他のサードパーティパッケージを取得します。
このコマンドでふさわしいコードを取得し、対応するオープンソースプラットホームに対し異なるソースコントロールツールを利用します。例えばGitHubではgit、googlecodeではhg。そのためこれらのコードを取得したい場合は、先に対応するソースコードコントロールツールをインストールしておく必要があります。
上述の方法で取得したコードはローカルの以下の場所に配置されます。
$GOPATH
src
|--github.com
|-astaxie
|-beedb
pkg
|--対応プラットフォーム
|-github.com
|--astaxie
|beedb.a
go getは以下のような手順を踏みます。まずはじめにソースコードツールでコードをsrcの下にcloneします。その後`go install`を実行します。
コードの中でリモートパッケージが使用される場合、単純にローカルのパッケージと同じように頭のimportに対応するパスを添えるだけです。
import "github.com/astaxie/beedb"
## プログラムの全体構成
上記で作成したローカルのmygoのディレクトリ構造は以下のようになっています。
bin/
mathapp
pkg/
プラットフォーム名/ 例darwin_amd64、linux_amd64
mymath.a
github.com/
astaxie/
beedb.a
src/
mathapp
main.go
mymath/
sqrt.go
github.com/
astaxie/
beedb/
beedb.go
util.go
上述の構成から明確に判断できるのは、binディレクトリの下にコンパイル後の実行可能ファイルが保存され、pkgの下に関数パッケージが保存され、srcの下にアプリケーションのソースコードが保存されているということです。
## links
* [目次](<preface.md>)
* 前へ: [GOのインストール](<01.1.md>)
* 次へ: [GOのコマンド](<01.3.md>)

View File

@@ -1,430 +1,430 @@
# 1.4 Go開発ツール
本章ではいくつかの開発ツールをご紹介します。これらはすべて自動化を備えており、fmt機能を自動化します。なぜならこれらはすべてクロスプラットフォームであり、そのためインストール手順といったものはすべて同じものです。
## LiteIDE
LiteIDEはGo言語の開発に特化したクロスプラットフォームの軽量統合開発環境(IDE)です。visualfcで書かれています。
![](images/1.4.liteide.png?raw=true)
図1.4 LiteIDEのメイン画面
**LiteIDEの主な特徴**
* 主なオペレーティングシステムのサポート
* Windows
* Linux
* MacOS X
* Goコンパイル環境の管理と切り替え
* 複数のGoコンパイル環境の管理と切り替え
* Go言語のクロスコンパイルのサポート
* Go標準と同じ項目管理方式
* GOPATHに基づいたパッケージブラウザ
* GOPATHに基づいたコンパイルシステム
* GOPATHに基づいたドキュメント検索
* Go言語の編集サポート
* クラスブラウザとアウトライン表示
* Gocode(コード自動作成ツール)の完全なサポート
* Go言語ドキュメントとApi高速検索
* コード表現情報の表示`F1`
* ソースコード定義とジャンプのサポート`F2`
* Gdbブレークポイントとテストサポート
* gofmt自動整形のサポート
* その他の特徴
* 多言語メニューのサポート
* 完全にプラガブルな構成
* エディタのカラーリングサポート
* Kateに基づいた文法表示サポート
* 全文に基づく単語の自動補完
* キーボードショートカットのバインディングサポート
* Markdownドキュメントの編集サポート
* リアルタイムプレビューと表示の同期
* カスタムCSS表示
* HTML及びPDFドキュメントのエクスポート
* HTML/PDFドキュメントへの変換とマージ
**LiteIDEインストール設定**
* LiteIDEインストール
* ダウンロード http://sourceforge.net/projects/liteide/files/>
* ソースコード <https://github.com/visualfc/liteide>
まずGo言語環境をインストールし、その後オペレーティングシステムにしたがってLiteIDEの対応圧縮ファイルを直接解凍すれば使用できます。
* コンパイル環境設定
自身のシステムの要求にしたがってLiteIDEが現在使用している環境変数を切り替えまたは設定します。
Windowsオペレーティングシステムの64bitGo言語の場合、
ツール欄の環境設定のなかでwin64を選択し、`編集環境`をクリックしてLiteIDEからwin64.envファイルを編集します。
GOROOT=c:\go
GOBIN=
GOARCH=amd64
GOOS=windows
CGO_ENABLED=1
PATH=%GOBIN%;%GOROOT%\bin;%PATH%
。。。
この中の`GOROOT=c:\go`を現在のGoのインストールパスに修正し、保存するだけです。もしMinGW64があれば、`c:\MinGW64\bin`をPATHの中に入れて、goによるgccのコールでCGOコンパイラのサポートを利用することができます。
Linuxオペレーティングシステムで64bitGo言語の場合、
ツール欄の環境設定の中からlinux64を選び、`編集環境`をクリックし、LiteIDEからlinux64.envファイルを編集します。
GOROOT=$HOME/go
GOBIN=
GOARCH=amd64
GOOS=linux
CGO_ENABLED=1
PATH=$GOBIN:$GOROOT/bin:$PATH
。。。
この中の`GOROOT=$HOME/go`を現在のGoのインストールパスに修正して保存します。
* GOPATH設定
Go言語のツールキーはGOPATH設定を使用します。Go言語開発のプロジェクトのパスリストです。コマンドライン(LiteIDEでは`Ctrl+,`を直接入力できます)で`go help gopath`を入力するとGOPATHドキュメントを素早く確認できます。
LiteIDEでは簡単に確認でき、GOPATHを設定することができます。`メニュー-確認-GOPATH`設定を通じて、システム中に存在するGOPATHリストを確認することができます。
同時に必要な追加項目にそってカスタムのGOPATHリストに追加することができます。
## Sublime Text
ここではSublime Text 2以下「Sublime」+GoSublimeの組み合わせをご紹介します。なぜこの組み合わせなのでしょうか
- コード表示の自動化、以下の図の通り
![](images/1.4.sublime1.png?raw=true)
図1.5 sublimeコードの自動化画面
- 保存した時にはコードが自動的に整形されています。あなたの書いたコードをより美しくGoの標準に合うよう仕上げてくれます。
- プロジェクト管理のサポート
![](images/1.4.sublime2.png?raw=true)
図1.6 sublimeプロジェクト管理画面 
- 文法のハイライトサポート
- Sublime Text 2はフリーで使用できます。保存回数が一定の量を超えると購入するかのダイアログが現れるので、継続利用をキャンセルするをクリックします。正式登録版とは何の違いもありません。
次はどのようにインストールするかご説明します。[Sublime](http://www.sublimetext.com/)ダウンロードします。
自分のシステムに合わせて対応するバージョンをダウンロードし、Sublimeを開きます。Sublimeに詳しくない方はまず[Sublime Text 2 入門とテクニック](http://lucifr.com/139225/sublime-text-2-tricks-and-tips/)の文章を読んでみてください。
1. 開いた後、 Package Controlをインストールします。Ctrl+`でコマンドラインを開き、以下のコードを実行します:
import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'
この時Sublimeを再度開き直してください。メニュー欄に一つ項目が増えているのがお分かりいただけるかと思います。これでPackage Controlが正しくインストールされました。
![](images/1.4.sublime3.png?raw=true)
図1.7 sublimeパッケージ管理
2. インストールが完了するとSublimeのプラグインをインストールできます。GoSublime, SidebarEnhancementsとGo Buildをインストールする必要があるので、プラグインをインストールしたあとSublimeを再起動させて有効にしてください。Ctrl+Shift+pでPackage Controlを開き、`pcip`を入力します。(これは"Package Control: Install Package"と省略されます)。
この時、左下のコーナーに現在読み込んでいるパッケージデータが表示されます。完了すると下のような画面になります。
![](images/1.4.sublime4.png?raw=true)
図1.8 sublimeプラグインのインストール画面
この時、GoSublimeと入力し、「確認」をクリックするとインストールが始まります。同じようにSidebarEnhancementsとGo Buildにも行います。
3. インストールが成功したかテストします。Sublimeを開き、main.goを開いて文法がハイライトされているのをご確認ください。`import`を入力してコードの自動表示がされます。`import "fmt"`のあとに`fmt.`を入力すると自動的に関数の候補が現れます。
もしすでにこのような表示がされる場合は、インストールが成功しており、自動補完が完了しています。
もしこのような表示がなされない場合、あなたの`$PATH`が正しく設定されていないのかもしれません。ターミナルを開き、gocodeを入力して、正しく実行できるか確認してください。もしダメであれば`$PATH`が正しく設定されていません。
(XP向け)たまたまターミナルでの実行が成功することもあります。しかしsublimeは何も知らせてくれないかデコードエラーが発生します。sublime text3とconvert utf8プラグインを試してみてください。
4. MacOSではすでに$GOROOT, $GOPATH, $GOBINが設定されていても自動的にはどうすればよいか教えてくれません。
sublimeにてcommand + 9を押し、envを入力して$PATH, $GOROOT, $GOPATH, $GOBINといった変数を確認します。もしなければ、以下の手順に従ってください。
まず下のシンボリックリンクを作成し、Terminalで直接sublimeを起動します
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime
## Vim
Vimはviから発展したテキストエディタです。コード補完、コンパイルまたエラージャンプなど、プログラミングに特化した機能が豊富です。広くプログラマに使用されています。
![](images/1.4.vim.png?raw=true)
図1.9 VIMエディタのGoの自動補完画面
1. vimハイライト表示の設定
cp -r $GOROOT/misc/vim/* ~/.vim/
2. ~/.vimrcファイルで文法のハイライト表示を追加します
filetype plugin indent on
syntax on
3. [Gocode](https://github.com/nsf/gocode/)をインストールします
go get -u github.com/nsf/gocode
gocodeはデフォルトで`$GOPATH/bin`の下にインストールされています。
4. [Gocode](https://github.com/nsf/gocode/)を設定します。
~ cd $GOPATH/src/github.com/nsf/gocode/vim
~ ./update.bash
~ gocode set propose-builtins true
propose-builtins true
~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64"
lib-path "/home/border/gocode/pkg/linux_amd64"
~ gocode set
propose-builtins true
lib-path "/home/border/gocode/pkg/linux_amd64"
>gocode setのつのパラメータの意味を説明します
>
>propose-builtinsはGoのビルトイン関数を補完するかです。タイプは定数です。デフォルトはfalseで、表示しません。
>
>lib-path:デフォルトで、gocodeは**$GOPATH/pkg/$GOOS_$GOARCH**と**$GOROOT/pkg/$GOOS_$GOARCH**ディレクトリのパッケージを検索するだけです。当然この設定には私達の外側のlibを検索できるようパスを設定することができます。
5. おめでとうございます。インストール完了です。あなたは今から`:e main.go`でGoで開発する面白さを体験することができます。
より多くのVIMの設定は、[リンク](http://monnand.me/p/vim-golang-environment/zhCN/)をご参照ください。
## Emacs
Emacsは伝説の神器です。彼女はエディタであるだけでなく、統合環境でもあります。または開発環境の集大成と呼んでもよいかもしれません。これらの機能はユーザの身を万能のオペレーティングシステムに置きます。
![](images/1.4.emacs.png?raw=true)
図1.10 EmacsでGoを編集するメイン画面
1. Emacsのハイライト表示設定
cp $GOROOT/misc/emacs/* ~/.emacs.d/
2. [Gocode](https://github.com/nsf/gocode/)をインストール
go get -u github.com/nsf/gocode
gocodeはデフォルトで`$GOBIN`の下にインストールされます。
3. [Gocode](https://github.com/nsf/gocode/)を設定
~ cd $GOPATH/src/github.com/nsf/gocode/emacs
~ cp go-autocomplete.el ~/.emacs.d/
~ gocode set propose-builtins true
propose-builtins true
~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // あなたのパスに置き換えてください。
lib-path "/home/border/gocode/pkg/linux_amd64"
~ gocode set
propose-builtins true
lib-path "/home/border/gocode/pkg/linux_amd64"
4. [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete)をインストールする必要があります。
AutoCompleteをダウンロードして解凍します。
~ make install DIR=$HOME/.emacs.d/auto-complete
~/.emacsファイルを設定します。
;;auto-complete
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict")
(ac-config-default)
(local-set-key (kbd "M-/") 'semantic-complete-analyze-inline)
(local-set-key "." 'semantic-complete-self-insert)
(local-set-key ">" 'semantic-complete-self-insert)
詳細情報はこちらを参考にしてくださいhttp://www.emacswiki.org/emacs/AutoComplete
5. .emacsを設定します。
;; golang mode
(require 'go-mode-load)
(require 'go-autocomplete)
;; speedbar
;; (speedbar 1)
(speedbar-add-supported-extension ".go")
(add-hook
'go-mode-hook
'(lambda ()
;; gocode
(auto-complete-mode 1)
(setq ac-sources '(ac-source-go))
;; Imenu & Speedbar
(setq imenu-generic-expression
'(("type" "^type *\\([^ \t\n\r\f]*\\)" 1)
("func" "^func *\\(.*\\) {" 1)))
(imenu-add-to-menubar "Index")
;; Outline mode
(make-local-variable 'outline-regexp)
(setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....")
(outline-minor-mode 1)
(local-set-key "\M-a" 'outline-previous-visible-heading)
(local-set-key "\M-e" 'outline-next-visible-heading)
;; Menu bar
(require 'easymenu)
(defconst go-hooked-menu
'("Go tools"
["Go run buffer" go t]
["Go reformat buffer" go-fmt-buffer t]
["Go check buffer" go-fix-buffer t]))
(easy-menu-define
go-added-menu
(current-local-map)
"Go tools"
go-hooked-menu)
;; Other
(setq show-trailing-whitespace t)
))
;; helper function
(defun go ()
"run current buffer"
(interactive)
(compile (concat "go run " (buffer-file-name))))
;; helper function
(defun go-fmt-buffer ()
"run gofmt on current buffer"
(interactive)
(if buffer-read-only
(progn
(ding)
(message "Buffer is read only"))
(let ((p (line-number-at-pos))
(filename (buffer-file-name))
(old-max-mini-window-height max-mini-window-height))
(show-all)
(if (get-buffer "*Go Reformat Errors*")
(progn
(delete-windows-on "*Go Reformat Errors*")
(kill-buffer "*Go Reformat Errors*")))
(setq max-mini-window-height 1)
(if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t))
(progn
(erase-buffer)
(insert-buffer-substring "*Go Reformat Output*")
(goto-char (point-min))
(forward-line (1- p)))
(with-current-buffer "*Go Reformat Errors*"
(progn
(goto-char (point-min))
(while (re-search-forward "<standard input>" nil t)
(replace-match filename))
(goto-char (point-min))
(compilation-mode))))
(setq max-mini-window-height old-max-mini-window-height)
(delete-windows-on "*Go Reformat Output*")
(kill-buffer "*Go Reformat Output*"))))
;; helper function
(defun go-fix-buffer ()
"run gofix on current buffer"
(interactive)
(show-all)
(shell-command-on-region (point-min) (point-max) "go tool fix -diff"))
6. おめでとうございます。今からあなたはこの神器を使ってGo開発の楽しみを体験できます。デフォルトのspeedbarは閉じています。もし開く場合は ;; (speedbar 1) の前のコメントを取り去るか、*M-x speedbar*を手動で起動してください。
## Eclipse
Eclipseも非常によく使われる開発ツールです。以下ではEclipseを使ってどのようにGoプログラムを編集するかご紹介します。
![](images/1.4.eclipse1.png?raw=true)
図1.11 EclipseでのGo編集のメイン画面
1. まず[Eclipse](http://www.eclipse.org/)をダウンロードしてインストールします。
2. [goclipse](https://code.google.com/p/goclipse/)プラグインをダウンロードします。
http://code.google.com/p/goclipse/wiki/InstallationInstructions
3. gocodeをダウンロードして、goのコード補完を表示させます。
gocodeのgithubアドレス
https://github.com/nsf/gocode
windowsではgitをインストールする必要があります。通常は[msysgit](https://code.google.com/p/msysgit/)を使います。
cmdでインストールを行います
go get -u github.com/nsf/gocode
以下のコードをダウンロードし、直接go buildでコンパイルしてもかまいません。この場合はgocode.exeが生成されます。
4. [MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)をダウンロードして要求に従いインストールしてください。
5. プラグイン設定
Windows->Reference->Go
(1).Goのコンパイラを設定します。
![](images/1.4.eclipse2.png?raw=true)
図1.12 Goの基本情報を設定します。
(2).Gocodeを設定しますオプション、コード補完、Gocodeのパスは事前に生成したgocode.exeファイルを設定します。
![](images/1.4.eclipse3.png?raw=true)
図1.13 gocode情報を設定します。
(3).GDBを設定しますオプション、テスト用、GDBのパスはMingGWのインストールディレクトリ下のgdb.exeファイルを設定します。
![](images/1.4.eclipse4.png?raw=true)
図1.14 GDB情報の設定
6. テストが成功するか
goプロジェクトを一つ新規作成して、hello.goを作成します
![](images/1.4.eclipse5.png?raw=true)
図1.15 プロジェクトの新規作成とファイルの編集
テストの実行consoleでコマンドを入力する必要があります
![](images/1.4.eclipse6.png?raw=true)
図1.16 Goプログラムのテスト
## IntelliJ IDEA
Javaに親しい読者はideaに詳しいことでしょう。ideaはプラグインを通してgo言語のシンタックスハイライト、コード補完およびリビルドをサポートしています。
1. ideaを先にダウンロードします。ideaはマルチプラットフォームをサポートしていますwin,mac,linux、もしお金があれば正式版を購入します、もし無ければ、コミュニティの無料版を使ってください。Go言語を開発するだけであれば無料版で十分事足ります。
![](images/1.4.idea1.png?raw=true)
2. Goプラグインをインストールし、FileメニューのSettingをクリックします。Pluginsを探したら、Browser repoボタンをクリックします。中国国内のユーザはおそらくエラーが出るかもしれませんが、自分で解決してくれよな。
![](images/1.4.idea3.png?raw=true)
3. この時いくつものプラグインが見つかります。Golangを検索して、download and installをダブルクリックしてください。golangの行末にDownloadedの表示が現れるのを待って、OKをクリックします。
![](images/1.4.idea4.png?raw=true)
その後Applyをクリックすると、IDEが再起動を要求します。
4. 再起動が完了し、新規プロジェクトを作成すると、golangプロジェクトが作成可能であることがお分かりいただけるかとおもいます
![](images/1.4.idea5.png?raw=true)
次に、go sdkの場所を入力するよう促されるかもしれません。普段はいつもC:\Goにインストールされています。Linuxとmacは自分のインストールディレクトリの設定にしたがって、ディレクトリを選択すれば大丈夫です。
## links
* [目次](<preface.md>)
* 前へ: [Goのコマンド](<01.3.md>)
* 次へ: [まとめ](<01.5.md>)
# 1.4 Go開発ツール
本章ではいくつかの開発ツールをご紹介します。これらはすべて自動化を備えており、fmt機能を自動化します。なぜならこれらはすべてクロスプラットフォームであり、そのためインストール手順といったものはすべて同じものです。
## LiteIDE
LiteIDEはGo言語の開発に特化したクロスプラットフォームの軽量統合開発環境(IDE)です。visualfcで書かれています。
![](images/1.4.liteide.png?raw=true)
図1.4 LiteIDEのメイン画面
**LiteIDEの主な特徴**
* 主なオペレーティングシステムのサポート
* Windows
* Linux
* MacOS X
* Goコンパイル環境の管理と切り替え
* 複数のGoコンパイル環境の管理と切り替え
* Go言語のクロスコンパイルのサポート
* Go標準と同じ項目管理方式
* GOPATHに基づいたパッケージブラウザ
* GOPATHに基づいたコンパイルシステム
* GOPATHに基づいたドキュメント検索
* Go言語の編集サポート
* クラスブラウザとアウトライン表示
* Gocode(コード自動作成ツール)の完全なサポート
* Go言語ドキュメントとApi高速検索
* コード表現情報の表示`F1`
* ソースコード定義とジャンプのサポート`F2`
* Gdbブレークポイントとテストサポート
* gofmt自動整形のサポート
* その他の特徴
* 多言語メニューのサポート
* 完全にプラガブルな構成
* エディタのカラーリングサポート
* Kateに基づいた文法表示サポート
* 全文に基づく単語の自動補完
* キーボードショートカットのバインディングサポート
* Markdownドキュメントの編集サポート
* リアルタイムプレビューと表示の同期
* カスタムCSS表示
* HTML及びPDFドキュメントのエクスポート
* HTML/PDFドキュメントへの変換とマージ
**LiteIDEインストール設定**
* LiteIDEインストール
* ダウンロード http://sourceforge.net/projects/liteide/files/>
* ソースコード <https://github.com/visualfc/liteide>
まずGo言語環境をインストールし、その後オペレーティングシステムにしたがってLiteIDEの対応圧縮ファイルを直接解凍すれば使用できます。
* コンパイル環境設定
自身のシステムの要求にしたがってLiteIDEが現在使用している環境変数を切り替えまたは設定します。
Windowsオペレーティングシステムの64bitGo言語の場合、
ツール欄の環境設定のなかでwin64を選択し、`編集環境`をクリックしてLiteIDEからwin64.envファイルを編集します。
GOROOT=c:\go
GOBIN=
GOARCH=amd64
GOOS=windows
CGO_ENABLED=1
PATH=%GOBIN%;%GOROOT%\bin;%PATH%
。。。
この中の`GOROOT=c:\go`を現在のGoのインストールパスに修正し、保存するだけです。もしMinGW64があれば、`c:\MinGW64\bin`をPATHの中に入れて、goによるgccのコールでCGOコンパイラのサポートを利用することができます。
Linuxオペレーティングシステムで64bitGo言語の場合、
ツール欄の環境設定の中からlinux64を選び、`編集環境`をクリックし、LiteIDEからlinux64.envファイルを編集します。
GOROOT=$HOME/go
GOBIN=
GOARCH=amd64
GOOS=linux
CGO_ENABLED=1
PATH=$GOBIN:$GOROOT/bin:$PATH
。。。
この中の`GOROOT=$HOME/go`を現在のGoのインストールパスに修正して保存します。
* GOPATH設定
Go言語のツールキーはGOPATH設定を使用します。Go言語開発のプロジェクトのパスリストです。コマンドライン(LiteIDEでは`Ctrl+,`を直接入力できます)で`go help gopath`を入力するとGOPATHドキュメントを素早く確認できます。
LiteIDEでは簡単に確認でき、GOPATHを設定することができます。`メニュー-確認-GOPATH`設定を通じて、システム中に存在するGOPATHリストを確認することができます。
同時に必要な追加項目にそってカスタムのGOPATHリストに追加することができます。
## Sublime Text
ここではSublime Text 2以下「Sublime」+GoSublimeの組み合わせをご紹介します。なぜこの組み合わせなのでしょうか
- コード表示の自動化、以下の図の通り
![](images/1.4.sublime1.png?raw=true)
図1.5 sublimeコードの自動化画面
- 保存した時にはコードが自動的に整形されています。あなたの書いたコードをより美しくGoの標準に合うよう仕上げてくれます。
- プロジェクト管理のサポート
![](images/1.4.sublime2.png?raw=true)
図1.6 sublimeプロジェクト管理画面 
- 文法のハイライトサポート
- Sublime Text 2はフリーで使用できます。保存回数が一定の量を超えると購入するかのダイアログが現れるので、継続利用をキャンセルするをクリックします。正式登録版とは何の違いもありません。
次はどのようにインストールするかご説明します。[Sublime](http://www.sublimetext.com/)ダウンロードします。
自分のシステムに合わせて対応するバージョンをダウンロードし、Sublimeを開きます。Sublimeに詳しくない方はまず[Sublime Text 2 入門とテクニック](http://lucifr.com/139225/sublime-text-2-tricks-and-tips/)の文章を読んでみてください。
1. 開いた後、 Package Controlをインストールします。Ctrl+`でコマンドラインを開き、以下のコードを実行します:
import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'
この時Sublimeを再度開き直してください。メニュー欄に一つ項目が増えているのがお分かりいただけるかと思います。これでPackage Controlが正しくインストールされました。
![](images/1.4.sublime3.png?raw=true)
図1.7 sublimeパッケージ管理
2. インストールが完了するとSublimeのプラグインをインストールできます。GoSublime, SidebarEnhancementsとGo Buildをインストールする必要があるので、プラグインをインストールしたあとSublimeを再起動させて有効にしてください。Ctrl+Shift+pでPackage Controlを開き、`pcip`を入力します。(これは"Package Control: Install Package"と省略されます)。
この時、左下のコーナーに現在読み込んでいるパッケージデータが表示されます。完了すると下のような画面になります。
![](images/1.4.sublime4.png?raw=true)
図1.8 sublimeプラグインのインストール画面
この時、GoSublimeと入力し、「確認」をクリックするとインストールが始まります。同じようにSidebarEnhancementsとGo Buildにも行います。
3. インストールが成功したかテストします。Sublimeを開き、main.goを開いて文法がハイライトされているのをご確認ください。`import`を入力してコードの自動表示がされます。`import "fmt"`のあとに`fmt.`を入力すると自動的に関数の候補が現れます。
もしすでにこのような表示がされる場合は、インストールが成功しており、自動補完が完了しています。
もしこのような表示がなされない場合、あなたの`$PATH`が正しく設定されていないのかもしれません。ターミナルを開き、gocodeを入力して、正しく実行できるか確認してください。もしダメであれば`$PATH`が正しく設定されていません。
(XP向け)たまたまターミナルでの実行が成功することもあります。しかしsublimeは何も知らせてくれないかデコードエラーが発生します。sublime text3とconvert utf8プラグインを試してみてください。
4. MacOSではすでに$GOROOT, $GOPATH, $GOBINが設定されていても自動的にはどうすればよいか教えてくれません。
sublimeにてcommand + 9を押し、envを入力して$PATH, $GOROOT, $GOPATH, $GOBINといった変数を確認します。もしなければ、以下の手順に従ってください。
まず下のシンボリックリンクを作成し、Terminalで直接sublimeを起動します
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime
## Vim
Vimはviから発展したテキストエディタです。コード補完、コンパイルまたエラージャンプなど、プログラミングに特化した機能が豊富です。広くプログラマに使用されています。
![](images/1.4.vim.png?raw=true)
図1.9 VIMエディタのGoの自動補完画面
1. vimハイライト表示の設定
cp -r $GOROOT/misc/vim/* ~/.vim/
2. ~/.vimrcファイルで文法のハイライト表示を追加します
filetype plugin indent on
syntax on
3. [Gocode](https://github.com/nsf/gocode/)をインストールします
go get -u github.com/nsf/gocode
gocodeはデフォルトで`$GOPATH/bin`の下にインストールされています。
4. [Gocode](https://github.com/nsf/gocode/)を設定します。
~ cd $GOPATH/src/github.com/nsf/gocode/vim
~ ./update.bash
~ gocode set propose-builtins true
propose-builtins true
~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64"
lib-path "/home/border/gocode/pkg/linux_amd64"
~ gocode set
propose-builtins true
lib-path "/home/border/gocode/pkg/linux_amd64"
>gocode setのつのパラメータの意味を説明します
>
>propose-builtinsはGoのビルトイン関数を補完するかです。タイプは定数です。デフォルトはfalseで、表示しません。
>
>lib-path:デフォルトで、gocodeは**$GOPATH/pkg/$GOOS_$GOARCH**と**$GOROOT/pkg/$GOOS_$GOARCH**ディレクトリのパッケージを検索するだけです。当然この設定には私達の外側のlibを検索できるようパスを設定することができます。
5. おめでとうございます。インストール完了です。あなたは今から`:e main.go`でGoで開発する面白さを体験することができます。
より多くのVIMの設定は、[リンク](http://monnand.me/p/vim-golang-environment/zhCN/)をご参照ください。
## Emacs
Emacsは伝説の神器です。彼女はエディタであるだけでなく、統合環境でもあります。または開発環境の集大成と呼んでもよいかもしれません。これらの機能はユーザの身を万能のオペレーティングシステムに置きます。
![](images/1.4.emacs.png?raw=true)
図1.10 EmacsでGoを編集するメイン画面
1. Emacsのハイライト表示設定
cp $GOROOT/misc/emacs/* ~/.emacs.d/
2. [Gocode](https://github.com/nsf/gocode/)をインストール
go get -u github.com/nsf/gocode
gocodeはデフォルトで`$GOBIN`の下にインストールされます。
3. [Gocode](https://github.com/nsf/gocode/)を設定
~ cd $GOPATH/src/github.com/nsf/gocode/emacs
~ cp go-autocomplete.el ~/.emacs.d/
~ gocode set propose-builtins true
propose-builtins true
~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // あなたのパスに置き換えてください。
lib-path "/home/border/gocode/pkg/linux_amd64"
~ gocode set
propose-builtins true
lib-path "/home/border/gocode/pkg/linux_amd64"
4. [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete)をインストールする必要があります。
AutoCompleteをダウンロードして解凍します。
~ make install DIR=$HOME/.emacs.d/auto-complete
~/.emacsファイルを設定します。
;;auto-complete
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict")
(ac-config-default)
(local-set-key (kbd "M-/") 'semantic-complete-analyze-inline)
(local-set-key "." 'semantic-complete-self-insert)
(local-set-key ">" 'semantic-complete-self-insert)
詳細情報はこちらを参考にしてくださいhttp://www.emacswiki.org/emacs/AutoComplete
5. .emacsを設定します。
;; golang mode
(require 'go-mode-load)
(require 'go-autocomplete)
;; speedbar
;; (speedbar 1)
(speedbar-add-supported-extension ".go")
(add-hook
'go-mode-hook
'(lambda ()
;; gocode
(auto-complete-mode 1)
(setq ac-sources '(ac-source-go))
;; Imenu & Speedbar
(setq imenu-generic-expression
'(("type" "^type *\\([^ \t\n\r\f]*\\)" 1)
("func" "^func *\\(.*\\) {" 1)))
(imenu-add-to-menubar "Index")
;; Outline mode
(make-local-variable 'outline-regexp)
(setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....")
(outline-minor-mode 1)
(local-set-key "\M-a" 'outline-previous-visible-heading)
(local-set-key "\M-e" 'outline-next-visible-heading)
;; Menu bar
(require 'easymenu)
(defconst go-hooked-menu
'("Go tools"
["Go run buffer" go t]
["Go reformat buffer" go-fmt-buffer t]
["Go check buffer" go-fix-buffer t]))
(easy-menu-define
go-added-menu
(current-local-map)
"Go tools"
go-hooked-menu)
;; Other
(setq show-trailing-whitespace t)
))
;; helper function
(defun go ()
"run current buffer"
(interactive)
(compile (concat "go run " (buffer-file-name))))
;; helper function
(defun go-fmt-buffer ()
"run gofmt on current buffer"
(interactive)
(if buffer-read-only
(progn
(ding)
(message "Buffer is read only"))
(let ((p (line-number-at-pos))
(filename (buffer-file-name))
(old-max-mini-window-height max-mini-window-height))
(show-all)
(if (get-buffer "*Go Reformat Errors*")
(progn
(delete-windows-on "*Go Reformat Errors*")
(kill-buffer "*Go Reformat Errors*")))
(setq max-mini-window-height 1)
(if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t))
(progn
(erase-buffer)
(insert-buffer-substring "*Go Reformat Output*")
(goto-char (point-min))
(forward-line (1- p)))
(with-current-buffer "*Go Reformat Errors*"
(progn
(goto-char (point-min))
(while (re-search-forward "<standard input>" nil t)
(replace-match filename))
(goto-char (point-min))
(compilation-mode))))
(setq max-mini-window-height old-max-mini-window-height)
(delete-windows-on "*Go Reformat Output*")
(kill-buffer "*Go Reformat Output*"))))
;; helper function
(defun go-fix-buffer ()
"run gofix on current buffer"
(interactive)
(show-all)
(shell-command-on-region (point-min) (point-max) "go tool fix -diff"))
6. おめでとうございます。今からあなたはこの神器を使ってGo開発の楽しみを体験できます。デフォルトのspeedbarは閉じています。もし開く場合は ;; (speedbar 1) の前のコメントを取り去るか、*M-x speedbar*を手動で起動してください。
## Eclipse
Eclipseも非常によく使われる開発ツールです。以下ではEclipseを使ってどのようにGoプログラムを編集するかご紹介します。
![](images/1.4.eclipse1.png?raw=true)
図1.11 EclipseでのGo編集のメイン画面
1. まず[Eclipse](http://www.eclipse.org/)をダウンロードしてインストールします。
2. [goclipse](https://code.google.com/p/goclipse/)プラグインをダウンロードします。
http://code.google.com/p/goclipse/wiki/InstallationInstructions
3. gocodeをダウンロードして、goのコード補完を表示させます。
gocodeのGitHubアドレス
https://github.com/nsf/gocode
windowsではgitをインストールする必要があります。通常は[msysgit](https://code.google.com/p/msysgit/)を使います。
cmdでインストールを行います
go get -u github.com/nsf/gocode
以下のコードをダウンロードし、直接go buildでコンパイルしてもかまいません。この場合はgocode.exeが生成されます。
4. [MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)をダウンロードして要求に従いインストールしてください。
5. プラグイン設定
Windows->Reference->Go
(1).Goのコンパイラを設定します。
![](images/1.4.eclipse2.png?raw=true)
図1.12 Goの基本情報を設定します。
(2).Gocodeを設定しますオプション、コード補完、Gocodeのパスは事前に生成したgocode.exeファイルを設定します。
![](images/1.4.eclipse3.png?raw=true)
図1.13 gocode情報を設定します。
(3).GDBを設定しますオプション、テスト用、GDBのパスはMingGWのインストールディレクトリ下のgdb.exeファイルを設定します。
![](images/1.4.eclipse4.png?raw=true)
図1.14 GDB情報の設定
6. テストが成功するか
goプロジェクトを一つ新規作成して、hello.goを作成します
![](images/1.4.eclipse5.png?raw=true)
図1.15 プロジェクトの新規作成とファイルの編集
テストの実行consoleでコマンドを入力する必要があります
![](images/1.4.eclipse6.png?raw=true)
図1.16 Goプログラムのテスト
## IntelliJ IDEA
Javaに親しい読者はideaに詳しいことでしょう。ideaはプラグインを通してgo言語のシンタックスハイライト、コード補完およびリビルドをサポートしています。
1. ideaを先にダウンロードします。ideaはマルチプラットフォームをサポートしていますwin,mac,linux、もしお金があれば正式版を購入します、もし無ければ、コミュニティの無料版を使ってください。Go言語を開発するだけであれば無料版で十分事足ります。
![](images/1.4.idea1.png?raw=true)
2. Goプラグインをインストールし、FileメニューのSettingをクリックします。Pluginsを探したら、Browser repoボタンをクリックします。中国国内のユーザはおそらくエラーが出るかもしれませんが、自分で解決してくれよな。
![](images/1.4.idea3.png?raw=true)
3. この時いくつものプラグインが見つかります。Golangを検索して、download and installをダブルクリックしてください。golangの行末にDownloadedの表示が現れるのを待って、OKをクリックします。
![](images/1.4.idea4.png?raw=true)
その後Applyをクリックすると、IDEが再起動を要求します。
4. 再起動が完了し、新規プロジェクトを作成すると、golangプロジェクトが作成可能であることがお分かりいただけるかとおもいます
![](images/1.4.idea5.png?raw=true)
次に、go sdkの場所を入力するよう促されるかもしれません。普段はいつもC:\Goにインストールされています。Linuxとmacは自分のインストールディレクトリの設定にしたがって、ディレクトリを選択すれば大丈夫です。
## links
* [目次](<preface.md>)
* 前へ: [Goのコマンド](<01.3.md>)
* 次へ: [まとめ](<01.5.md>)

View File

@@ -1,124 +1,124 @@
# 5.4 PostgreSQLデータベースの使用
PostgreSQLはフリーなオブジェクト-リレーショナルデータベースサーバデータベース管理システムです。これは活発なBSDライクなライセンスで公開されています。他のオープンソースなデータベースシステム(MySQLやFirebird)やOracle、Sybase、IBMのDB2やMicrosoft SQL Serverといったプロプライエタリなシステムに対する選択肢の一つです。
PostgreSQLとMySQLを比較すると、これは少々巨大です。これはOracleの代替として設計されているためです。そのため、企業のアプリケーションではPostgreSQLを選択することが賢い選択の一つとなっています。
MySQLはOracleに買収され、現在徐々にクローズされつつあります。(MySQL 5.5.31以降のすべてのバージョンがGPLライセンスを順守していません)。これに鑑み、将来我々もプロジェクトのバックエンドのデータベースとしてMySQLではなくPostgreSQLを選択することになるかもしれません。
## ドライバ
GoはPostgreSQLをサポートしたドライバも非常に多く実装されています。国外では多くの人が開発でこのデータベースを使用しているためです。
- https://github.com/lib/pq database/sqlドライバをサポートしています。純粋にGoで書かれています。
- https://github.com/jbarham/gopgsqldriver database/sqlドライバをサポートしています。純粋にGoで書かれています。
- https://github.com/lxn/go-pgsql database/sqlドライバをサポートしています。純粋にGoで書かれています。
下の例では一つ目のドライバを採用してご説明します。これは使用している人が最も多く、githubでも比較的活発であるからです。
## 実例コード
データベースのテーブル作成文:
CREATE TABLE userinfo
(
uid serial NOT NULL,
username character varying(100) NOT NULL,
department character varying(500) NOT NULL,
Created date,
CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
)
WITH (OIDS=FALSE);
CREATE TABLE userdeatail
(
uid integer,
intro character varying(100),
profile character varying(100)
)
WITH(OIDS=FALSE);
下ではGoがどのようにデータベースのテーブルのデータを操作するか見て行きましょう追加・削除・修正・検索
package main
import (
"database/sql"
"fmt"
_ "https://github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres", "user=astaxie password=astaxie dbname=test sslmode=disable")
checkErr(err)
//データの挿入
stmt, err := db.Prepare("INSERT INTO userinfo(username,department,created) VALUES($1,$2,$3) RETURNING uid")
checkErr(err)
res, err := stmt.Exec("astaxie", "研究開発部門", "2012-12-09")
checkErr(err)
//pgはこの関数をサポートしていません。MySQLのインクリメンタルなIDのようなものが無いためです。
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
//データの更新
stmt, err = db.Prepare("update userinfo set username=$1 where uid=$2")
checkErr(err)
res, err = stmt.Exec("astaxieupdate", 1)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
//データの検索
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, &created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
//データの削除
stmt, err = db.Prepare("delete from userinfo where uid=$1")
checkErr(err)
res, err = stmt.Exec(1)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
db.Close()
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
上のコードによって、PostgreSQLが`$1``$2`といった方法によって引数を渡している様子がお分かりいただけるかとおもいます。MySQLの中の`?`ではありません。また、sql.Openではdsn情報のシンタックスがMySQLのドライバでのdsnシンタックスと異なります。そのため、使用される際はこの違いにご注意ください。
また、pgはLastInsertId関数をサポートしていません。PostgreSQLの内部ではMySQLのインクリメンタルなIDを返すといった実装がないためです。その他のコードはほとんど同じです。
## links
* [目次](<preface.md>)
* 前へ: [SQLiteデータベースの使用](<05.3.md>)
* 次へ: [beedbライブラリを使ってORM開発を行う](<05.5.md>)
# 5.4 PostgreSQLデータベースの使用
PostgreSQLはフリーなオブジェクト-リレーショナルデータベースサーバデータベース管理システムです。これは活発なBSDライクなライセンスで公開されています。他のオープンソースなデータベースシステム(MySQLやFirebird)やOracle、Sybase、IBMのDB2やMicrosoft SQL Serverといったプロプライエタリなシステムに対する選択肢の一つです。
PostgreSQLとMySQLを比較すると、これは少々巨大です。これはOracleの代替として設計されているためです。そのため、企業のアプリケーションではPostgreSQLを選択することが賢い選択の一つとなっています。
MySQLはOracleに買収され、現在徐々にクローズされつつあります。(MySQL 5.5.31以降のすべてのバージョンがGPLライセンスを順守していません)。これに鑑み、将来我々もプロジェクトのバックエンドのデータベースとしてMySQLではなくPostgreSQLを選択することになるかもしれません。
## ドライバ
GoはPostgreSQLをサポートしたドライバも非常に多く実装されています。国外では多くの人が開発でこのデータベースを使用しているためです。
- https://github.com/lib/pq database/sqlドライバをサポートしています。純粋にGoで書かれています。
- https://github.com/jbarham/gopgsqldriver database/sqlドライバをサポートしています。純粋にGoで書かれています。
- https://github.com/lxn/go-pgsql database/sqlドライバをサポートしています。純粋にGoで書かれています。
下の例では一つ目のドライバを採用してご説明します。これは使用している人が最も多く、GitHubでも比較的活発であるからです。
## 実例コード
データベースのテーブル作成文:
CREATE TABLE userinfo
(
uid serial NOT NULL,
username character varying(100) NOT NULL,
department character varying(500) NOT NULL,
Created date,
CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
)
WITH (OIDS=FALSE);
CREATE TABLE userdeatail
(
uid integer,
intro character varying(100),
profile character varying(100)
)
WITH(OIDS=FALSE);
下ではGoがどのようにデータベースのテーブルのデータを操作するか見て行きましょう追加・削除・修正・検索
package main
import (
"database/sql"
"fmt"
_ "https://github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres", "user=astaxie password=astaxie dbname=test sslmode=disable")
checkErr(err)
//データの挿入
stmt, err := db.Prepare("INSERT INTO userinfo(username,department,created) VALUES($1,$2,$3) RETURNING uid")
checkErr(err)
res, err := stmt.Exec("astaxie", "研究開発部門", "2012-12-09")
checkErr(err)
//pgはこの関数をサポートしていません。MySQLのインクリメンタルなIDのようなものが無いためです。
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
//データの更新
stmt, err = db.Prepare("update userinfo set username=$1 where uid=$2")
checkErr(err)
res, err = stmt.Exec("astaxieupdate", 1)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
//データの検索
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, &created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
//データの削除
stmt, err = db.Prepare("delete from userinfo where uid=$1")
checkErr(err)
res, err = stmt.Exec(1)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
db.Close()
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
上のコードによって、PostgreSQLが`$1``$2`といった方法によって引数を渡している様子がお分かりいただけるかとおもいます。MySQLの中の`?`ではありません。また、sql.Openではdsn情報のシンタックスがMySQLのドライバでのdsnシンタックスと異なります。そのため、使用される際はこの違いにご注意ください。
また、pgはLastInsertId関数をサポートしていません。PostgreSQLの内部ではMySQLのインクリメンタルなIDを返すといった実装がないためです。その他のコードはほとんど同じです。
## links
* [目次](<preface.md>)
* 前へ: [SQLiteデータベースの使用](<05.3.md>)
* 次へ: [beedbライブラリを使ってORM開発を行う](<05.5.md>)

View File

@@ -1,7 +1,7 @@
# 13.6 まとめ
この章ではどのように基礎的なGo言語のフレームワークを実装するかについてご紹介しました。フレームワークにはルーティング設計が含まれます。Goのビルトインのhttpパッケージにあるルーティングにはいくつか足りない部分があるため、我々は動的なルーティング規則を設計し、その後MVCモデルにおけるController設計をご紹介しました。controllerはRESTを実装しており、主な考え方はtornadeフレームワークからきています。次にも出るのlayoutおよびテンプレートの自動化技術を実装しました。主に採用したのはGoのビルトインのモデルエンジンです。最後に補足的なログ、設定といった情報の設計をご紹介しました。これらの設計を通して基礎的なフレームワークbeegoを実装しました。現在このフレームワークはすでにgithub上でオープンソースになっています。最後に我々はbeegoを通じてブログシステムの実装を行いました。この実例コードを通してどのように快速にホームページを開発するのかが見渡せたのではないかと思います。
## links
* [目次](<preface.md>)
* 前へ: [ブログの追加/削除/修正の実装](<13.5.md>)
* 次へ: [Webフレームワークの拡張](<14.0.md>)
# 13.6 まとめ
この章ではどのように基礎的なGo言語のフレームワークを実装するかについてご紹介しました。フレームワークにはルーティング設計が含まれます。Goのビルトインのhttpパッケージにあるルーティングにはいくつか足りない部分があるため、我々は動的なルーティング規則を設計し、その後MVCモデルにおけるController設計をご紹介しました。controllerはRESTを実装しており、主な考え方はtornadeフレームワークからきています。次にも出るのlayoutおよびテンプレートの自動化技術を実装しました。主に採用したのはGoのビルトインのモデルエンジンです。最後に補足的なログ、設定といった情報の設計をご紹介しました。これらの設計を通して基礎的なフレームワークbeegoを実装しました。現在このフレームワークはすでにGitHub上でオープンソースになっています。最後に我々はbeegoを通じてブログシステムの実装を行いました。この実例コードを通してどのように快速にホームページを開発するのかが見渡せたのではないかと思います。
## links
* [目次](<preface.md>)
* 前へ: [ブログの追加/削除/修正の実装](<13.5.md>)
* 次へ: [Webフレームワークの拡張](<14.0.md>)

View File

@@ -1,259 +1,259 @@
# 14.4 ユーザの認証
Webアプリケーションを開発する過程で、ユーザ認証は開発者がよくぶつかる問題です。ユーザのログイン、サインアップ、ログアウト等といった操作で、一般的な認証はつの方面の認証に分けることができます
- HTTP BasicとHTTP Digest認証
- サードパーティ認証QQ、weibo、doubian、OPENID、google、github、facebookおよびtwitterなどです
- カスタム定義のユーザログイン、サインアップ、ログアウトは一般的にsession、cookie認証にもとづいています。
beegoは現在このつの方式のどの形式にも対応していません。しかしサードパーティのオープンソースライブラリによって上のつの方法のユーザ認証を実装することができます。しかし後々beegoは前者つの認証を一つ一つ実装するかもしれません。
## HTTP BasicとHTTP Digest認証
この2つの認証はいくつかのアプリケーションが採用している比較的簡単な認証です。現在すでにオープンソースのサードパーティライブラリでこの2つの認証をサポートしています;
github.com/abbot/go-http-auth
下のコードはこれらのライブラリをどのようにbeegoに導入するかを示しています
package controllers
import (
"github.com/abbot/go-http-auth"
"github.com/astaxie/beego"
)
func Secret(user, realm string) string {
if user == "john" {
// password is "hello"
return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
}
return ""
}
type MainController struct {
beego.Controller
}
func (this *MainController) Prepare() {
a := auth.NewBasicAuthenticator("example.com", Secret)
if username := a.CheckAuth(this.Ctx.Request); username == "" {
a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request)
}
}
func (this *MainController) Get() {
this.Data["Username"] = "astaxie"
this.Data["Email"] = "astaxie@gmail.com"
this.TplNames = "index.tpl"
}
上のコードはbeegoのprepare関数を利用しています。正常なロジックを実行する前に認証関数をコールすることで、非常に簡単にhttp authを実装しています。digest認証も同様の原理です。
## oauthとoauth2の認証
oauthとoauth2は現在比較的流行している二種類の認証方式です。サードパーティでちょうどこの認証を実装しているライブラリがあるのですが、国外で実装されたもので、QQ、weiboといった中国国内のアプリケーション認証はありません。
github.com/bradrydzewski/go.auth
下のコードはどのようにしてこのライブラリをbeegoの中に導入しoauth認証を実装するか示しています。ここではgithubを例にしています
1. ルーティングを2本追加
beego.RegisterController("/auth/login", &controllers.GithubController{})
beego.RegisterController("/mainpage", &controllers.PageController{})
2. 次にGithubControllerログインの画面を処理
package controllers
import (
"github.com/astaxie/beego"
"github.com/bradrydzewski/go.auth"
)
const (
githubClientKey = "a0864ea791ce7e7bd0df"
githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca"
)
type GithubController struct {
beego.Controller
}
func (this *GithubController) Get() {
// set the auth parameters
auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV")
auth.Config.LoginSuccessRedirect = "/mainpage"
auth.Config.CookieSecure = false
githubHandler := auth.Github(githubClientKey, githubSecretKey)
githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request)
}
3. ログインに成功した後のページ画面を処理
package controllers
import (
"github.com/astaxie/beego"
"github.com/bradrydzewski/go.auth"
"net/http"
"net/url"
)
type PageController struct {
beego.Controller
}
func (this *PageController) Get() {
// set the auth parameters
auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV")
auth.Config.LoginSuccessRedirect = "/mainpage"
auth.Config.CookieSecure = false
user, err := auth.GetUserCookie(this.Ctx.Request)
//if no active user session then authorize user
if err != nil || user.Id() == "" {
http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther)
return
}
//else, add the user to the URL and continue
this.Ctx.Request.URL.User = url.User(user.Id())
this.Data["pic"] = user.Picture()
this.Data["id"] = user.Id()
this.Data["name"] = user.Name()
this.TplNames = "home.tpl"
}
全体の流れは以下のようになります。まずブラウザを開いてアドレスを入力します:
![](images/14.4.github.png?raw=true)
図14.4 ログインボタンを持つトップページの表示
次にリンクをクリックすると以下のようなインターフェースが現れます:
![](images/14.4.github2.png?raw=true)
図14.5 ログインボタンをクリックしてgithubの権限取得ページを表示
Authorize appをクリックすると以下のようなインターフェースが現れます
![](images/14.4.github3.png?raw=true)
図14.6 権限取得にログインした後表示される取得済みのgithub情報のページ
## カスタム定義認証
カスタム定義の認証は一般的にはsessionと組み合わせて検証されます。以下のコードはあるbeegoのオープンソースブログに基づいています
//ログイン処理
func (this *LoginController) Post() {
this.TplNames = "login.tpl"
this.Ctx.Request.ParseForm()
username := this.Ctx.Request.Form.Get("username")
password := this.Ctx.Request.Form.Get("password")
md5Password := md5.New()
io.WriteString(md5Password, password)
buffer := bytes.NewBuffer(nil)
fmt.Fprintf(buffer, "%x", md5Password.Sum(nil))
newPass := buffer.String()
now := time.Now().Format("2006-01-02 15:04:05")
userInfo := models.GetUserInfo(username)
if userInfo.Password == newPass {
var users models.User
users.Last_logintime = now
models.UpdateUserInfo(users)
//ログイン成功でsessionを設定
sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
sess.Set("uid", userInfo.Id)
sess.Set("uname", userInfo.Username)
this.Ctx.Redirect(302, "/")
}
}
//サインアップ処理
func (this *RegController) Post() {
this.TplNames = "reg.tpl"
this.Ctx.Request.ParseForm()
username := this.Ctx.Request.Form.Get("username")
password := this.Ctx.Request.Form.Get("password")
usererr := checkUsername(username)
fmt.Println(usererr)
if usererr == false {
this.Data["UsernameErr"] = "Username error, Please to again"
return
}
passerr := checkPassword(password)
if passerr == false {
this.Data["PasswordErr"] = "Password error, Please to again"
return
}
md5Password := md5.New()
io.WriteString(md5Password, password)
buffer := bytes.NewBuffer(nil)
fmt.Fprintf(buffer, "%x", md5Password.Sum(nil))
newPass := buffer.String()
now := time.Now().Format("2006-01-02 15:04:05")
userInfo := models.GetUserInfo(username)
if userInfo.Username == "" {
var users models.User
users.Username = username
users.Password = newPass
users.Created = now
users.Last_logintime = now
models.AddUser(users)
//ログイン成功でsessionを設定
sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
sess.Set("uid", userInfo.Id)
sess.Set("uname", userInfo.Username)
this.Ctx.Redirect(302, "/")
} else {
this.Data["UsernameErr"] = "User already exists"
}
}
func checkPassword(password string) (b bool) {
if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok {
return false
}
return true
}
func checkUsername(username string) (b bool) {
if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok {
return false
}
return true
}
ユーザのログインとサインアップがあって、その他のモジュールでも以下のようにユーザがログインしているかどうかの判断を追加することができます:
func (this *AddBlogController) Prepare() {
sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
sess_uid := sess.Get("userid")
sess_username := sess.Get("username")
if sess_uid == nil {
this.Ctx.Redirect(302, "/admin/login")
return
}
this.Data["Username"] = sess_username
}
## links
* [目次](<preface.md>)
* 前へ: [フォームおよび検証のサポート](<14.3.md>)
* 次へ: [多言語サポート](<14.5.md>)
# 14.4 ユーザの認証
Webアプリケーションを開発する過程で、ユーザ認証は開発者がよくぶつかる問題です。ユーザのログイン、サインアップ、ログアウト等といった操作で、一般的な認証はつの方面の認証に分けることができます
- HTTP BasicとHTTP Digest認証
- サードパーティ認証QQ、weibo、doubian、OPENID、google、GitHub、facebookおよびtwitterなどです
- カスタム定義のユーザログイン、サインアップ、ログアウトは一般的にsession、cookie認証にもとづいています。
beegoは現在このつの方式のどの形式にも対応していません。しかしサードパーティのオープンソースライブラリによって上のつの方法のユーザ認証を実装することができます。しかし後々beegoは前者つの認証を一つ一つ実装するかもしれません。
## HTTP BasicとHTTP Digest認証
この2つの認証はいくつかのアプリケーションが採用している比較的簡単な認証です。現在すでにオープンソースのサードパーティライブラリでこの2つの認証をサポートしています;
github.com/abbot/go-http-auth
下のコードはこれらのライブラリをどのようにbeegoに導入するかを示しています
package controllers
import (
"github.com/abbot/go-http-auth"
"github.com/astaxie/beego"
)
func Secret(user, realm string) string {
if user == "john" {
// password is "hello"
return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
}
return ""
}
type MainController struct {
beego.Controller
}
func (this *MainController) Prepare() {
a := auth.NewBasicAuthenticator("example.com", Secret)
if username := a.CheckAuth(this.Ctx.Request); username == "" {
a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request)
}
}
func (this *MainController) Get() {
this.Data["Username"] = "astaxie"
this.Data["Email"] = "astaxie@gmail.com"
this.TplNames = "index.tpl"
}
上のコードはbeegoのprepare関数を利用しています。正常なロジックを実行する前に認証関数をコールすることで、非常に簡単にhttp authを実装しています。digest認証も同様の原理です。
## oauthとoauth2の認証
oauthとoauth2は現在比較的流行している二種類の認証方式です。サードパーティでちょうどこの認証を実装しているライブラリがあるのですが、国外で実装されたもので、QQ、weiboといった中国国内のアプリケーション認証はありません。
github.com/bradrydzewski/go.auth
下のコードはどのようにしてこのライブラリをbeegoの中に導入しoauth認証を実装するか示しています。ここではGitHubを例にしています
1. ルーティングを2本追加
beego.RegisterController("/auth/login", &controllers.GithubController{})
beego.RegisterController("/mainpage", &controllers.PageController{})
2. 次にGithubControllerログインの画面を処理
package controllers
import (
"github.com/astaxie/beego"
"github.com/bradrydzewski/go.auth"
)
const (
githubClientKey = "a0864ea791ce7e7bd0df"
githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca"
)
type GithubController struct {
beego.Controller
}
func (this *GithubController) Get() {
// set the auth parameters
auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV")
auth.Config.LoginSuccessRedirect = "/mainpage"
auth.Config.CookieSecure = false
githubHandler := auth.Github(githubClientKey, githubSecretKey)
githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request)
}
3. ログインに成功した後のページ画面を処理
package controllers
import (
"github.com/astaxie/beego"
"github.com/bradrydzewski/go.auth"
"net/http"
"net/url"
)
type PageController struct {
beego.Controller
}
func (this *PageController) Get() {
// set the auth parameters
auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV")
auth.Config.LoginSuccessRedirect = "/mainpage"
auth.Config.CookieSecure = false
user, err := auth.GetUserCookie(this.Ctx.Request)
//if no active user session then authorize user
if err != nil || user.Id() == "" {
http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther)
return
}
//else, add the user to the URL and continue
this.Ctx.Request.URL.User = url.User(user.Id())
this.Data["pic"] = user.Picture()
this.Data["id"] = user.Id()
this.Data["name"] = user.Name()
this.TplNames = "home.tpl"
}
全体の流れは以下のようになります。まずブラウザを開いてアドレスを入力します:
![](images/14.4.github.png?raw=true)
図14.4 ログインボタンを持つトップページの表示
次にリンクをクリックすると以下のようなインターフェースが現れます:
![](images/14.4.github2.png?raw=true)
図14.5 ログインボタンをクリックしてGitHubの権限取得ページを表示
Authorize appをクリックすると以下のようなインターフェースが現れます
![](images/14.4.github3.png?raw=true)
図14.6 権限取得にログインした後表示される取得済みのGitHub情報のページ
## カスタム定義認証
カスタム定義の認証は一般的にはsessionと組み合わせて検証されます。以下のコードはあるbeegoのオープンソースブログに基づいています
//ログイン処理
func (this *LoginController) Post() {
this.TplNames = "login.tpl"
this.Ctx.Request.ParseForm()
username := this.Ctx.Request.Form.Get("username")
password := this.Ctx.Request.Form.Get("password")
md5Password := md5.New()
io.WriteString(md5Password, password)
buffer := bytes.NewBuffer(nil)
fmt.Fprintf(buffer, "%x", md5Password.Sum(nil))
newPass := buffer.String()
now := time.Now().Format("2006-01-02 15:04:05")
userInfo := models.GetUserInfo(username)
if userInfo.Password == newPass {
var users models.User
users.Last_logintime = now
models.UpdateUserInfo(users)
//ログイン成功でsessionを設定
sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
sess.Set("uid", userInfo.Id)
sess.Set("uname", userInfo.Username)
this.Ctx.Redirect(302, "/")
}
}
//サインアップ処理
func (this *RegController) Post() {
this.TplNames = "reg.tpl"
this.Ctx.Request.ParseForm()
username := this.Ctx.Request.Form.Get("username")
password := this.Ctx.Request.Form.Get("password")
usererr := checkUsername(username)
fmt.Println(usererr)
if usererr == false {
this.Data["UsernameErr"] = "Username error, Please to again"
return
}
passerr := checkPassword(password)
if passerr == false {
this.Data["PasswordErr"] = "Password error, Please to again"
return
}
md5Password := md5.New()
io.WriteString(md5Password, password)
buffer := bytes.NewBuffer(nil)
fmt.Fprintf(buffer, "%x", md5Password.Sum(nil))
newPass := buffer.String()
now := time.Now().Format("2006-01-02 15:04:05")
userInfo := models.GetUserInfo(username)
if userInfo.Username == "" {
var users models.User
users.Username = username
users.Password = newPass
users.Created = now
users.Last_logintime = now
models.AddUser(users)
//ログイン成功でsessionを設定
sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
sess.Set("uid", userInfo.Id)
sess.Set("uname", userInfo.Username)
this.Ctx.Redirect(302, "/")
} else {
this.Data["UsernameErr"] = "User already exists"
}
}
func checkPassword(password string) (b bool) {
if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok {
return false
}
return true
}
func checkUsername(username string) (b bool) {
if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok {
return false
}
return true
}
ユーザのログインとサインアップがあって、その他のモジュールでも以下のようにユーザがログインしているかどうかの判断を追加することができます:
func (this *AddBlogController) Prepare() {
sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
sess_uid := sess.Get("userid")
sess_username := sess.Get("username")
if sess_uid == nil {
this.Ctx.Redirect(302, "/admin/login")
return
}
this.Data["Username"] = sess_username
}
## links
* [目次](<preface.md>)
* 前へ: [フォームおよび検証のサポート](<14.3.md>)
* 次へ: [多言語サポート](<14.5.md>)