Jenkinsでgo言語のプロジェクトをCIする方法を調査した
はじめに
Golangをちまちまプライベートで触っていて、バックエンドサーバを試しにgolangで書いてみてるんだけど、Jenkinsのpipelineでgoを扱う方法が、調査しても断片的にしか出てこなかったので、本腰を入れて調査してみた。
pipelineでなければ、もっと簡単そうだけど、BlueOceanも1.0リリースされたしね。
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太,稲葉貴洋
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: 大型本
- この商品を含むブログ (3件) を見る
対象
ソースコードはこちら
単なる足し算を実装しただけの簡易なもの。
しかも明らかにミスってる(もちろんわざと)
func Sum(a int, b int) int { return a + a }
これをJenkinsでTestしてみる。
事前準備
プラグインの導入、初期設定
Go pluginを導入しておく
Go Plugin - Jenkins - Jenkins Wiki
次にプラグインの設定をする。
日本語メニューの場合、「Jenkinsの設定」→「Global Tool Configuration」にGoの設定があるはず。(http://JenkinsのURL/configureTools/ にアクセスしてもよい)
インストール済Goというのに適当な名前(ここではGo1.8とした)をつけて、必要なGoのバージョンを設定しておく。これは必須ではないが、これをやっておくと、Jenkins専用のGoを設定しておくことができる。CentOSのepelリポジトリが1.6までしかなくて、depが使えなかったので、このやりかたで導入した。
Jenkinsfileを書く
pipelineは、Jenkins上で書くこともできるけど、ファイルとして切り出して管理することもできる。バージョン管理もできるし、そちらの方が推されてるはず。
というわけで、Jenkinsfileをごりごり書いた。
書いてみたのがこんな
node { def root = tool name: 'Go1.8', type: 'go' ws("${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}/src/github.com/grugrut/golang-ci-jenkins-pipeline") { withEnv(["GOROOT=${root}", "GOPATH=${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}/", "PATH+GO=${root}/bin"]) { env.PATH="${GOPATH}/bin:$PATH" stage 'Checkout' git url: 'https://github.com/grugrut/golang-ci-jenkins-pipeline.git' stage 'preTest' sh 'go version' sh 'go get -u github.com/golang/dep/...' sh 'dep init' stage 'Test' sh 'go vet' sh 'go test -cover' stage 'Build' sh 'go build .' stage 'Deploy' // Do nothing. } } }
重要(というか自分が詰まった)なのが前半部分。
def root = tool name: 'Go1.8', type: 'go'
必要なバージョンのGoを利用するための設定がこちら。
nameのところに先程のプラグイン設定で名付けたものを入れる。
はじめに利用するときに、goが自動でダウンロードされるので、始めの一回はそこそこ時間がかかるけど、次からはすぐに使える。ちなみに、このGoのインストール先は、${JENKINS_HOME}/tools/org.jenkinsci.plugins.golang.GolangInstallation/Go1.8/
となっているようだ(最後のGo1.8は自分がつけた名前)。
ws("${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}/src/github.com/grugrut/golang-ci-jenkins-pipeline") { withEnv(["GOROOT=${root}", "GOPATH=${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}/", "PATH+GO=${root}/bin"]) { env.PATH="${GOPATH}/bin:$PATH"
Goに入ってはGoに従えの格言の通り、Golangらしいファイル配置になるように設定している。
1行目のwsは、カレントディレクトリを設定している。普通は${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}/が、カレントディレクトリになるところを、src配下に配置するようにしている。詳細は以下のページで。
Goコードの書き方 - The Go Programming Language
次に2行目は、GOROOTとGOPATHの二つの環境変数を設定している。PATH+GOで、goのバイナリの箇所を設定しているらしいけど、詳しいドキュメントが見付からず、ここは見様見真似でやってる。
GOPATH配下のbinもPATHに含めたかったのだけど、withEnvでやろうとすると、(おそらく)Jenkinsとしての変数展開と、shellの変数展開が競合してうまくいかなかったので、3行目に別途いれてる。
あとは、ソースコードの通り、チェックアウトして、depをインストールした上で、依存関係を解決、その後go vet, go testと来て、とおればbuildしておしまい。(とはいえtestでこけるのでbuildまで行かないのだけど)
結果
こんな感じで、testにこけてることが確認できた。
なんとなく動いてる気はするけど、もっと効率の良いやりかたがありそうなので、ご存知の方いたら教えてください!!
書籍の情報を検索して挿入するためのHelmインタフェースを作ってみた
やりたかったこと
org-modeで本の記録を取るのに、いちいち著者情報を手入力するのがきつすぎるので、検索していいかんじにバッファに挿入させたかった。
で、それを実現するのにHelmインタフェースで作るのが、それっぽいかんじで良さそうだったので、そうした。
HelmインタフェースもAnythingインタフェースも作ったことなかったので、やってみたかったというのもある
できたもの
使いかた
requireして、M-x helm-booksするといつものHelmインタフェースが表示される。
そして入力すると入力した文言に対してgoogle books apiに対してクエリが発行されて結果がリストとして表示される。
Actionとしては、挿入する文章を変数"helm-books-custom-format"で設定することができる。
org-modeとの統合
org-captureでは、テンプレートに
(setq org-capture-templates '(("b" "book memo" entry (file (concat org-directory "book.org")) "* %(helm-books)" ))))
のように、%(sexp)とすることで、S式を埋め込むことができる。
これを利用することで、このテンプレートを呼び出すと、自動でhelm-booksが呼ばれ、本を検索し、必要な情報をプロパティとして設定したメモを簡単に取ることができる。
これはすごい
今後
- 作者: るびきち
- 出版社/メーカー: 技術評論社
- 発売日: 2011/11/26
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 220回
- この商品を含むブログを見る
本の情報を取得するためのHelm拡張を作ってみた(途中)
続きを書いた
grugrut.hatenablog.jp
init.el読書会で、org-modeのメモを読書記録にするための、org-captureのテンプレートがあって、やりたかったのだけど、いちいち本の情報をプロパティに手打ちするのは面倒だと思った。
例
* ゼロから作るDeep Learning :PROPERTIES: :Author: 斎藤 康毅 :Year: 2016 :Publisher: オライリー :END:
なんか皆やってそうなので、こういう情報を簡単に挿入できるような良いパッケージが無いか探してみたのだけど、みつけられなかったので、Helm拡張として作ってみることにした。
作るにあたっては、
helm拡張を書く - Qiita
Developing · emacs-helm/helm Wiki · GitHub
を超参考にした。
Helm拡張書いてみての感想
まだsourceの定義の一部しか終わってないけど、はじめとっつきにくい印象(公式documentもそこまで充実してないし)だったけど、ちょっとずつ書いてみたら、意外とあっさり書けた。
actionの定義はもっと簡単そうな気がするので、この調子でちゃんと完成させたい。
- 作者: るびきち
- 出版社/メーカー: 技術評論社
- 発売日: 2011/11/26
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 220回
- この商品を含むブログを見る
気象庁の時系列データをRで遊んでみた
はじめに
最近時系列データの解析に興味があって、いろいろと調べてたけれども、実データでないといまいちピンとこないので、いろいろとRの使いかたを調べつつ遊んでみた。emacsでもessをセッティングしているからいくらでもできるのだけど、せっかくなのでRStudioを使ってみた。
現場ですぐ使える時系列データ分析 ~データサイエンティストのための基礎知識~
- 作者: 横内大介,青木義充
- 出版社/メーカー: 技術評論社
- 発売日: 2014/02/18
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (6件) を見る
元データ
気象庁が過去の天気データを公開してくれているので、こちらを利用した。
いろいろとデータの種別やら期間やらあるけど、今回は1877年から2006年までの東京の月平均気温を使っている。
とりあえず読み込む
> tokyo <- read.csv("data.csv") > View(tokyo) > tokyo 年月 平均気温 1 1877/1 3.2 2 1877/2 3.6 3 1877/3 6.2 4 1877/4 13.6 5 1877/5 16.5 6 1877/6 22.0 7 1877/7 26.5 8 1877/8 25.9 9 1877/9 21.3 10 1877/10 15.9 11 1877/11 9.6 12 1877/12 5.8 13 1878/1 2.3 (後略)
本来は、csvにコメント部分や他の列もあるけど、そこは先に加工したものを取り込んだ。read.csvでそのへんはカバーできるので実は不要であるが。
とりあえずデータテーブルだと扱いづらいので、平均気温を年ごとに扱えるように分割しておく。
はじめ2次元配列に分割しようとして、なんかうまくいかないと悩んでたけど、3次元配列にしてみたらうまくいったのでよかった。
> splited_tokyo = array(tokyo$平均気温, dim=c(1,12,140)) > splited_tokyo[1, 1:12, 1:3] [,1] [,2] [,3] [1,] 3.2 2.3 3.2 [2,] 3.6 2.5 5.4 [3,] 6.2 7.2 8.0 [4,] 13.6 11.5 12.6 [5,] 16.5 18.3 18.0 [6,] 22.0 20.0 21.4 [7,] 26.5 26.0 26.1 [8,] 25.9 24.6 26.6 [9,] 21.3 22.8 21.3 [10,] 15.9 15.8 15.0 [11,] 9.6 9.7 9.7 [12,] 5.8 5.1 8.0
とりあえずグラフ化してみる
複数の時系列データをグラフ化するなら、ts.plotを使うのが簡単
> ts.plot(splited_tokyo[,,], type ="l")
140年分のデータをまとめてみると、やっぱり毎年同じように気温は変化する(1月2月が一番寒くて、8月が一番暑い)ということがわかるね。
20年ごとの相関も見てみた。
> pairs(splited_tokyo[1,1:12,c(1,21,41,61,81,101,121,140)])
細かいところをみると違うところもあるけど、ほぼ一直線上にプロットされており、かなり相関係数は1に近いといえそう(計算して出せよ、というのは正しいがやってない)
過去と比べてみる
温暖化温暖化っていうけど、本当に昔に比べて気温はあがってるのだろうか。
とりあえず時系列データということで、tsで時系列データに変換する
> ts_tokyo <- ts(data=tokyo$平均気温, start=c(1877, 1), frequency=12) > plot(ts_tokyo)
なんとなく上昇傾向にある気はするけど、よくわからない
> plot(stl(ts_tokyo, s.window="periodic"))
トレンドは確かに上昇傾向にあるけど、残差も多いのではなかろうか、これ。ただ、残差はプラスマイナス両方に散らばってるので、全体としては上昇傾向にある気がする。
ARIMAモデルによる推定もしてみた。
> library("forecast") > arima_tokyo <- auto.arima(ts_tokyo, trace=T, stepwise=F, seasonal=T) > plot(forecast(arima_tokyo, c(95), h=480)) [f:id:grugrut:20170226210851p:plain] これは、2050年には1年中16度ぐらいの過ごしやすかちょっと肌寒いぐらいの気温になる、ということであろうか。 * 別アプローチ 1877年から1976年までの平均、標準偏差に対し、1977年から2016年までの値がどれぐらいの範囲にいるかを調べてみた。 >|r| > m <- apply(splited_tokyo[1,1:12,1:100], 1, function(v){return (mean(v))})[1:12] > m [1] 3.482 4.183 7.277 12.951 17.226 20.815 24.694 26.057 [9] 22.367 16.403 10.982 5.873 > s <- apply(splited_tokyo[1,1:12,1:100], 1, function(v){return (sd(v))})[1:12] > s > ts.plot(splited_tokyo[,,101:140], type ="l") > lines(m-3*s, type = "l", col="red", lwd="3") > lines(m-2*s, type = "l", col="yellow", lwd="3") > lines(m-s, type = "l", col="green", lwd="3") > lines(m, type = "l", col="blue", lwd="3") > lines(m+s, type = "l", col="green", lwd="3") > lines(m+2*s, type = "l", col="yellow", lwd="3") > lines(m+3*s, type = "l", col="red", lwd="3")
赤が3σ、黄色が2σ、青が1σなので、気温が全体的に高くなってるように見える。
計算ミスでないことを角煮するために、1877年から1916年までの40年間で同様に確認してみると、
と、だいたいが1σ、外れ値っぽいところでもほぼ2σの範囲にはおさまってるので、データとしては問題なさそう。とはいえ最近寒くて閉口してるけどね。
まとめ
Rたーのしー!!
以下の本も買ったけど、見た目によらずかなり教科書教科書してて読みきれてない。
- 作者: 田中孝文
- 出版社/メーカー: シーエーピー出版
- 発売日: 2008/06
- メディア: 単行本
- 購入: 12人 クリック: 113回
- この商品を含むブログ (19件) を見る
zenburnテーマのregionのbackgroundが見辛かったのでテーマを少しいじった
はじめに
しばらくmisteriosoをテーマとして使ってたけど、最近はzenburnを使ってる。
理由は簡単で、Emacs Theme Gallaryで最も人気が高かったから。
https://pawelbx.github.io/emacs-theme-gallery/
落ち着いた色合いが気に入っているといえばそうなんだけど、気になるところもいくつかあり、そのひとつが色が弱々しくて視認性が悪いところ。
特に範囲選択したところ、リージョンの背景が色の違いがなさすぎてつらい。
これならまだわかる
単語レベルでmultiple-cursors使おうとすると、もうダメ
色のカスタマイズ
zenburnテーマは、zenburn-with-color-variablesマクロで各faceの設定をしてるので、init.elにこんな感じの設定をいれてみた。
(zenburn-with-color-variables (custom-theme-set-faces 'zenburn `(region ((t (:background ,zenburn-bg-2))))))
zenburn-bg-2は、いってしまえば、#000000と、完全なる黒なのだけど、これぐらい極端にやったほうがよい感じ。
くっきり表示される。
単語レベルでもこの通り。
おまけ
zenburnのissueには、「他のテーマは、regionが通常の箇所より明るい色が普通だから、もっと明るい色使おうぜ!」って提案されてるものの「そんなんしたら見辛くなるじゃん」と一蹴されてた(issueだけに)。
その通りだと思うけど、デフォルトも十分見辛いと思う。スタイリッシュさが失なわれるのは確かなので、おとなしく他のテーマに移ることも検討しよ。
Google Code Jamに向けて、goで雛形を書いてみた
遅ればせながら、最近Go言語に興味が出てきたので、普段はGCJ(Google Code Jam)をはじめ、競技プログラミングはJavaで書いているけど、その雛形をgoでリライトしてみた。
だいたい競技プログラミングのinputはスペース区切りのテキストで、outputは一行で、というのが基本なので、それに対応しているはず。
outメソッドがあらかじめfmt.Sprintf()で整形したstringを渡すことを前提としていて、若干使いづらいのが難点で、
out(fmt.Sprintf("Case #%v: my answer\n", test))
と渡さなければならない。
func out(format string, s ...interface{}) { fmt.Printf(format, s) }
で、仲介できると思ったのだけど、期待通りは動かなかった(複数渡した引数が、配列?として渡ってしまう)。
さすがに、渡し方はあるはずなので、さらに調査が必要そう。
fmtパッケージのソースを見るのが一番てっとり早いのかな。
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: Kindle版
- この商品を含むブログを見る
org-modeで計時(Clocking)する際に特定のTODOキーワードの場合だけ状態変更する
この記事は、.emacs Advent Calendar 2016の18日目の記事です。
org-modeの小ネタです。
はじめに
org-modeではTODO管理の中で、そのタスクにかかった時間を計測することができるようになっています。
C-c C-x C-i→時間計測を開始する(clock-in)
C-c C-x C-o→時間計測を終了する(clock-out)
で、便利なことに、clock-inした場合に、自動でTODOキーワードを変更することができます。
;; 時間計測を開始したら自動でSTARTED状態にする (setq org-clock-in-switch-to-state "STARTED")
これをやっておくと、未着手のTODOを着手(時間計測開始)すると、STARETEDになり、着手済か未着手かがわかりやすくなるというわけです。
Aプロジェクトを開始した状態。AプロジェクトはSTARTEDと表示され、BプロジェクトはTODOのままになっている。また、モードラインには計時しているタスクが表示されるのも便利。
org-captureを活用すると、タスクに着手している際に割り込み(電話等)が入って中断された場合でも、割り込まれたものも含め簡単に計時することができます。詳しくはこちらの過去記事をご覧ください。
このやりかたで困ったこと
そんなこんなでやってたのですが、困ったことがおきました。
それがこれです。
本当のTODOも、一時的に実施していたTODOで無い作業も、ミーティングのような計時だけしておきたいものもすべて、clock-inすると皆STARTED状態になってしまって、何が本当のTODOなのかわからなくなってしまうのです(今回は例として適当に作りましたが、実際はもっと雑多なものが30個近くたまってしまいました)。
本当は、GTDでは日次レビュー、週次レビューは基本なので、その中で不要なものを完了状態にしていくのが基本なのですが、そうはいっても、これだけたまると片付けるのも面倒だし、そもそも計時だけしたいものをいちいち完了に変更するのも面倒だし、ということで、モチベーションがかなり下がってしまいました。
計時だけして、TODOでないものは、TODOキーワードいらないようにできないだろうか、と虫の良いことを考えていました。
そんな都合のよいやりかた
実はorg-clock-in-switch-to-stateには関数を指定することができます(できること自体は知ってたけど、わざわざそれをする意味がわかってなかった)。
;; 時間計測を開始したらSTARTED状態に (setq org-clock-in-switch-to-state 'my-org-clock-in-switch-to-state) ;;; TODOの場合だけSTARTEDに変更する (defun my-org-clock-in-switch-to-state (state) (when (or (string-equal state "TODO") (string-equal state "STARTED")) "STARTED"))
my-org-clock-in-switch-to-stateには前の状態のTODOキーワードが入ってくるので、TODOか既にSTARTEDの場合のみ"STARTED"を返すようになっています(よくよく見直すとSTARTEDを条件に入れる必要ないし、ヒットしない場合はstateをそのまま返したほうがよいのかな?)
そうするとこんな感じで、TODOに設定していない場合は、STRATEDが設定されないので、org-agendaを汚さないで良いかんじ。
まとめ
他の人の.emacsを読んでて知ったのだけど、なぜそんな設定をしているのか想像しながら読むと勉強になるね
明日はtakaxpさんの「高速起動用ミニマム*scratch*バッファ」の予定です。楽しみですね。