20190530のGoに関する記事は15件です。

Go入門②~package/importについて・簡単なtestコードを書いてみる~

前回はGoのインストールと、VSCodeで環境を整えてハローワールドするところまでやった。
今回はディレクトリの構成の話と、簡単なテストコードを書いて実行するところまでやってみる。

package

Goではすべての要素は、何らかのパッケージに属していなければならない。

また、1つのファイルに記述できるのは単一のパッケージのみで、複数パッケージを宣言するとエラーとなる。

Goで書かれたプログラムは package main と宣言したファイルの中の、 mainメソッドからスタートすることになる。

また、1つのディレクトリには1種類のパッケージ定義のみ許容される。
→これはイメージを掴むために実際にやってみる。試しに以下のようなファイル構成をとってみた。

.
├── hello.go
└── hey.go

そして、片方のファイルの中でmainではないパッケージ名を宣言してみる

hey.go
package hey

func hey() {
  // nothing to do
}

すると確かに下記のような感じで怒られる

> go build
can't load package: package Hello: found packages main (hello.go) and hey (hey.go) in /Users/user/go/src/Hello

フォルダ名や宣言しているpackage名に気をつける必要があることがわかった。

import

他のパッケージの要素をそのファイルで使用するために使う。

前回ハローワールドしたときも、文字列の出力のために必要なfmtをインポートしていた。

※importしたのに使わなかったパッケージがあると、コンパイル時にエラーが出てしまう

goTest.go
package main

import "fmt"
import "notRefered" // 参照されていないパッケージ

func main() {
    fmt.Println("Hello, World!")
}
goTest.go:3:8: cannot find package "notRefered" in any of:
    /usr/local/go/src/notRefered (from $GOROOT)
    /Users/user/go/src/notRefered (from $GOPATH)

しかし、これに関しては、前回紹介したVSCodeの環境であれば勝手にimport文を削除or追加してくれた。

ファイル分割してみる

こんな感じのファイル構成にしてみた

greeting
    ├── countries
    │   ├── china.go
    │   ├── germany.go
    │   └── japan.go
    └── main.go
main.go
package main

import "fmt"
import "./countries"

func main() {
    fmt.Println(countries.SayHelloInJapanese())
    fmt.Println(countries.SayHelloInChinese())
    fmt.Println(countries.SayHelloInGerman())
}

importで、package名だけ書くと、$GOPATHを見に行くので、自分で他のディレクトリに作成したパッケージをimportしたい場合は、上記のように相対パスで指定してあげる必要がある。

china.go
package countries

func SayHelloInChinese() string {
    return "Nihao!"
}
japan.go
package countries

func SayHelloInJapanese() string {
    return "Konnichiha!"
}
germany.go
package countries

func SayHelloInGerman() string {
    return "GutenTag!"
}

実行

> go run main.go
Konnichiha!
Nihao!
GutenTag!

Testコード書いてみる

Goでは*_test.go となっているファイルはテストコードとして扱ってくれる。

先程のcountriesパッケージのテストコードを作成する。

countries_test.go
package countries

import "testing"

func TestSayHelloInJapanese(test *testing.T) {
    expect := "Konnichiha!"
    actual := SayHelloInJapanese()
    if expect != actual {
        test.Errorf("%s != %s", expect, actual)
    }
}
func TestSayHelloInChinese(test *testing.T) {
    expect := "Nihao!"
    actual := SayHelloInChinese()
    if expect != actual {
        test.Errorf("%s != %s", expect, actual)
    }
}
func TestSayHelloInGerman(test *testing.T) {
    expect := "GutenTag!"
    actual := SayHelloInGerman()
    if expect != actual {
        test.Errorf("%s != %s", expect, actual)
    }
}

ディレクトリ階層はこんな感じ

├── countries
│   ├── china.go
│   ├── countries_test.go
│   ├── germany.go
│   └── japan.go
└── main.go

テストを実行してみる

> go test ./countries -v
=== RUN   TestSayHelloInJapanese
--- PASS: TestSayHelloInJapanese (0.00s)
=== RUN   TestSayHelloInChinese
--- PASS: TestSayHelloInChinese (0.00s)
=== RUN   TestSayHelloInGerman
--- PASS: TestSayHelloInGerman (0.00s)
PASS
ok      greeting/countries      0.005s

無事にテストが実行され、PASSできた :clap:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

golangで非同期にタスクを行ってリトライしてくれる君を作った

What

非同期でタスクを実行、追加できるようにするくん

Why

GCPのタスクキューを見て、非同期でタスクをポンポン投げて勝手に実行、リトライしてくれるようなものを作ってみたかった

リポジトリ

コードはこちらに
https://github.com/nozo-moto/taskqueue

使い方

// set task queue interval
taskQueue := taskqueue.New(100 * time.Millisecond)
defer taskQueue.Stop()
// Run Task Queue Job in background.
go taskQueue.Run()

// Add Task, you can set retry coun
// if taskQueue.Stop called taskQueue.Add return err
err := taskQueue.Add(
    func() error {
        fmt.Printf("hoge\n")
        return nil
    },
    5,
)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dep ensureでbuild.NoGoErrorが出た場合

github.com/aws/aws-xray-sdk-goをdepを使って取り込もうとし、READMEに従いdep ensureコマンドを入力したら下記エラーに出くわした。

$ dep ensure -add github.com/aws/aws-xray-sdk-go
Fetching sources...

Solving failure: No versions of github.com/aws/aws-xray-sdk-go met constraints:
    v0.9.4: Could not introduce github.com/aws/aws-xray-sdk-go@v0.9.4, as its subpackage github.com/aws/aws-xray-sdk-go does not contain usable Go code (*build.NoGoError).. (Package is required by (root).)

これはgithub.com/aws/aws-xray-sdk-goの配下に.goファイルが見つからないためエラーになっている模様。
.goファイルが入っているpackageを指定したらエラーなく取り込めた

$ dep ensure -add github.com/aws/aws-xray-sdk-go/xray                                                                                                   
Fetching sources...

"github.com/aws/aws-xray-sdk-go/xray" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/.
If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

トレンドの「ojichat」で遊びたいがためにGoを導入してみた。

おじちゃっと。発想が天才。

本家Github

はてなブックマーク - GitHub - greymd/ojichat: おじさんがLINEやメールで送ってきそうな文を生成する

こんなときに

  • 「ojichat」をためしたい
  • 「ojichat」でおじさんと遊びたい
  • 「ojichat」でおじさんに名前呼ばれたい
  • 「ojichat」で…(ry

  • Go言語をとりあえず使ってみたい

手順

  1. homebrewでインストール
  2. パスを通す
  3. .bash_profileを再読込
  4. Goでhello worldしてみる。
  5. ojichatをインストール
  6. おじさんと遊ぼう

1. homebrewでインストール

brew install go

わりと重い。

2. パスを通す

export GOPATH=$HOME/go/
export PATH=$GOPATH/bin:$PATH

ホームフォルダ直下の
.bash_profileに以下を追記。

3. .bash_profileの読み込み

source .bash_profile

まじで忘れる。「command not found」が返ってくる原因、大抵これ。

4. Goでhello worldしてみる。(蛇足)

適当なディレクトリに hello.goというファイルを以下の内容で作る。

hello.go
package main
import "fmt"

func main(){
    fmt.Printf("Hello, world\n")
}

ディレクトリに移動して、以下のコマンドを叩く。

go run hello.go

Hello, world

5. ojichatをインストール

go get -u github.com/greymd/ojichat

これも結構重い。時間かかる。

6. おじさんと遊ぼう

ランダムに遊ぶ

ojichat

りかちゃん、会社をサボるなんて、悪い子だなぁ???冗談??♥ ?バー?好きかな?( ̄ー ̄?)✋❓今週の日曜日、仕事が早く終わりそうなんだけど、ご飯でもどうかな✋❓⁉?⁉️( ̄ー ̄?)

名前を読んでもらう

ojichat どらら

ヤッホー?✋???どららちゃん、元気かな?⁉️❓今日はどんな一日だッタ( ̄ー ̄?)⁉そろそろご飯行こうよ?ご要望とかはあるのかな(笑)???⁉️❓

ときどき名前読んでもらえないこともある。根気よくチャレンジしよう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

raylib-goのtips的なもの

raylibとは?

raylibのサイトから

raylibはビデオゲームのプログラミングを楽しむためのシンプルで使いやすいライブラリです。

ライブラリはC言語で書かれていて、色々な言語のバインディングがあります。(C#,Go,Python,Ruby,Lua等)

2D、3D両方対応していますがここでは主に2Dゲーム用途で書いてます。

raylib-go

raylib-goはraylibのGo言語バインディングです。

インストール

Go開発環境はすでにある前提で書きます。
各環境によってインストール前に必要なものがあるので注意してください。詳細はこちらで。

go getでインストール。

go get -v -u github.com/gen2brain/raylib-go/raylib

自分の環境(LinuxMint)では1つ警告が出ましたがよくわからないのでスルーしました。
インストールできたらサンプルを実行してみて動作するか確認します。

raylibのバージョンは2.1でした。

チートシート

raylib cheatsheet
raylibで使える関数一覧になります。raylib-goには無いものもあるのでGoDocも合わせて見ます。

GoDoc

raylib-go GoDoc
Goで使用可能な関数の一覧です。

付属サンプル

raylibインストール場所のexamplesフォルダにサンプルがあります。
一通り実行してみると良いと思う。

ウィンドウ

基本のウィンドウ表示

main.go
package main

import rl "github.com/gen2brain/raylib-go/raylib"

func main() {
    rl.InitWindow(800, 450, "window title.")
    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        // 計算はここで

        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)
        // 描画処理はここに

        rl.EndDrawing()
    }

    rl.CloseWindow()
}

コンフィグ

func SetConfigFlags(flags byte)
ウィンドウ初期化前に設定する必要がある。

フラグ一覧、|で結合出来ます。
FlagShowLogo, FlagFullscreenMode, FlagWindowResizable, FlagWindowUndecorated, FlagWindowTransparent, FlagMsaa4xHint, FlagVsyncHint

ロゴ表示例
rl.SetConfigFlags(rl.FlagShowLogo)

スクリーンサイズ、モニターサイズを取得

スクリーンは作成したウィンドウのサイズ。どちらもInitWindowの後じゃないと取得できない。

main.go
package main

import (
    "fmt"

    rl "github.com/gen2brain/raylib-go/raylib"
)

func main() {
    rl.InitWindow(800, 450, "window title.")
    mw := rl.GetMonitorWidth(0)
    mh := rl.GetMonitorHeight(0)
    fmt.Printf("monitor width=%d height=%d\n", mw, mh)
    sw := rl.GetScreenWidth()
    sh := rl.GetScreenHeight()
    fmt.Printf("screen width=%d height=%d\n", sw, sh)

    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)
        rl.EndDrawing()
    }

    rl.CloseWindow()
}

フルスクリーン切り替え

func ToggleFullscreen()
フルスクリーン時はモニターの解像度がそのまま描画領域になる。

前フレームからの時間を取得

func GetFrameTime() float32

スクリーン座標系

左上が(0, 0)で右下方向がプラス。テキスト、テクスチャ、マウス等。

テキスト描画

main.go
package main

import rl "github.com/gen2brain/raylib-go/raylib"

func main() {
    rl.InitWindow(800, 450, "window title.")
    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)

        rl.DrawText("Text draw test.", 100, 100, 20, rl.Black)
        rl.DrawFPS(0, 0)

        rl.EndDrawing()
    }

    rl.CloseWindow()
}

デフォルトフォント使用

func DrawText(text string, posX int32, posY int32, fontSize int32, color Color)
colorには定義済みのものを指定したり、rl.Color{}rl.NewColor()で好きな色を作成出来ます。
ASCII文字のみ使用可。

TrueTypeフォント読み込み、描画

func LoadFont(fileName string) Font
func UnloadFont(font Font) // 使い終わったらアンロードする
func DrawTextEx(font Font, text string, position Vector2, fontSize float32, spacing float32, tint Color)
日本語表示できず。仕様?
(追記:raylib v2.5からユニコード対応だそうです。)

FPS表示

func DrawFPS(posX int32, posY int32)

テクスチャ

func LoadTexture(fileName string) Texture2D
func UnloadTexture(texture Texture2D)
GPUメモリに読み込まれる。
テクスチャのロードはウィンドウ作成後でなければならない。デフォルトのフィルタは無し。使い終わったらアンロードする。

テクスチャ描画

使用画像
gopher.png
Gopherくんのような画像。

main.go
package main

import rl "github.com/gen2brain/raylib-go/raylib"

func main() {
    rl.InitWindow(300, 200, "window title.")

    gopher := rl.LoadTexture("gopher.png")

    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)

        rl.DrawTexture(gopher, 0, 0, rl.White) // テクスチャ描画

        rl.EndDrawing()
    }

    rl.UnloadTexture(gopher) // アンロードを忘れずに
    rl.CloseWindow()
}

左右反転、上下反転

描画を反転させたい場合、
func DrawTexturePro(texture Texture2D, sourceRec, destRec Rectangle, origin Vector2, rotation float32, tint Color)
を使います。

sourceRecはテクスチャの領域、destRectはスクリーンの領域。
テクスチャの方のWidthにマイナスをつけると左右反転、Heightにマイナスをつけると上下反転になる。

main.go
package main

import rl "github.com/gen2brain/raylib-go/raylib"

func main() {
    rl.InitWindow(300, 200, "window title.")

    gopher := rl.LoadTexture("gopher.png")

    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)

        rl.DrawTexture(gopher, 0, 0, rl.White)
        rl.DrawTexturePro(gopher, rl.NewRectangle(0, 0, -32, 32), rl.NewRectangle(32, 0, 32, 32), rl.Vector2{}, 0, rl.White)
        rl.DrawTexturePro(gopher, rl.NewRectangle(0, 0, 32, -32), rl.NewRectangle(64, 0, 32, 32), rl.Vector2{}, 0, rl.White)
        rl.DrawTexturePro(gopher, rl.NewRectangle(0, 0, -32, -32), rl.NewRectangle(96, 0, 32, 32), rl.Vector2{}, 0, rl.White)

        rl.EndDrawing()
    }

    rl.UnloadTexture(gopher)
    rl.CloseWindow()
}

左から順番に描画。
スクリーンショット_2019-05-28_15-37-56.png

背面カリング

raylibでは初期化時に背面カリングが有効になるように設定されている。
どうしても無効にしたい場合raylibフォルダにあるrlgl.hを開き、1816行にあるglEnable(GL_CULL_FACE);をコメントアウトする。

ブレンドモード

描画時のブレンドモードを変えることが出来る。
func BeginBlendMode(mode BlendMode)
func EndBlendMode()

モードはBlendAlpha, BlendAdditive, BlendMultipliedの3つ。デフォルトはアルファブレンディング。

使用例
rl.BeginBlendMode(rl.BlendAdditive)

// テクスチャ等描画

rl.EndBlendMode()

描画順

描画関数を呼んだ順に描画される。

キーボード

func IsKeyPressed(key int32) bool // キーを押した瞬間か
func IsKeyDown(key int32) bool // 押されているか

func IsKeyReleased(key int32) bool // キーを離した瞬間か
func IsKeyUp(key int32) bool // 押されていないか

keyの定数はGoDocを見る。

main.go
package main

import (
    "fmt"

    rl "github.com/gen2brain/raylib-go/raylib"
)

func main() {
    rl.InitWindow(300, 200, "window title.")
    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        if rl.IsKeyPressed(rl.KeyA) {
            fmt.Println("pressed A key.")
        } else if rl.IsKeyReleased(rl.KeyA) {
            fmt.Println("released A key.")
        }

        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)

        rl.EndDrawing()
    }

    rl.CloseWindow()
}

マウス

func GetMousePosition() Vector2
func IsMouseButtonDown(button int32) bool
func IsMouseButtonPressed(button int32) bool
func IsMouseButtonReleased(button int32) bool
func IsMouseButtonUp(button int32) bool

カーソル位置描画。

main.go
package main

import (
    "fmt"

    rl "github.com/gen2brain/raylib-go/raylib"
)

func main() {
    rl.InitWindow(800, 450, "window title.")
    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        rl.BeginDrawing()
        rl.ClearBackground(rl.RayWhite)

        m := rl.GetMousePosition()
        rl.DrawText(fmt.Sprintf("mouse x=%v y=%v", m.X, m.Y), 0, 0, 20, rl.Black)

        rl.EndDrawing()
    }

    rl.CloseWindow()
}

衝突判定

簡単なものは用意されている。
func CheckCollisionRecs(rec1, rec2 Rectangle) bool
func CheckCollisionCircles(center1 Vector2, radius1 float32, center2 Vector2, radius2 float32) bool
func CheckCollisionCircleRec(center Vector2, radius float32, rec Rectangle) bool
func CheckCollisionPointRec(point Vector2, rec Rectangle) bool
func CheckCollisionPointCircle(point Vector2, center Vector2, radius float32) bool
func CheckCollisionPointTriangle(point, p1, p2, p3 Vector2) bool

2Dカメラ

移動、回転、ズーム対応。
type Camera2D
func NewCamera2D(offset, target Vector2, rotation, zoom float32) Camera2D
func BeginMode2D(camera Camera2D)
func EndMode2D()
回転、ズームが入ると分かりづらい。

キーボードでカメラを操作するサンプル。

main.go
package main

import (
    "fmt"

    rl "github.com/gen2brain/raylib-go/raylib"
)

func main() {
    rl.InitWindow(800, 450, "2DCamera test.")

    uvgrid := rl.LoadTexture("uvgrid.png")
    camera := rl.Camera2D{}
    camera.Zoom = 1.0

    rl.SetTargetFPS(60)

    for !rl.WindowShouldClose() {
        dt := rl.GetFrameTime()

        if rl.IsKeyPressed(rl.KeyOne) {
            camera.Zoom = 1.0
        } else if rl.IsKeyPressed(rl.KeyTwo) {
            camera.Zoom = 2.0
        } else if rl.IsKeyPressed(rl.KeyThree) {
            camera.Zoom = 4.0
        } else if rl.IsKeyPressed(rl.KeyFour) {
            camera.Zoom = 8.0
        }

        if rl.IsKeyDown(rl.KeyRight) {
            camera.Offset.X -= 180. * dt
        } else if rl.IsKeyDown(rl.KeyLeft) {
            camera.Offset.X += 180. * dt
        }
        camera.Target.X = -camera.Offset.X
        if rl.IsKeyDown(rl.KeyDown) {
            camera.Offset.Y -= 180. * dt
        } else if rl.IsKeyDown(rl.KeyUp) {
            camera.Offset.Y += 180. * dt
        }
        camera.Target.Y = -camera.Offset.Y

        if rl.IsKeyDown(rl.KeyA) {
            camera.Rotation -= 60. * dt
        } else if rl.IsKeyDown(rl.KeyD) {
            camera.Rotation += 60. * dt
        }

        rl.BeginDrawing()

        rl.ClearBackground(rl.RayWhite)

        rl.BeginMode2D(camera) // カメラを適応させたい物だけはさむ。

        rl.DrawTexture(uvgrid, 0, 0, rl.White)

        rl.EndMode2D()

        rl.DrawText(fmt.Sprintf("offset x=%.f y=%.f", camera.Offset.X, camera.Offset.Y), 0, 0, 20, rl.Black)
        rl.DrawText(fmt.Sprintf("target x=%.f y=%.f", camera.Target.X, camera.Target.Y), 0, 20, 20, rl.Black)
        rl.DrawText(fmt.Sprintf("rotation %.f", camera.Rotation), 0, 40, 20, rl.Black)
        rl.DrawText(fmt.Sprintf("zoom %v", camera.Zoom), 0, 60, 20, rl.Black)

        rl.EndDrawing()
    }
    rl.UnloadTexture(uvgrid)

    rl.CloseWindow()
}

画像はこれを使用。
uvgrid.png

最後に

以上、メモのようなtipsのようなものでした。
ここにあげたものはraylibの機能のほんの一部なので、もっと詳しく知りたいかたはHPの方を見てください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Goでhtmlメール自動送信

1. はじめに

誰かにhtmlメールを送信するサービスはたくさんありますが、SMTPやhtmlメールの
テンプレートなど、参考になるサイトがいくつかあり、意外に自分で作れるかもと思い、作ってみました。

2. コード

完成したコードはgithubに置いてます。
https://github.com/koki-iwaizumi/html_email

※GoのDB周りはxormを使っています。

3. 処理の流れ

①MySQLに保存してあるユーザ情報を取得(const EMAIL_TARGET_STATUSとjintoカラムが一致するユーザーを取得)
②メールテンプレート作成
③ユーザー毎にメールの文言修正後、SMTPでメール送信
④全員にメール送信したら、コンソール上で'PRESS Y'と表示されるので、'Y'を押しエンターを押すと終了

3. 使い方

  1. MySQLに下記を登録します。
person.sql
CREATE TABLE IF NOT EXISTS `person` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `company` varchar(255) NOT NULL DEFAULT '',
    `email` varchar(255) NOT NULL DEFAULT '',
    `name` varchar(255) NOT NULL DEFAULT '',
    `honorific` varchar(255) NOT NULL DEFAULT '',
    `post_h` varchar(3) NOT NULL DEFAULT '',
    `post_l` varchar(4) NOT NULL DEFAULT '',
    `prefecture` varchar(255) NOT NULL DEFAULT '',
    `address_h` varchar(25) NOT NULL DEFAULT '',
    `address_l` varchar(25) NOT NULL DEFAULT '',
    `jinto` varchar(10) NOT NULL DEFAULT '',
    `saibaru` varchar(10) NOT NULL DEFAULT '',
    `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `company` (`company`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `person` (`id`, `company`, `email`, `name`, `honorific`, `post_h`, `post_l`, `prefecture`, `address_h`, `address_l`, `jinto`, `saibaru`, `created`) VALUES
(1, 'test_company', 'info@test.test', 'testname', '様', '111', '1111', 'prefecture', 'address_h', 'address_l', '未送信', '未送信', '2019-05-14 23:21:54');
  1. email設定の変更 main.go
main.go
const (
    EMAIL_HOST                = "*"
    EMAIL_PORT                = "*"
    EMAIL_USER                = "*"
    EMAIL_PASSWORD            = "*"
    EMAIL_FROMNAME            = "*"
    EMAIL_FROMADDRESS         = "*"
    EMAIL_SUBJECT             = "IoTデータロガーのご紹介!"
    EMAIL_PATH                = "view/email.html"
    EMAIL_TARGET_STATUS       = "未送信"
    EMAIL_TARGET_STATUS_AFTER = "メール送信済み"
)
  1. db設定の変更 model/base.go
model/base.go
const (
    MODEL_DRIVER   = "mysql"
    MODEL_USER     = "*"
    MODEL_PASSWORD = "*"
    MODEL_NAME     = "*"
)
  1. 実行!

$ go run main.go

5. 参考にしたサイト

htmlメールは下記のサイトを参考にさせていだきました。
https://blog.kannart.co.jp/coding/1093/

SMTPに関しては下記を参考にさせていだきました。
https://qiita.com/cyabane/items/b0cbc9bc7526c56f5724

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語 コンソールモードでコンソール上にグラフ、ボタン、スクロールテキストを表示するtermdashの紹介

概要

通常コンソールにはテキストしか表示できないと思い込んでいました。紹介するtermdashを使えばコンソール上にGUIもどきのものが表示できます。

機能

下記の画像はデモをWindowsで実行したものです。

image.png

次が画面の中央にある白いボタンのsparklinesをマウスでクリックしたときの画面です

image.png

下記のURLではグラフが時間変化する動画が見られます。

  • Github URL
  • レイアウト
  • Widget
    • BarChart 棒グラフ (画像の右上)
    • Button ボタン (画像の中央4ボタンと右下の2ボタン)
    • Donut ドーナツグラフ (画像のBarChartの下)
    • Gauge ゲージ (画像の中央の緑の帯)
    • LineChart グラフ(画像の下、マウスによるズーム機能)
    • SegmentDisplay 未調査
    • Sparkline ミニグラフ (画像の中央)
    • Text  (画像の中央)
      • スクロール
        • マウスやキーボードでスクロールできます。
      • テキストの折り返し
      • はみ出し分を省略

各 OS上での実行

  • Windows 上記画像の通り問題なし
    • 日本語や中国語などを表示するときはchcp 65001でUTF-8にしないと画面が乱れる
  • Mac ほぼ問題はなかったが Sparklineに横筋が入っていた
  • Linux  (ubuntu 18.04)
    • Linux画面を直接操作することはないので以下のsshで試しました。
    • Mac ssh ではMac上と同じでした
    • Windows (おすすめはgit bashのssh)
      • git bash のssh
        • 一番良かった
        • ボタンも押せます 
        • sparklineの表示で塗りつぶされていない四角文字がでる(気にしなければ問題ない)
        • Scroll textでスクロールの特殊文字が表示されない
      • putty
        • グラフは出たが 枠の罫線が乱れている
        • ボタンが押せない
      • openssh
        • 時間変化させたグラフ等が乱れる。
        • ボタンが押せない
        • 一部枠の罫線が乱れる
      • WSL(ubuntu 18.04) のssh
        • LineChartが乱れる
        • Donutが乱れる
        • 中央の白いボタンが出ない
        • 右下のボタンは表示されて、クリックも出来る。

Scroll textが2つのログコンソール画面の実装

次のような画面です。左がFatalログで右がInformationログです。下記の画面は右側をクリックしたので枠の色が黄色?になっていますのでマウスの中ボタンやキーボードのカーソルキーで上下にスクロールできます。ログの文字が折り返されたら画面を横に広げればリサイズされます。 Fatalの時刻は赤にして、Informationはシアンにしました。

image.png

ソースコード

デモのソースを簡単に改造しただけです。Fatalかどうかは乱数によって決めました。実際はログファイルやデータベース、ネットワークから取得すると思います。

container.SplitVerticalを使って画面を縦に2分割しました。

main.go
package main

import (
    "context"
    "fmt"
    "math/rand"
    "time"

    "github.com/mum4k/termdash"
    "github.com/mum4k/termdash/cell"
    "github.com/mum4k/termdash/container"
    "github.com/mum4k/termdash/linestyle"
    "github.com/mum4k/termdash/terminal/termbox"
    "github.com/mum4k/termdash/terminal/terminalapi"
    "github.com/mum4k/termdash/widgets/text"
)

func writeLines(ctx context.Context, fatal, info *text.Text, delay time.Duration) {
    s := rand.NewSource(time.Now().Unix())
    r := rand.New(s)
    ticker := time.NewTicker(delay)
    defer ticker.Stop()
    fatalCount := 0
    infoCount := 0
    for {
        select {
        case <-ticker.C:
            var err error
            d := time.Now().Format("03:04:05")
            i := r.Intn(3)
            if i == 0 {
                fatal.Write(d, text.WriteCellOpts(cell.FgColor(cell.ColorRed)))
                if err == nil {
                    fatalCount++
                    log := fmt.Sprintf(" %d fatal fatal fatal\n", fatalCount)
                    err = fatal.Write(log)
                }
            } else {
                err = info.Write(d, text.WriteCellOpts(cell.FgColor(cell.ColorCyan)))
                if err == nil {
                    infoCount++
                    log := fmt.Sprintf(" %d information information information\n", infoCount)
                    err = info.Write(log)
                }
            }
            if err != nil {
                panic(err)
            }
        case <-ctx.Done():
            return
        }
    }
}

func main() {
    t, err := termbox.New()
    if err != nil {
        panic(err)
    }
    defer t.Close()

    ctx, cancel := context.WithCancel(context.Background())

    rolledFatal, err := text.New(text.RollContent(), text.WrapAtWords())
    if err != nil {
        panic(err)
    }
    rolledInfo, err := text.New(text.RollContent(), text.WrapAtWords())
    if err != nil {
        panic(err)
    }
    go writeLines(ctx, rolledFatal, rolledInfo, 1*time.Second)

    c, err := container.New(
        t,
        container.Border(linestyle.Light),
        container.BorderTitle("PRESS Q TO QUIT"),
        container.SplitVertical(
            container.Left(
                container.Border(linestyle.Light),
                container.BorderTitle("  Fatal ログ"),
                container.PlaceWidget(rolledFatal),
            ),
            container.Right(
                container.Border(linestyle.Light),
                container.BorderTitle("  Information ログ"),
                container.PlaceWidget(rolledInfo),
            ),
        ),
    )
    if err != nil {
        panic(err)
    }

    quitter := func(k *terminalapi.Keyboard) {
        if k.Key == 'q' || k.Key == 'Q' {
            cancel()
        }
    }

    if err := termdash.Run(ctx, t, c, termdash.KeyboardSubscriber(quitter)); err != nil {
        panic(err)
    }
}

まとめ

サーバー系のモニタ画面に使えるのではないかと思います。 まさかコンソールでマウスが使えるとは思いませんでした。
各Layout, Widgetの使い方をQIITAに載せて頂けると嬉しいです。
git bashのsshよりもっと最適なWindowsのSSHソフトが有ったら教えてほしいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GOの環境変数について

go envで環境変数を確認

vim ~/.bashrcでPATHを変更

重要なPATH:

GOROOT=$HOME/local/go   //goの位置
PATH=$PATH:$GOROOT/bin
export GOPATH=projectDir
export GOBIN=projectDir/din


プロジェクト中にには{pkg,src,bin}のような三つのフォルダーがあります。
*.go-------src
buided file--------bin

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語で開発したHTTPサーバーをGCP(GAE)へデプロイする

はじめに

GCP_GAE_Go.jpg
Go言語で開発したHTTPサーバー(HTTPによって通信を行うプログラム)を
GCPに作成したGAEへデプロイするまでの手順を記載します。

開発したHTTPサーバーは
Google Cloud SDKのローカルサーバーで動作確認を行った後、
GAEへデプロイして動作確認を行います。

おさらいしておきますと、GAE(Google APP Engine)とは、
開発したウェブアプリケーション(PHP・Python・Java・Go言語)を
Googleのインフラストラクチャー上で実行、バージョン管理するためのGCPサービスです。

開発環境

 ・OS:Windows7(64bit)
 ・クラウド:GCP(ナビゲーションメニュー > App Engineを作成済)
 ・Go:Go言語(1.12.0)
 ・JDK:Java SE(12.0.1)
 ・IDE:Eclipse(2019-03)
 ・Eclipseのプラグイン:GoClipse(0.16.1)
 ・Google Cloud SDK:Go用Cloud SDK(248.0.0)
  ⇒インストール時にAll Usersを選択し、インストール先は「C:\go_appengine_sdk」を指定

Go言語で簡単なHTTPサーバーを開発

JSONでレスポンスを返すシンプルなGoアプリ(HTTPサーバー)と、
Goアプリを構成するためのyamlファイルを開発してみます。

1.プロジェクトを作成
 Eclipseのメニューから ファイル > 新規 > Go プロジェクトを選択し、
 プロジェクト「GoStudy」を作成。

2.プロジェクト直下の「src」内に「main」フォルダを作成

3.「src\main」配下に以下「helloHttpServer.go」ファイルを作成

4.「src\main」配下に以下「app.yaml」ファイルを作成

5.Eclipseのメニューから プロジェクト > クリーン > 「GoStudy」を選択し、プロジェクトをクリーン

helloHttpServer.go
// このソースファイルは「main」パッケージに属すことを指定しています。
// また、Go言語のソースファイルは必ず「package」文で始まります。
package main

// 一つの import ステートメントで複数のパッケージをインポートしています。
import (

    // HTTPを扱うパッケージです。
    // HTTPクライアントとHTTPサーバーを実装するために必要な機能が提供されています。
    "net/http"

    // JSONを扱うパッケージです。
    // JSONのエンコードとデコードをを実装するために必要な機能が提供されています。
    "encoding/json"

    // GAEのAPIを扱うコンテキストのパッケージです。
    // 下記はGo1.6までのコンテキストでして、最近のGAEに使用されております。
    // ※Go1.7からのGo標準のコンテキストは「context.Context」ですが、現在GAEはGo1.6なので使えないです。
    "google.golang.org/appengine"
)

// レスポンスパラメータ用の構造体です。
//   ・JSON:XMLなどと同様のテキストベースのデータフォーマットです。
// typeで構造体の型(Response)を宣言しています。構造体型以外の型にも名前をつけることができます。
// structで構造体(名前と型を持つフィールドの集まり)を宣言しています。
type Response struct {

    // フィールド名 型     タグと呼ばれるメタデータ。「Status」ではなく「status」でjsonを整えてくれる。
    Status          string `json:"status"`
    Message         string `json:"message"`
}

// main関数は実行可能プログラムのエントリポイント
func main() {

    // 第一引数にURL、第二引数にハンドラを渡し、DefaultServeMuxに登録する。
    // つまり、「/test」というURLがリクエストされた際に、handlerが起動する。
    //   ・URL            :HTTPリクエストのパターン
    //   ・ハンドラ       :リクエストに対する応答
    //   ・DefaultServeMux:パターンにマッチしたリクエストに対して、そのパターンを持つhandlerを返却
    http.HandleFunc("/test", handle)

    // GAEでリクエストを受信するためのHTTPサーバーを起動します。
    appengine.Main()
}

// JSONでレスポンスを返す関数
func handle(w http.ResponseWriter, r *http.Request) {

    // NewEncoder関数:「w」に書き込みを行う、新しいEncoderを返却
    // Encode関数    :「Response」のJSONエンコーディングを接続「w」に書込
    // Response構造体:各フィールドへ値を代入
    json.NewEncoder(w).Encode(Response{Status: "ok", Message: "Hello world!"})
}

app.yaml
# YAMLのルールに従って記述された設定ファイルです。
# App EngineのGoアプリを構成するには、app.yamlファイルを使用します。(固有のファイル名を指定可能)

# Goランタイム環境を選択します。
runtime: go

# 使用するGoランタイム環境のバージョンです。
# go1はGoの最新リリース(現時点でGo1.9)のエイリアスです。
api_version: go1

# 必須要素。URL パターンと処理方法の説明のリストを定義します。
handlers:

# handlersで必要な要素。正規表現を使用したURLパターンを定義します。
# 先端の「- 」は、ハッシュのリストです。
# リストとするためにはハイフンを使い、さらにインデントを揃えてハッシュのキーを列挙します
- url: /test

# アプリケーションのルート ディレクトリを起点として、このスクリプトへのパスを指定します。
# Goアプリの場合、scriptには常に_go_appの値を含める必要があります。
  script: _go_app

- url: /
  script: _not_found

・実施結果
Eclipse_GoStudy.jpg

ローカルサーバーで動作確認

GAEへデプロイする前に、ローカルサーバーで動作確認をしてみます。

1.Windowsのコマンドプロンプトを起動

2.GAEのAPIを扱うパッケージを取得

コマンドプロンプト
go get google.golang.org/appengine

3.プロジェクトの「src\main」配下へ移動

コマンドプロンプト
cd C:[ワークスペースのフルパス]\src\main

4.ローカルサーバーを起動

コマンドプロンプト
C:\go_appengine_sdk\google-cloud-sdk\platform\bundledpython\python.exe C:\go_appengine_sdk\google-cloud-sdk\bin\dev_appserver.py app.yaml

 Google Cloud SDKのpython.exeでローカルサーバー(dev_appserver.py)を起動します。
 引数として与えるapp.yamlは、
 項目「Go言語でHTTPサーバーを作成」で作成したGoアプリを構成する設定ファイルです。

 ソースコード(helloHttpServer.go、app.yaml)を書き換えると、自動的にリビルドされます。

5.ブラウザからローカルサーバーへアクセス
http://localhost:8080/test

アクセス結果
{"status":"ok","message":"Hello world!"}

GAEへデプロイ

1.Windowsのコマンドプロンプトを起動

2.プロジェクトの「src\main」配下へ移動

コマンドプロンプト
cd C:[ワークスペースのフルパス]\src\main

3.デプロイコマンドを実行

コマンドプロンプト
gcloud app deploy --project [GCPのプロジェクトID]

4.ブラウザを起動

コマンドプロンプト
gcloud app browse --project [GCPのプロジェクトID]

5.ブラウザのURLへディレクトリ「/test」を追記

ブラウザのURL
- https://[プロジェクトID].appspot.com
+ https://[プロジェクトID].appspot.com/test
アクセス結果
{"status":"ok","message":"Hello world!"}

参考にしたサイト

Goスタンダード環境(Google公式)
net/httpパッケージ
encoding/jsonパッケージ
google.golang.org/appengineパッケージ
Googleの中の人が書いたソース

おわりに

デプロイがワンショットワンファイアで出来るなんて素晴らしいですね。

次回はGKEにデプロイするまでの手順を投稿したいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語で開発したWebアプリをGCP(GAE)へデプロイする

はじめに

Go言語で開発したWebアプリ(HTTPによって通信を行うプログラム)を
GCPに作成したGAEへデプロイするまでの手順を記載します。

開発したWebアプリは
Google Cloud SDKのローカルサーバーで動作確認を行った後、
GAEへデプロイして動作確認を行います。

おさらいしておきますと、GAE(Google APP Engine)とは、
開発したウェブアプリケーション(PHP・Python・Java・Go言語)を
Googleのインフラストラクチャー上で実行、バージョン管理するためのGCPサービスです。

開発環境

 ・OS:Windows7(64bit)
 ・クラウド:GCP(ナビゲーションメニュー > App Engineを作成済)
 ・Go:Go言語(1.12.0)
 ・JDK:Java SE(12.0.1)
 ・IDE:Eclipse(2019-03)
 ・Eclipseのプラグイン:GoClipse(0.16.1)
 ・Google Cloud SDK:Go用Cloud SDK(248.0.0)
  ⇒インストール時にAll Usersを選択し、インストール先は「C:\go_appengine_sdk」を指定

Go言語で簡単なWebアプリを開発

GCP_GAE_Go.jpg
JSONでレスポンスを返すシンプルなWebアプリと、
Webアプリを構成するためのyamlファイルを開発してみます。

1.プロジェクトを作成
 Eclipseのメニューから ファイル > 新規 > Go プロジェクトを選択し、
 プロジェクト「GoStudy」を作成。

2.プロジェクト直下の「src」内に「main」フォルダを作成

3.「src\main」配下に以下「helloHttpServer.go」ファイルを作成

4.「src\main」配下に以下「app.yaml」ファイルを作成

5.Eclipseのメニューから プロジェクト > クリーン > 「GoStudy」を選択し、プロジェクトをクリーン

helloHttpServer.go
// このソースファイルは「main」パッケージに属すことを指定しています。
// また、Go言語のソースファイルは必ず「package」文で始まります。
package main

// 一つの import ステートメントで複数のパッケージをインポートしています。
import (

    // HTTPを扱うパッケージです。
    // HTTPクライアントとHTTPサーバーを実装するために必要な機能が提供されています。
    "net/http"

    // JSONを扱うパッケージです。
    // JSONのエンコードとデコードをを実装するために必要な機能が提供されています。
    "encoding/json"

    // GAEのAPIを扱うコンテキストのパッケージです。
    // 下記はGo1.6までのコンテキストでして、最近のGAEに使用されております。
    // ※Go1.7からのGo標準のコンテキストは「context.Context」ですが、現在GAEはGo1.6なので使えないです。
    "google.golang.org/appengine"
)

// レスポンスパラメータ用の構造体です。
//   ・JSON:XMLなどと同様のテキストベースのデータフォーマットです。
// typeで構造体の型(Response)を宣言しています。構造体型以外の型にも名前をつけることができます。
// structで構造体(名前と型を持つフィールドの集まり)を宣言しています。
type Response struct {

    // フィールド名  型      タグと呼ばれるメタデータ。「Status」ではなく「status」でjsonを整えてくれる。
    Status          string `json:"status"`
    Message         string `json:"message"`
}

// main関数は実行可能プログラムのエントリポイント
func main() {

    // 第一引数にURL、第二引数にハンドラを渡し、DefaultServeMuxに登録する。
    // つまり、「/test」というURLがリクエストされた際に、handlerが起動する。
    //   ・URL            :HTTPリクエストのパターン
    //   ・ハンドラ        :リクエストに対する応答
    //   ・DefaultServeMux:パターンにマッチしたリクエストに対して、そのパターンを持つhandlerを返却
    http.HandleFunc("/test", handle)

    // GAEでリクエストを受信するためのHTTPサーバーを起動します。
    appengine.Main()
}

// JSONでレスポンスを返す関数
func handle(w http.ResponseWriter, r *http.Request) {

    // NewEncoder関数:「w」に書き込みを行う、新しいEncoderを返却
    // Encode関数    :「Response」のJSONエンコーディングを接続「w」に書込
    // Response構造体:各フィールドへ値を代入
    json.NewEncoder(w).Encode(Response{Status: "ok", Message: "Hello world!"})
}

app.yaml
# YAMLのルールに従って記述された設定ファイルです。
# App EngineのGoアプリを構成するには、app.yamlファイルを使用します。(固有のファイル名を指定可能)

# Goランタイム環境を選択します。
runtime: go

# 使用するGoランタイム環境のバージョンです。
# go1はGoの最新リリース(現時点でGo1.9)のエイリアスです。
api_version: go1

# 必須要素。URL パターンと処理方法の説明のリストを定義します。
handlers:

# handlersで必要な要素。正規表現を使用したURLパターンを定義します。
# 先端の「- 」は、ハッシュのリストです。
# リストとするためにはハイフンを使い、さらにインデントを揃えてハッシュのキーを列挙します
- url: /test

# アプリケーションのルート ディレクトリを起点として、このスクリプトへのパスを指定します。
# Goアプリの場合、scriptには常に_go_appの値を含める必要があります。
  script: _go_app

- url: /
  script: _not_found

・実施結果
Eclipse_GoStudy.jpg

ローカルサーバーで動作確認

GAEへデプロイする前に、ローカルサーバーで動作確認をしてみます。

1.Windowsのコマンドプロンプトを起動

2.GAEのAPIを扱うパッケージを取得

コマンドプロンプト
go get google.golang.org/appengine

3.プロジェクトの「src\main」配下へ移動

コマンドプロンプト
cd C:[ワークスペースのフルパス]\src\main

4.ローカルサーバーを起動

コマンドプロンプト
C:\go_appengine_sdk\google-cloud-sdk\platform\bundledpython\python.exe C:\go_appengine_sdk\google-cloud-sdk\bin\dev_appserver.py app.yaml

 Google Cloud SDKのpython.exeでローカルサーバー(dev_appserver.py)を起動します。
 引数として与えるapp.yamlは、
 項目「Go言語でHTTPサーバーを作成」で作成したGoアプリを構成する設定ファイルです。

 ソースコード(helloHttpServer.go、app.yaml)を書き換えると、自動的にリビルドされます。

5.ブラウザからローカルサーバーへアクセス
http://localhost:8080/test

アクセス結果
{"status":"ok","message":"Hello world!"}

GAEへデプロイ

1.Windowsのコマンドプロンプトを起動

2.プロジェクトの「src\main」配下へ移動

コマンドプロンプト
cd C:[ワークスペースのフルパス]\src\main

3.デプロイコマンドを実行

コマンドプロンプト
gcloud app deploy --project [GCPのプロジェクトID]

4.ブラウザを起動

コマンドプロンプト
gcloud app browse --project [GCPのプロジェクトID]

5.ブラウザのURLへディレクトリ「/test」を追記

ブラウザのURL
- https://[プロジェクトID].appspot.com
+ https://[プロジェクトID].appspot.com/test
アクセス結果
{"status":"ok","message":"Hello world!"}

参考にしたサイト

Goスタンダード環境(Google公式)
net/httpパッケージ
encoding/jsonパッケージ
google.golang.org/appengineパッケージ
Googleの中の人が書いたソース

おわりに

デプロイがワンショットワンファイアで出来るなんて素晴らしいですね。

次回はGKEにデプロイするまでの手順を投稿したいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語で書いたHTTPサーバーをGCP(GAE)へデプロイする

はじめに

GCP_GAE_Go.jpg
Go言語で開発したHTTPサーバー(HTTPによって通信を行うプログラム)を
GCPに作成したGAEへデプロイするまでの手順を記載します。

開発したHTTPサーバーは
Google Cloud SDKのローカルサーバーで動作確認を行った後、
GAEへデプロイして動作確認を行います。

おさらいしておきますと、GAE(Google APP Engine)とは、
開発したウェブアプリケーション(PHP・Python・Java・Go言語)を
Googleのインフラストラクチャー上で実行、バージョン管理するためのGCPサービスです。

開発環境

 ・OS:Windows7(64bit)
 ・クラウド:GCP(ナビゲーションメニュー > App Engineを作成済)
 ・Go:Go言語(1.12.0)
 ・JDK:Java SE(12.0.1)
 ・IDE:Eclipse(2019-03)
 ・Eclipseのプラグイン:GoClipse(0.16.1)
 ・Google Cloud SDK:Go用Cloud SDK(248.0.0)
  ⇒インストール時にAll Usersを選択し、インストール先は「C:\go_appengine_sdk」を指定

開発

JSONでレスポンスを返すシンプルなGoアプリ(HTTPサーバー)と、
Goアプリを構成するためのyamlファイルを開発してみます。
また、上記のソース(説明コメント付)も記載します。

HTTPサーバーとyamlファイルを開発

1.プロジェクトを作成
 Eclipseのメニューから ファイル > 新規 > Go プロジェクトを選択し、
 プロジェクト「GoStudy」を作成。

2.プロジェクト直下の「src」内に「main」フォルダを作成

3.「src\main」配下に以下「helloHttpServer.go」ファイルを作成

4.「src\main」配下に以下「app.yaml」ファイルを作成

5.Eclipseのメニューから プロジェクト > クリーン > 「GoStudy」を選択し、プロジェクトをクリーン

helloHttpServer.go
// このソースファイルは「main」パッケージに属すことを指定しています。
// また、Go言語のソースファイルは必ず「package」文で始まります。
package main

// 一つの import ステートメントで複数のパッケージをインポートしています。
import (

    // HTTPを扱うパッケージです。
    // HTTPクライアントとHTTPサーバーを実装するために必要な機能が提供されています。
    "net/http"

    // JSONを扱うパッケージです。
    // JSONのエンコードとデコードをを実装するために必要な機能が提供されています。
    "encoding/json"

    // GAEのAPIを扱うコンテキストのパッケージです。
    // 下記はGo1.6までのコンテキストでして、最近のGAEに使用されております。
    // ※Go1.7からのGo標準のコンテキストは「context.Context」ですが、現在GAEはGo1.6なので使えないです。
    "google.golang.org/appengine"
)

// レスポンスパラメータ用の構造体です。
//   ・JSON:XMLなどと同様のテキストベースのデータフォーマットです。
// typeで構造体の型(Response)を宣言しています。構造体型以外の型にも名前をつけることができます。
// structで構造体(名前と型を持つフィールドの集まり)を宣言しています。
type Response struct {

    // フィールド名 型     タグと呼ばれるメタデータ。「Status」ではなく「status」でjsonを整えてくれる。
    Status          string `json:"status"`
    Message         string `json:"message"`
}

// main関数は実行可能プログラムのエントリポイント
func main() {

    // 第一引数にURL、第二引数にハンドラを渡し、DefaultServeMuxに登録する。
    // つまり、「/test」というURLがリクエストされた際に、handlerが起動する。
    //   ・URL            :HTTPリクエストのパターン
    //   ・ハンドラ       :リクエストに対する応答
    //   ・DefaultServeMux:パターンにマッチしたリクエストに対して、そのパターンを持つhandlerを返却
    http.HandleFunc("/test", handle)

    // GAEでリクエストを受信するためのHTTPサーバーを起動します。
    appengine.Main()
}

// JSONでレスポンスを返す関数
func handle(w http.ResponseWriter, r *http.Request) {

    // NewEncoder関数:「w」に書き込みを行う、新しいEncoderを返却
    // Encode関数    :「Response」のJSONエンコーディングを接続「w」に書込
    // Response構造体:各フィールドへ値を代入
    json.NewEncoder(w).Encode(Response{Status: "ok", Message: "Hello world!"})
}

app.yaml
# YAMLのルールに従って記述された設定ファイルです。
# App EngineのGoアプリを構成するには、app.yamlファイルを使用します。(固有のファイル名を指定可能)

# Goランタイム環境を選択します。
runtime: go

# 使用するGoランタイム環境のバージョンです。
# go1はGoの最新リリース(現時点でGo1.9)のエイリアスです。
api_version: go1

# 必須要素。URL パターンと処理方法の説明のリストを定義します。
handlers:

# handlersで必要な要素。正規表現を使用したURLパターンを定義します。
# 先端の「- 」は、ハッシュのリストです。
# リストとするためにはハイフンを使い、さらにインデントを揃えてハッシュのキーを列挙します
- url: /test

# アプリケーションのルート ディレクトリを起点として、このスクリプトへのパスを指定します。
# Goアプリの場合、scriptには常に_go_appの値を含める必要があります。
  script: _go_app

- url: /
  script: _not_found

・実施結果
Eclipse_GoStudy.jpg

ローカルサーバーで動作確認

GAEへデプロイする前に、ローカルサーバーで動作確認をしてみます。

1.Windowsのコマンドプロンプトを起動

2.GAEのAPIを扱うパッケージを取得

コマンドプロンプト
go get google.golang.org/appengine

3.プロジェクトの「src\main」配下へ移動

コマンドプロンプト
cd C:[ワークスペースのフルパス]\src\main

4.ローカルサーバーを起動

コマンドプロンプト
C:\go_appengine_sdk\google-cloud-sdk\platform\bundledpython\python.exe C:\go_appengine_sdk\google-cloud-sdk\bin\dev_appserver.py app.yaml

 Google Cloud SDKのpython.exeでローカルサーバー(dev_appserver.py)を起動します。
 引数として与えるapp.yamlは、
 項目「Go言語でHTTPサーバーを作成」で作成したGoアプリを構成する設定ファイルです。

 ソースコード(helloHttpServer.go、app.yaml)を書き換えると、自動的にリビルドされます。

5.ブラウザからローカルサーバーへアクセス
http://localhost:8080/test

アクセス結果
{"status":"ok","message":"Hello world!"}

GAEへデプロイ

1.Windowsのコマンドプロンプトを起動

2.プロジェクトの「src\main」配下へ移動

コマンドプロンプト
cd C:[ワークスペースのフルパス]\src\main

3.デプロイコマンドを実行

コマンドプロンプト
gcloud app deploy --project [GCPのプロジェクトID]

4.ブラウザを起動

コマンドプロンプト
gcloud app browse --project [GCPのプロジェクトID]

5.ブラウザのURLへディレクトリ「/test」を追記

ブラウザのURL
- https://[プロジェクトID].appspot.com
+ https://[プロジェクトID].appspot.com/test
アクセス結果
{"status":"ok","message":"Hello world!"}

参考にしたサイト

Goスタンダード環境(Google公式)
net/httpパッケージ
encoding/jsonパッケージ
google.golang.org/appengineパッケージ
Googleの中の人が書いたソース

おわりに

デプロイがワンショットワンファイアで出来るなんて素晴らしいですね。

次回はGKEにデプロイするまでの手順を投稿したいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go入門①[Mac]VSCodeでGolangのハロワをしてみる~インストールからハロワまで~

golangを勉強し始めたので備忘録的にまとめてみる

Golangとは

特徴

  • コンパイル型言語
  • VMは無く、ネイティブコードを生成する
  • 実行環境が不要であり、オーバーヘッドが少なくて高速に動作する
  • クロスコンパイルができ、マルチプラットフォームで動作する
  • 並行処理が得意(ゴルーチン)

多言語と比較すると(かなりざっくり)

  • C言語に似ている

    • ポインタ型
    • 構造体
    • 基本型
    • でもGCはサポートされている
  • Java/C#

    • オブジェクト指向ではない
    • VM要らず
    • IDEなくても十分開発可能
  • JS/PHP/Ruby/Pythonなど

    • 型推論はあるが静的型付け言語
    • パフォーマンスが優れている(10倍以上)

インストール

  • Goのダウンロードページからダウンロード
    • Macの場合はbrewでインストールできる→ brew install go
  • インストーラでインストールする

パス追加(zshの場合)

echo 'export GOPATH=$HOME/go' >> ~/.zshrc
echo 'export GOBIN=$GOPATH/bin' >> ~/.zshrc
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc

GOPATHが使用するディレクトリ作成

mkdir -p $GOBIN/go

GOPATHとは

外部のライブラリが格納されているディレクトリの場所を認識するために必要な環境変数

→イマイチよくわからんけど必要らしいので設定しておく

Version確認してみる

> go version
go version go1.11.5 darwin/amd64

エディター

Visual Studio Codeを使用

VSCodeのインストール

https://code.visualstudio.com/ からダウンロードする

golang用の拡張機能をインストール

goで検索してインストール数が一番多いものを選択してインストールする

https://github.com/Microsoft/vscode-go

Extension__Go_—_go.png

必要なツールのインストール

拡張機能の説明欄に

You will see Analysis Tools Missing in the bottom right, clicking this will offer to install all of the dependent Go tools. You can also run the command Go: Install/Update tools to install/update the same.

とあり、Go: Install/Update tools を実行するにはコマンドパレットを開けと書いてある

Cmd+Shift+PCtrl+Shift+P でコマンドパレットをを開き、Go: Install/Update toolsを実行する

goInstallTools.png

どれをインストールするか聞いてくるので、全て選択し、OKを押す
goToolsList.png

Outputに以下のようにインストールされた旨が表示されればOK

InstalledTools.png

ハロワしてみる

新しくファイルを作成し、以下のように記載する

hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

go run hello.goで実行してみる(デバッグモードでrunしてもよい)
hello_go_—_go.png

さっきインストールしたlintも効いている模様
lint_go_—_go.png

無事ハロワできた!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VSCodeでGolangのハロワをしてみる~インストールからハロワまで~

golangを勉強し始めたので備忘録的にまとめてみる

Golangとは

特徴

  • コンパイル型言語
  • VMは無く、ネイティブコードを生成する
  • 実行環境が不要であり、オーバーヘッドが少なくて高速に動作する
  • クロスコンパイルができ、マルチプラットフォームで動作する
  • 並行処理が得意(ゴルーチン)

多言語と比較すると(かなりざっくり)

  • C言語に似ている

    • ポインタ型
    • 構造体
    • 基本型
    • でもGCはサポートされている
  • Java/C#

    • オブジェクト指向ではない
    • VM要らず
    • IDEなくても十分開発可能
  • JS/PHP/Ruby/Pythonなど

    • 型推論はあるが静的型付け言語
    • パフォーマンスが優れている(10倍以上)

インストール

  • Goのダウンロードページからダウンロード
    • Macの場合はbrewでインストールできる→ brew install go
  • インストーラでインストールする

パス追加(zshの場合)

echo 'export GOPATH=$HOME/go' >> ~/.zshrc
echo 'export GOBIN=$GOPATH/bin' >> ~/.zshrc
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc

GOPATHが使用するディレクトリ作成

mkdir -p $GOBIN/go

GOPATHとは

外部のライブラリが格納されているディレクトリの場所を認識するために必要な環境変数

→イマイチよくわからんけど必要らしいので設定しておく

Version確認してみる

> go version
go version go1.11.5 darwin/amd64

エディター

Visual Studio Codeを使用

VSCodeのインストール

https://code.visualstudio.com/ からダウンロードする

golang用の拡張機能をインストール

goで検索してインストール数が一番多いものを選択してインストールする

https://github.com/Microsoft/vscode-go

Extension__Go_—_go.png

必要なツールのインストール

拡張機能の説明欄に

You will see Analysis Tools Missing in the bottom right, clicking this will offer to install all of the dependent Go tools. You can also run the command Go: Install/Update tools to install/update the same.

とあり、Go: Install/Update tools を実行するにはコマンドパレットを開けと書いてある

Cmd+Shift+PCtrl+Shift+P でコマンドパレットをを開き、Go: Install/Update toolsを実行する

goInstallTools.png

どれをインストールするか聞いてくるので、全て選択し、OKを押す
goToolsList.png

Outputに以下のようにインストールされた旨が表示されればOK

InstalledTools.png

ハロワしてみる

新しくファイルを作成し、以下のように記載する

hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

go run hello.goで実行してみる(デバッグモードでrunしてもよい)
hello_go_—_go.png

さっきインストールしたlintも効いている模様
lint_go_—_go.png

無事ハロワできた!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Mac]VSCodeでGolangのハロワをしてみる~インストールからハロワまで~

golangを勉強し始めたので備忘録的にまとめてみる

Golangとは

特徴

  • コンパイル型言語
  • VMは無く、ネイティブコードを生成する
  • 実行環境が不要であり、オーバーヘッドが少なくて高速に動作する
  • クロスコンパイルができ、マルチプラットフォームで動作する
  • 並行処理が得意(ゴルーチン)

多言語と比較すると(かなりざっくり)

  • C言語に似ている

    • ポインタ型
    • 構造体
    • 基本型
    • でもGCはサポートされている
  • Java/C#

    • オブジェクト指向ではない
    • VM要らず
    • IDEなくても十分開発可能
  • JS/PHP/Ruby/Pythonなど

    • 型推論はあるが静的型付け言語
    • パフォーマンスが優れている(10倍以上)

インストール

  • Goのダウンロードページからダウンロード
    • Macの場合はbrewでインストールできる→ brew install go
  • インストーラでインストールする

パス追加(zshの場合)

echo 'export GOPATH=$HOME/go' >> ~/.zshrc
echo 'export GOBIN=$GOPATH/bin' >> ~/.zshrc
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc

GOPATHが使用するディレクトリ作成

mkdir -p $GOBIN/go

GOPATHとは

外部のライブラリが格納されているディレクトリの場所を認識するために必要な環境変数

→イマイチよくわからんけど必要らしいので設定しておく

Version確認してみる

> go version
go version go1.11.5 darwin/amd64

エディター

Visual Studio Codeを使用

VSCodeのインストール

https://code.visualstudio.com/ からダウンロードする

golang用の拡張機能をインストール

goで検索してインストール数が一番多いものを選択してインストールする

https://github.com/Microsoft/vscode-go

Extension__Go_—_go.png

必要なツールのインストール

拡張機能の説明欄に

You will see Analysis Tools Missing in the bottom right, clicking this will offer to install all of the dependent Go tools. You can also run the command Go: Install/Update tools to install/update the same.

とあり、Go: Install/Update tools を実行するにはコマンドパレットを開けと書いてある

Cmd+Shift+PCtrl+Shift+P でコマンドパレットをを開き、Go: Install/Update toolsを実行する

goInstallTools.png

どれをインストールするか聞いてくるので、全て選択し、OKを押す
goToolsList.png

Outputに以下のようにインストールされた旨が表示されればOK

InstalledTools.png

ハロワしてみる

新しくファイルを作成し、以下のように記載する

hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

go run hello.goで実行してみる(デバッグモードでrunしてもよい)
hello_go_—_go.png

さっきインストールしたlintも効いている模様
lint_go_—_go.png

無事ハロワできた!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

振り出しに戻ろう

一度立ち戻ったほうがいい気がしてきた

  • API`を実行するファイルを編集しテストするも当たり前だけどダメ
  • ただ闇雲にやっても意味がないような気がしてきた。ここ最近全然前に進んでいないような気がするし
  • 明日からのタスクを整理

 1.改めて買ったGOの本を読み、基本を勉強する
 2.修正、変更を機会に覚えさせ管理したいので、ローカルリポジトリの内容をリモートリポジトリへプッシュさせ、統合管理させる

今日の気持ち

  • タイトル付けが段々と面倒になってきた。単純に日付でもいいが内容が分からなくなってくるし、かと言って無記名は仕様上出来ないし。参った、そしてメンドくさい
  • duet display接続のiPadとはいえ、デュアルディスプレイは上下配置のスタイルがいいらしい
  • 明日もまた挑戦だ!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む