tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【go】direnvで環境(プロジェクトやディレクトリ)ごとに環境変数を分けるメモ - 例:GOPATH

はじめ

golangに限らないですが、
環境ごとに環境変数を切り替えたいときはまぁまぁありますよね。
そんなときのdirenvメモです。

mac x golangな環境を前提に書きますが
direnv自体はlinuxでも他の言語や環境でも同じです。

アジェンダ

  1. direnvとは
  2. direnvのinstall&設定
  3. direnv使ってみる
  4. direnv: error .envrc is blocked. Run direnv allow to approve its content.なとき

1. direnvとは

まずはdirenvのリポジトリ
https://github.com/direnv/direnv

簡単にいうとプロジェクトやディレクトリごとに環境変数を勝手に切り替えてくれる君です。
公式から引用するとこんな感じ。

direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh and fish shell to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the “~/.profile” file.

使うとこんな事が可能になります。

* ディレクトリごとにGPATHを設定できる
* ディレクトリへ移動すると自動的に設定される(出ると勝手に解除)

2. direnvのinstall&設定

使う前のinstall&設定。簡単です

# install
$ brew update
$ brew install direnv

# shellに設定
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc

3. direnv使ってみる

設定してみる

ここでは環境(ディレクトリ)ごとにGOPATHを切り替える という例で書きますが、他の環境変数でも同じです。

# 移動
$ cd path/to/設定したいディレクトリ

# .envrcを作成
$ direnv edit .
---- vi追記 ----
export GOPATH=$(pwd) 
--------------- 

使い方

# direnvを設定したdir以外にいる前提
$ pwd
path/to/direnv設定してないdir

# 移動
$ cd path/to/設定したdir
direnv: loading .envrc
direnv: export ~GOPATH

# 出てみる
$ cd ..
direnv: unloading

補足

direnv edit .でエラー

direnv edit .するとdirenv: $EDITOR not found なエラーができるときは$EDITORを設定してやります

# 怒られる
$ direnv edit .
direnv: $EDITOR not found.

# bashrcに設定&読み込み
$ echo 'export EDITOR=vim' >> ~/.bashrc
$ source ~/.bashrc

# vimが開けばok
$ direnv edit .

4. direnv: error .envrc is blocked. Run direnv allow to approve its content.なとき

.envrcを直接編集すると以下のようなエラーが出るときがあります。
編集後は安全のためにdirenv allowで明示的に読み込むまでは無効になっているよ、という事らしいです。

# 何かしたらこれがでる
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.

# 素直に打つ
$ direnv allow

参考

終わり

いまさら direnv の解説という記事を参考にさせてもらって
さらに今さら感がありますが自分用メモ>\(^o^)/

【Homebrew】brew updateとbrew upgradeどっちがどっちメモ

はじめに

いつも忘れるのでメモ

違い

参考サイトのまんまですが違いをメモ。

update

Homebrew自体を最新版にして,内部で管理しているformula(パッケージ)も最新版にする

upgrade

Homebrew内部で管理しているformulaのみを最新版にする

参考

もうちょっと詳しく書いてあるので気になる場合は参考サイトをどぞ http://glass5er.hatenablog.com/entry/20121208/1354983531

【go】golangでyamlを読み込んでstructに入れるメモ - gopkg.in/yaml.v2

はじめに

golangyamlを読み込むときのメモ

読み込みたいyaml

userのデータが入ってると仮定したyamlです

sample.yaml
users:
    -   
        name: ほげ ほげ男
        full_name:
            first_name: ほげ
            last_name: ほげ男
        sex: male
        birthday: 1990-12-12
        self_introduction:
            long: ほげほげ男です。よろしくおねがいします!
            short: しゃす!
        image_urls:
            - /my/photo/01.png
            - /my/photo/02.png
            - /my/photo/03.png
        shemale: false
    -   
        name: ふが ふが子
        full_name:
            first_name: ふが
            last_name: ふが子
        sex: female
        birthday: 1994-03-03
        self_introduction:
            long: ふが子です!(≧∀≦*)
        image_urls:
            - /my/photo/01.png
        shemale: true

使うパッケージ

gopkg.in/yaml.v2 というパッケージを使います。

go getで取得すればいけるはず

$ go get gopkg.in/yaml.v2

今回はglideで入れました

構成

sample.yaml が読み込みたいyamlです。
glideな関係でmainのコードはsrc/go-yaml-sample/yaml_sample.goとなってます。

$ pwd
プロジェクトdir

$ tree -L 3
.
├── sample.yaml
└── src
    └── yaml_sample
        ├── glide.lock
        ├── glide.yaml
        ├── vendor
        └── yaml_sample.go

コード

gopkg.in/yaml.v2 を使うと、json.Marshalな感じでyamlを読み込んでくれます。

src/go-yaml-sample/yaml_sample.go
package main

import (
  "fmt"
  "io/ioutil"

  yaml "gopkg.in/yaml.v2"
)

// structたち
type Data struct {
  Users []User `yaml:"users"`
}

type User struct {
  Name             string           `yaml:"common"`
  FullName         fullName         `yaml:"full_name"`
  Sex              string           `yaml:"sex"`
  SelfIntroduction selfIntroduction `yaml:"self_introduction"`
  ImageURLs        []string         `yaml:"image_urls"`
  Shemale          bool             `yaml:"shemale"`
}

type fullName struct {
  FirstName string `yaml:"first_name"`
  LastName  string `yaml:"last_name"`
}

type selfIntroduction struct {
  Long  string `yaml:"long"`
  Short string `yaml:"short"`
}

func main() {
  // yamlを読み込む
  buf, err := ioutil.ReadFile("../../sample.yaml")
  if err != nil {
    panic(err)
  }
  fmt.Printf("buf: %+v\n", string(buf))

  // structにUnmasrshal
  var d Data
  err = yaml.Unmarshal(buf, &d)
  if err != nil {
    panic(err)
  }
  fmt.Printf("d: %+v", d)

}
結果
$ cd src/yaml_sample/

$ go run yaml_sample.go 
buf: users:
    -
        name: ほげ ほげ男
        full_name:
            first_name: ほげ
            last_name: ほげ男
        sex: male
        birthday: 1990-12-12
        self_introduction:
            long: ほげほげ男です。よろしくおねがいします!
            short: しゃす!
        image_urls:
            - /my/photo/01.png
            - /my/photo/02.png
            - /my/photo/03.png
        shemale: false
    -
        name: ふが ふが子
        full_name:
            first_name: ふが
            last_name: ふが子
        sex: female
        birthday: 1994-03-03
        self_introduction:
            long: ふが子です!(≧∀≦*)
        image_urls:
            - /my/photo/01.png
        shemale: true


d: {Users:[{Name: FullName:{FirstName:ほげ LastName:ほげ男} Sex:male SelfIntroduction:{Long:ほげほげ男です。よろしくおねがいします! Short:しゃす!} ImageURLs:[/my/photo/01.png /my/photo/02.png /my/photo/03.png] Shemale:false} {Name: FullName:{FirstName:ふが LastName:ふが子} Sex:female SelfIntroduction:{Long:ふが子です!(≧∀≦*) Short:} ImageURLs:[/my/photo/01.png] Shemale:true}]}

リポジトリ

おわり

yamlもサクっと簡単!\(^o^)/

【git】git tagを取り消す

はじめに

git tagを取り消すメモ。 ほとんど手順メモ程度な感じ+他記事で使うスニペット記事。

補足

他の取り消しもぱっと見たい自分用にまとめたので参考までに。

【git】add、commit、push、merge、pull request、merge pull request、tagの取り消し

アジェンダ

  1. localでの取り消し(削除)
  2. リモートでの取り消し

1. localでの取り消し(削除)

ローカルで消す場合は git tag -d タグ とします。

$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.4
v1.0.5

$ git tag v1.0.6

$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.4
v1.0.5
v1.0.6

$ git tag -d v1.0.6
Deleted tag 'v1.0.6' (was 7bd2f6b)

$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.4
v1.0.5safdsa

2. リモートでの取り消し

リモートのtagを消す場合は git push origin :refs/tags/タグ とします。
ローカルを先に消す必要も無いし、localのが一緒に消えるわけでもないです。

# リモートのタグを確認
$ git ls-remote --tags
From https://github.com/tweeeety/git-tag-sample.git
6d0a343aa89b63f6d01116116afcca30c7250ed1  refs/tags/v1.0.0
08c9f32c3f36a7577366440f24b095a697c8645d  refs/tags/v1.0.1
0715d6e897c84b003ee3f1d9833bfe23d0023355  refs/tags/v1.0.2
063adbe5ed48fc19dbea5d92491995e09ad762f2  refs/tags/v1.0.4
33ed691e1c4363b4b5cf7f102fab3ca27f5ba5ab  refs/tags/v1.0.5
7bd2f6b05c73cc1042d0b9b8b311e96d3375b13f  refs/tags/v1.0.6

# リモートのタグを削除
$ git push origin :refs/tags/v1.0.6
To https://github.com/tweeeety/git-tag-sample.git
 - [deleted]         v1.0.6

# 消えてるか確認
$ git ls-remote --tags
From https://github.com/tweeeety/git-tag-sample.git
6d0a343aa89b63f6d01116116afcca30c7250ed1  refs/tags/v1.0.0
08c9f32c3f36a7577366440f24b095a697c8645d  refs/tags/v1.0.1
0715d6e897c84b003ee3f1d9833bfe23d0023355  refs/tags/v1.0.2
063adbe5ed48fc19dbea5d92491995e09ad762f2  refs/tags/v1.0.4
33ed691e1c4363b4b5cf7f102fab3ca27f5ba5ab  refs/tags/v1.0.5

# ローカルには残ってるので別途消してね
$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.4
v1.0.5
v1.0.6

終わり

git ls-remote --tags のほうを忘れそうw

【git】git tagの使い方をかんたんにおさらい

はじめに

リリース管理やブランチ管理にはまぁまぁ利用するgit tagですがおさらいがてらにメモ

アジェンダ

  1. git tagとは
  2. よく使うgit tagコマンド
  3. tagの作成
  4. tagの一覧
  5. tagの確認
  6. tagの削除
  7. tagのpush
  8. リモートのタグの一覧
  9. リモートのタグの削除

1. git tagとは

タグとは、コミットを参照しやすくするために、わかりやすい名前を付けるものです。

Gitでは、軽量タグと、注釈付きタグの2種類のタグが使用できます。また、一度付けたタグはブランチのように位置が移動することはなく固定です。

説明下手なので参考サイトから引用させていただきました。 * http://www.backlog.jp/git-guide/stepup/stepup4_1.html

2. よく使うgit tagコマンド

あんちょこ的に先にまとめておきます。
コマンドベースでざっとできる事を羅列

# tagの作成
$ git tag タグ
$ git tag -a タグ -m "こめんと"

# tagの一覧
$ git tag

# リモートのタグの一覧
$ git ls-remote --tags

# tagの確認
$ git show タグ

# tagの削除
$ git tag -d タグ

# tagのpush
$ git tag push タグ
$ git push --tags

3. tagの作成

軽量タグの作成

コマンド

git tag タグ

$ git tag v1.0.0

注釈付きタグの作成

コマンド

git tag -a タグ -m ‘コメント’

$ git tag -a v1.0.0 -m 'add readme'

タグをあとからつける

コマンド

git tag -a タグ -m ‘コメント’ コミットハッシュ

$ git tag -a v1.0.0 -m "add readme" 6d0a343aa89b63f6d01116116afcca30c7250ed1

4. tagの一覧

コマンド

git tag

$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.3

5. tagの確認

コマンド

git show タグ

$ git show v1.0.0
tag v1.0.0
Tagger: tweeeety <tweeeety.0719@gmail.com>
Date:   Mon May 8 23:09:11 2017 +0900

add readme

commit 6d0a343aa89b63f6d01116116afcca30c7250ed1
Author: tweeeety <tweeeety.0719@gmail.com>
Date:   Wed Apr 19 21:58:44 2017 +0900

    first commit

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..71d9d7a
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# git-tag-sample

6. tagの削除

コマンド

git tag -d タグ

$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.3

$ git tag -d v1.0.3
Deleted tag 'v1.0.3' (was 8bfcc5a)

$ git tag
v1.0.0
v1.0.1
v1.0.2

7. tagのpush

個別にpush

コマンド

git push origin タグ

$ git push origin v1.0.2
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 525 bytes | 0 bytes/s, done.
Total 6 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/tweeeety/git-tag-sample.git
 * [new tag]         v1.0.2 -> v1.0.2
補足

タグv1.0.2は一番最後のcommit(8bfcc5aa8eab54d20b46864595de4e8b992c4479)に対してつけたもの。 最初のcommitから最後までpushを一度もしてないままに、
git push origin v1.0.2 とする事もできる。

$ git log
commit 8bfcc5aa8eab54d20b46864595de4e8b992c4479
Author: tweeeety <tweeeety.0719@gmail.com>
Date:   Mon May 8 23:11:22 2017 +0900

    modify third

commit 0715d6e897c84b003ee3f1d9833bfe23d0023355
Author: tweeeety <tweeeety.0719@gmail.com>
Date:   Mon May 8 23:10:42 2017 +0900

    modify second

commit 08c9f32c3f36a7577366440f24b095a697c8645d
Author: tweeeety <tweeeety.0719@gmail.com>
Date:   Mon May 8 23:07:55 2017 +0900

    modify first

commit 6d0a343aa89b63f6d01116116afcca30c7250ed1
Author: tweeeety <tweeeety.0719@gmail.com>
Date:   Wed Apr 19 21:58:44 2017 +0900

    first commit

まとめてpush

それまでpushされてないlocalで作成済みのtagがまとめてpushされます

コマンド

git push –tags

$ git push --tags
Counting objects: 12, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 509 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To https://github.com/tweeeety/git-tag-sample.git
 * [new tag]         v1.0.2 -> v1.0.2
 * [new tag]         v1.0.4 -> v1.0.4
 * [new tag]         v1.0.5 -> v1.0.5

8. リモートのタグの一覧

commitとの紐付けも見れて便利

コマンド

git ls-remote –tags

$ git ls-remote --tags
From https://github.com/tweeeety/git-tag-sample.git
6d0a343aa89b63f6d01116116afcca30c7250ed1  refs/tags/v1.0.0
08c9f32c3f36a7577366440f24b095a697c8645d  refs/tags/v1.0.1
0715d6e897c84b003ee3f1d9833bfe23d0023355  refs/tags/v1.0.2
063adbe5ed48fc19dbea5d92491995e09ad762f2  refs/tags/v1.0.4
33ed691e1c4363b4b5cf7f102fab3ca27f5ba5ab  refs/tags/v1.0.5

9. リモートのタグの削除

コマンド

git push origin :refs/tags/タグ

# リモートのタグを確認
$ git ls-remote --tags
From https://github.com/tweeeety/git-tag-sample.git
6d0a343aa89b63f6d01116116afcca30c7250ed1  refs/tags/v1.0.0
08c9f32c3f36a7577366440f24b095a697c8645d  refs/tags/v1.0.1
0715d6e897c84b003ee3f1d9833bfe23d0023355  refs/tags/v1.0.2
063adbe5ed48fc19dbea5d92491995e09ad762f2  refs/tags/v1.0.4
33ed691e1c4363b4b5cf7f102fab3ca27f5ba5ab  refs/tags/v1.0.5
7bd2f6b05c73cc1042d0b9b8b311e96d3375b13f  refs/tags/v1.0.6

# リモートのタグを削除
$ git push origin :refs/tags/v1.0.6
To https://github.com/tweeeety/git-tag-sample.git
 - [deleted]         v1.0.6

# 消えてるか確認
$ git ls-remote --tags
From https://github.com/tweeeety/git-tag-sample.git
6d0a343aa89b63f6d01116116afcca30c7250ed1  refs/tags/v1.0.0
08c9f32c3f36a7577366440f24b095a697c8645d  refs/tags/v1.0.1
0715d6e897c84b003ee3f1d9833bfe23d0023355  refs/tags/v1.0.2
063adbe5ed48fc19dbea5d92491995e09ad762f2  refs/tags/v1.0.4
33ed691e1c4363b4b5cf7f102fab3ca27f5ba5ab  refs/tags/v1.0.5

# ローカルには残ってるので別途消してね
$ git tag
v1.0.0
v1.0.1
v1.0.2
v1.0.4
v1.0.5
v1.0.6

リポジトリ

https://github.com/tweeeety/git-tag-sample

終わり

おさらいというかあんちょこ的になったけど、それはそれで良し\(^o^)/

【git】最初のgit commitを取り消す - `git update-ref -d HEAD`もしくは`git filter-branch`

はじめに

以前、【git】git commitを取り消すという記事を書きました。

git reset xxxで普段のcommitの取り消しは問題なくできますが、
そのリポジトリで1発目のcommitの取り消しができません。

たとえばこんな時ありますよね。
「あ、間違ってauthor違う名前でcommitしちゃった。取り消して設定しなおそ」
みたいな。

そんな時のメモ

補足

他の取り消しもぱっと見たい自分用にまとめたので参考までに。

内容

  1. git reset xxxでcommit取り消しできない例
  2. git update-ref -d HEAD でcommit取り消しできる例
  3. git update-ref -d HEAD でcommit取り消したがgithub上は違う方法で変えなきゃな例

1. git reset xxxでcommit取り消しできない例

リポジトリを作成し、1発目にcommitしたものを取り消します。

# log確認。当然1つしかない
$ git log
commit 5646f5ca182c74329094f89c888d80f6b3de92fa
Author: hogehoge <hogehoge>
Date:   Fri Apr 14 22:32:41 2017 +0900

    first commit

# reset --soft HEAD^で1つ前を取り消そうと思ったけどできない
$ git reset --soft HEAD^
fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

2. git update-ref -d HEAD でcommit取り消しできる例

章題に書いてますが、git update-ref -d HEAD でできます。

# log確認。当然1つしかない
$ git log
commit 5646f5ca182c74329094f89c888d80f6b3de92fa
Author: hogehoge <hogehoge>
Date:   Fri Apr 14 22:32:41 2017 +0900

    first commit

# 
$ git update-ref -d HEAD

# 無事リセットされてる
$ git log
git log
fatal: bad default revision 'HEAD'

git update-ref についてはあまり調べてませんが、参照を更新するコマンドらしいです。

3. git update-ref -d HEAD でcommit取り消したがgithub上は違う方法で変えなきゃな例

2の項目で一見落着な感じでしたが、
これはlocalで行った操作が git add / git commit のみの場合です。

git push してgithub上にpushしてしまった場合は、以下の方法で変える必要があります。
※ ここは以前書いたのではしょりました

おわり

慣れてるつもりでもあんまりやらない操作だと
わからない事はまだまだ多いですね\(^o^)/

【go】golangはmapは宣言だけだと `panic: assignment to entry in nil map` に...なることがあるよのメモ

はじめに

かなり初歩的ですがpanic: assignment to entry in nil map で小一時間悩んだので自分戒めメモ。
わかってるつもりが、mapの宣言と初期化を混同していましたというお恥ずかしいアレです...

panic: assignment to entry in nil map が起こった例

  • mapを宣言して
  • funcで取得した値を入れて
  • その後にdefaultでkey:valueを追加しておきたい

みたいな時にpanic: assignment to entry in nil map がでてぱっと原因がわからなくて悩みました。

あとで単純かしたpanicも載せますが、よく考えれば当たり前とはいえロジック中だと最初ほんとにわからなかった...

sample.go

package main

import "log"

func main() {
  // 宣言
  var m map[string]string
  
  // 条件に応じて取得
  // trueの時は問題無し
  // falseだと....
  if condition := false; condition {
    m = getMap()
  }

  // mapにdefaultでkey:valueを追加
  //   -> ここで `panic: assignment to entry in nil map` 
  addMapValue(&m)

  // 出力
  log.Printf("m: %+v", m)
}

// mapを取得する
func getMap() map[string]string {
  return map[string]string{"hoge": "fuga"}
}

// mapに追加する
func addMapValue(m *map[string]string) {
  // 何か処理をして

  // からの追加
  key := "piyo"
  value := "magu"
  (*m)[key] = value
}

実行結果

  • condition := true の場合
$ go run sample.go 
2017/04/11 00:38:48 m: map[hoge:fuga piyo:magu]
  • condition := false の場合
$ go run sample.go 
panic: assignment to entry in nil map

goroutine 1 [running]:
panic(0xbab40, 0x8201ce290)
  /usr/local/Cellar/go/1.6.2/libexec/src/runtime/panic.go:481 +0x3e6
main.main()
  /Users/hoge/sample/sample.go:26 +0x162
exit status 2

原因

  • 初期化前のmapはnil
  • nilのmapに要素を割り当てられない

参考サイト Go言語:Map

要は宣言だけのmap(やsliceなどのポインタ系)はゼロ値がnilのためという事ですね。

panic: assignment to entry in nil map の単純な例

かなり単純化して書くとわかりやすいです。

func main() {
  // 宣言
  var m map[string]string

  // key:valueをsetのつもり
  // -> この時点で `panic: assignment to entry in nil map`
  m["hoge"] = "fuga"

  // 出力
  log.Printf("m: %+v", m)
}

最初から素直にこうしろって感じですね。。。

func main() {
  // 初期化
  m := map[string]string{"hoge": "fuga"}

  // 出力
  log.Printf("m: %+v", m)
}

終わり

goさわりはじめたとはいえだいぶ慣れたよな〜と思ってたころでしたが、
まだまだやん...と思いました、というメモ\(^o^)/