OmniAICreator/Qiita-1.07M huggingface dataset:
HomebrewでプライベートなGitHubリポジトリのReleaseページから社内ツールを配布する

# 背景
GoでCLIツールを書いてると、ビルド済みのバイナリをどうやって配布するのか問題がある。
一番手軽なのはGitHubのReleaseページにリリース物を添付ファイルとしてアップロードしておいて、curlのワンライナーでダウンロードしてもらうという方法。

でも、privateなリポジトリだとこの方法はGitHubの認証を超えられなくて使えない。
社内向けのツールなどprivateなリポジトリに置いたものも配布したいので、これなんとかならんかなぁと思って試行錯誤した結果、以前curl+jqでダウンロードするワンライナーを編み出した。

[privateなGitHub Releaseページのリリース物をcurl+jqでダウンロードするワンライナー](http://qiita.com/minamijoyo/items/0affb46414cb746438bc)

でも、ワンライナーがすごい長いので、配布の敷居を下げるためにHomebrewのオレオレなbrew tapで配布できないかなぁと思って、さらに改良を加えた結果、brewのダウンロード処理をカスタマイズしてインストールすることに成功した。
これはみんなに有用だろうと思い、brew本体に機能追加のプルリクエストを送り、先日めでたくマージされた。

[New feature: Allow download from private GitHub repository](https://github.com/Homebrew/brew/pull/1763)

この機能は現在stableブランチにも入り、みんな使えるようになっているので、使い方を説明しておこうと思う。

# 使い方
そもそもの前提として、publicなリポジトリで独自のbrew tapを作って自作ツールを配布する方法は以前書いたので、publicな場合の方法を知らない場合は、以下を参照。タイトルにGolangって入ってるけど、別にGolangじゃなくても使える。

[Golangで書いたCLIツールのビルド済みバイナリをbrew tapでインストールできるようにする](http://qiita.com/minamijoyo/items/285d8838ffaa7ae1fe5f)

privateなGitHubリポジトリからダウンロードしたい場合は、ダウンロードurlの末尾にオプション指定として `:using => GitHubPrivateRepositoryReleaseDownloadStrategy` というダウンロード方法の指定を書く。

以下では `yourcompany` というOrgの `hoge` というツールを配布する想定で説明する。
このツールは `https://github.com/yourcompany/hoge` というprivateなGitHubリポジトリのReleaseページにビルド済みのバイナリがアップロードされている。

このツールをbrewでダウンロードしてインストールするには、
以下のような Formula用の `hoge.rb` を作成し、これを `https://github.com/yourcompany/homebrew-tap` というプライベートなGitHubリポジトリに配置する。

```hoge.rb
require "formula"

class Hoge < Formula
  homepage "https://github.com/yourcompany/hoge"
  url "https://github.com/yourcompany/hoge/releases/download/v0.1.0/hoge_v0.1.0_darwin_amd64.tar.gz", :using => GitHubPrivateRepositoryReleaseDownloadStrategy
  sha256 "6de411ff3e4b1658a413dd6181fcXXXXXXXXXXXXXXXXXXXX"
  head "https://github.com/yourcompany/hoge.git"
  version "0.1.0"

  def install
    bin.install "hoge"
  end
end
```

このようなprivateな独自brew tapを使う場合は、 `brew tap` コマンドに リポジトリパスをgitプロトコルで指定すると、gitの認証でprivateなtapも使えるようになる。

```bash
$ brew tap yourcompany/tap git@github.com:yourcompany/homebrew-tap.git
```

実際にhogeをインストールするには、 `https://github.com/yourcompany/hoge` からリリース物をダウンロードする必要がある。というわけで、このリポジトリにアクセス可能なGitHubのパーソナルアクセストークンを `HOMEBREW_GITHUB_API_TOKEN` という環境変数でexportしておく必要がある。

```bash
$ export HOMEBREW_GITHUB_API_TOKEN=xxx
```

この状態で、brew installすると、hogeがインストールできる。

```bash
$ brew install hoge
```

やったね :beer:

(補足: brew tapをgitプロトコルではなくhttpsでAPIトークンで認証する場合は `https://$HOMEBREW_GITHUB_API_TOKEN@github.com/yourcompany/homebrew-tap.git` とすることもできる)

# まとめ
HomebrewでプライベートなGitHubリポジトリのReleaseページからダウンロードしてきてbrew installできるようになった。これで、社内ツールが配布し放題ですね。

# 追記:2019/07/05
残念ながらGitHubPrivateRepositoryReleaseDownloadStrategyは、あんまり使われてないからか（？）、Homebrewのv2系でbrew本体から削除されてしまったようです。悲しい :cry:
https://github.com/Homebrew/brew/pull/5598

一応Strategyの定義をコピペしてFormulaに読み込ませれば使えるようなので、現時点のbrewの最新版v2.1.6で動くコードをGistに貼っておきました。使いたい人はこちらをコピペしてFormulaで読み込ませてご利用下さい。（今後Strategyのインターフェースが変わったりすると、また壊れるかもしれないですが）

[Using GitHubPrivateRepositoryReleaseDownloadStrategy removed in brew v2](https://gist.github.com/minamijoyo/3d8aa79085369efb79964ba45e24bb0e)
Meteor + Angular2でドラマ・レビューサイトを作ってみた

Meteor + Angular2でドラマ・レビューサイトを作ってみました。
http://www.mypress.jp/

Meteorの最大の魅力ですが、手早くアプリ作成ができます。このケースでは2週間ほどで作成できました。もちろん働いているので、休日や夜に作成したのですが。Angular2でなくてBlazeだったらもっと速くできていたかもしれません。一応bootstrapを使っていて、スマホでもＰＣでもそれなりに利用できます。

Meteor+Angular2でReactiveを実現させるためキーとなるのがmeteor-rxjsで、Minimongo cursorsにReactive性を与えてくれます。Meteorの世界（主にサーバ・DB）とAngular2の世界（クライアント）を貼り付ける糊のような役割を果たしてくれます。この辺のコーディングが面白くもあり、少しシームレスではないかなと違和感を感じるところでもあります。

Reactiveで言えばBlazeの方が自然でシンプルで手早く作れるような気がします。MeteorではBlazeが第一候補で、どうしても理由がある場合はAngular2を選択するというのが自然でしょうか。

今回のレビューサイトでは、ページング(ng2-pagination)とレイティング(ng2-rating)のライブラリを使っています。Angular2の豊富なエコシステムを利用できるのは強みですが、複雑さと解説サイトの少なさが欠点です。3月にAngular4になるといううし。Tutorialサイトもドラスティックに変更されているし、あああああ。。。。
https://angular-meteor.com/
【メモ】Githubのwebhookを使った自動git pull

# 背景
ローカルでプログラミングをしているとソースコードをGithubで管理し、外部のサーバでレポジトリをクローンし
開発しているウェブサイトなどをデプロイすることをよく行います。
ローカルでプログラミングしているとよく思うのが、外部のサーバのレポジトリを最新の状態に保ちたいということがよくあります。

なので、ローカルでプログラミングを行い、それをGithubにpushすると、Githubのwebhook機能で、
外部のサーバで`git pull`を行うという、自動デプロイ的なことを行います。
(何番煎じかわかりませんが、よくやるので個人的にメモしておく)


#外部サーバでの設定
##レポジトリをクローン

最新の状態に保ちたいレポジトリをGithubからクローンしてくる。

>***ハマりポイント***
>クローンしたレポジトリの所有者をapacheにしておく。（httpdのとき）
>webhookからgit pullするプログラムが実行されるので、そのままだと`Permission denied`される
>設定例）
>`# chown apache:apache -R <target_repo>`


 
##外部サーバにgit pullするスクリプトを用意

```webhook.php
<?php

// 設定
$LOG_FILE = dirname(__FILE__).'/hook.log';
$SECRET_KEY = 'hoge';　//githubで設定するsecretもところ

$header = getallheaders();
$hmac = hash_hmac('sha1', $HTTP_RAW_POST_DATA, $SECRET_KEY);
if ( isset($header['X-Hub-Signature']) && $header['X-Hub-Signature'] === 'sha1='.$hmac ) {
    $payload = json_decode($HTTP_RAW_POST_DATA, true);  // 受け取ったJSONデータ
    // ここに実行したいコードを書く(testレポに移動して、git pullする)
    exec('cd test ; git pull');
    file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." ".$_SERVER['REMOTE_ADDR']." git pulled: ".$payload['after']." ".$payload['commits'][0]['message']."\n", FILE_APPEND|LOCK_EX);
} else {
    // 認証失敗
    file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." invalid access: ".$_SERVER['REMOTE_ADDR']."\n", FILE_APPEND|LOCK_EX);
}
```

#Githubの設定

対象のレポジトリにて
Settings
↓
webhooks
↓
設定

```
payload URL
http://hoge/webhook.php

※外部サーバの先程用意したgit pullをたたくようにプログラムを指定
※今回の場合webhook.php

Content type
application/json

※どっちでもok

Secret
今回の場合は`hoge`

Which events would you like to trigger this webhook?
 Just the push event.　←これ
 Send me everything.
 Let me select individual events.
 Active
We will deliver event details when this hook is triggered.

※webhook機能実行の条件を指定する。今回、pushされたら実行してほしいので一番上
```

#動作確認

実際にpushを行い、動作を確認する
うまくいない場合はwebサーバのerror.logをみるとよい。
GoでAtcoder出てみるわ


#経緯
会社でGo使う事になったので、その勉強を兼ねてAtcoderの問題解きまくりてー
Atcoderでの問題を解く事で文法に慣れるが目標


# GoをMacにinstall
```brew を install
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

確認

```
$ brew update
Already up-to-date.
```

goをinstall

```
$ brew install go
==> Downloading https://homebrew.bintray.com/bottles/go-1.7.5.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring go-1.7.5.el_capitan.bottle.tar.gz
==> Caveats
As of go 1.2, a valid GOPATH is required to use the `go get` command:
  https://golang.org/doc/code.html#GOPATH

You may wish to add the GOROOT-based install location to your PATH:
  export PATH=$PATH:/usr/local/opt/go/libexec/bin
==> Summary
🍺  /usr/local/Cellar/go/1.7.5: 6,440 files, 250.8M
```

go path は未だ設定しない

# 練習問題を実施してみる

解く問題はこちら
http://abc053.contest.atcoder.jp/tasks/abc053_a

コードを書いて

```a.go
package main

import (
	"fmt"
)

func main() {

	var x int
	ans := "ABC"

	fmt.Scan(&x)

	if x >= 1200 {
		ans = "ARC"
	}
	fmt.Println(ans)

}
```

実行

```
$ go run a.go
1222
ARC
```
提出して無事 Accept !
http://abc053.contest.atcoder.jp/submissions/1095734
【VMWare】データストアの容量拡張

#はじめに
自宅環境で、ネステッド構成となっています。
Workstation側で、容量が割り当てられていることを前提に
これをesxiのデータストアに割り当てます。
作業内容をトレース。

#作業
①「構成タブ」をクリック。　ハードウェア欄より「ストレージ」をクリックします。

②データストアを選択し、右クリック→プロパティを選択します。

③「拡大ボタン」をクリックします。

④拡張に使用するデバイスを選択し、「次へ」をクリックします。

⑤現在のレイアウトに対し、「次へ」をクリックします。

⑥エクステントサイズについて、拡張すべき容量を入力し、「次へ」をクリックします。

⑦内容を確認し、「終了」ボタンをクリックします。
Azure LBにサーバ証明書を・・・

AzureでWEBサーバを構築することになったので、SSL証明書の適用に調べました。


# SSLオフロード

Azureでは、「SSLアクセラレータ」のことを「SSLオフロード」と定義されています。

# LBに適用
L4のLoadBalancerには、サーバ証明書を適用できません。
その代わりに･･･L7のApplicationGatewayで設定できます。

# ARMから設定してみよう
１．ARMで「アプリケーションゲートウェイ」を選択。
２．「追加」をクリック。
３．基本設定の項目を埋めて「OK」を押します。
４．設定項目のリスナー項目でプロトコルを「HTTPS」を選択。
５．「PFX証明書のアップロード」にファイルをアップします。

![app01.png](https://qiita-image-store.s3.amazonaws.com/0/109620/91528c53-d487-f5fb-4da4-f85d8d8c6284.png)

簡単！！
TFSで他人のチェックアウトを取り消す


## チェックアウト取り消し

チェックアウトの取消時には、`コレクション`と`ワークスペース`と`ユーザー`情報が必要。
それが分かっていれば以下のコマンドで取消が可能。
(試してないけどユーザーは無くても動くかも。)

```js:チェックアウト取消コマンド
tf undo /collection:"コレクション" /workspace:"ワークスペース";"ユーザー" "取消ファイルサーバーパス"

例）
tf undo /collection:http://192.168.1.1:8080/tfs/projectname /workspace:wkname;username $/Tools/Test/test1.cs
```

## 必要情報取得方法

コレクション・ワークスペース・ユーザーが分からない場合は、以下のように取得する。

* コレクションの取得  
`開発者コマンドプロンプト`でコレクションを取得する。

```js:コレクション取得コマンド
tf workspaces
```
```js:結果
コレクション: http://192.168.1.2:8080/tfs/myproject
ワークスペース 所有者             コンピューター  コメント
-------------- ---------------- -------------- -----------------
build          ほげた             hoge_pc

コレクション: http://192.168.1.2:8080/tfs/yourproject
ワークスペース 所有者             コンピューター  コメント
-------------- ---------------- -------------- -----------------
dev            ほげた            hoge_pc
```

* ワークスペース・ユーザーの取得  
ユーザーはフルネームで表示されるので、サーバーマネージャー等で確認。

```js:全ワークスペース取得コマンド
tf workspaces /collection:"コレクション" /owner:*
```

```js:結果
ワークスペース      所有者        コンピューター
------------------ ------------- --------------
Build              ほげた          hoge_pc
Dev                ぴよこ          piyo_pc
```



* (おまけ)チェックアウトファイルのサーバーパス取得  
$付パスがサーバーパス

```js:チェックアウト一覧取得コマンド
tf status /collection:"コレクション" /user:*
```

```js:結果
ファイル名             変更 ユーザー ローカル パス
---------------------- ---- -------- ------------------------------------
$/MyProject/COMMON
Db.cs                  編集 ほげた   D:\Source\MyProject\COMMON\Db.cs
Control.cs             編集 ぴよこ   D:\Source\MyProject\COMMON\Control.cs

$/MyProject/Main
Project.csproj         編集 ぴよこ   D:\Source\MyProject\COMMON\Project.csproj

3 変更 (数)
```
Azureオートスケールやってみて感じた問題点

Azureのオートスケール（「仮想マシンのスケールセット」）をポータル画面（ARM)からやってみました。
※ 2017/2/4時点のものです。今後ARMから実施できる内容がより充実してくることを期待しています。

■ 問題点
・リソースグループは「新規作成」のみ（まだかわいいレベル:relieved:）
・一度設定すると設定変更は、できない。（まぁ、きっちり考えて設定しますよ:sob:）
・セットできるイメージは、Azureが用意しているものだけ（おいおい困る・・・:tired_face:）
  → 仮想マシン作成時には2017/2/4時点、CentOS7.3が最新だが、ここではCentOS7.2までしか出てこなかった。
・セットで自動的にできるのはLB（SSLオフロードを行いたいのでApplicationGatewayであってほしかった:tired_face:PowerShellならApplicationGatewayにできるのか？）
⇒ 2017/2/14 ApplicationGatewayにも対応していることが判明！PowerShellからの設定になりますが、動作検証してみます。

![AutoScale02.png](https://qiita-image-store.s3.amazonaws.com/0/109620/ca46caf8-0bdd-6e17-6350-21dea614f2dd.png)




■ 設定内容
スケールセットの情報自体あまり多くないですが、次の牛上さんのサイト（「くらう道」）が参考になります。
（参照先）http://www.cloudou.net/virtual-machine-scale-sets/vmss001/
分報をSlackにCLIで投稿する

# はじめに

分報という文化が定着してきているようですね。

- [Slackで簡単に「日報」ならぬ「分報」をチームで実現する3ステップ〜Problemが10分で解決するチャットを作ろう | | Craftsman Software Inc.](http://c16e.com/1511101558/)

私も始めてみたのですが、作業を随時投稿するという目的の割に、わざわざSlackの画面に移動しなければいけないという面倒臭さがあるのはちょっと納得がいきません。やはりターミナル上から投稿できるべきです。

Slackを操作するコマンドラインツールはいくつかありますが、今回は `slackcat` を使ってみましょう。基本的にGoで書かれているようです。クロスプラットフォーム、良いですね。

- [vektorlab/slackcat: CLI utility to post files and command output to slack](https://github.com/vektorlab/slackcat)

# インストール＆設定

Macではおなじみの `brew` コマンドでインストールできます。

```console
$ brew install slackcat
```

Linuxではバイナリをダウンロードして配置します。Goはシングルバイナリを生成するので簡単ですね。

```console
$ wget https://github.com/vektorlab/slackcat/releases/download/v1.1/slackcat-1.1-linux-amd64 -O slackcat
$ sudo mv slackcat /usr/local/bin/
$ sudo chmod +x /usr/local/bin/slackcat
```

Slackとの通信に必要なtokenを設定します。下記のコマンドを実行してください。

```console
$ slackcat --configure
```

デフォルトのWebブラウザが起動し、権限を求めてきます。

<img width="603" alt="権限確認画面" src="https://qiita-image-store.s3.amazonaws.com/0/5823/13ea4886-4628-7766-294c-54f595ffe825.png">

承認すると slackcat のページに遷移します。

<img width="1900" alt="Token表示画面" src="https://qiita-image-store.s3.amazonaws.com/0/5823/508bcd7f-8907-536b-5dcd-95f45525895b.png">

デカデカとtokenが表示されているので、これを指示通りにファイルに保存します。内容はだいたい下記のようなものです。

```text:~/.slackcat
xoxp-0123456789-0123456789a-0123456789ab-0123456789abcdefghijklmnopqrstuv
```

ここで発行されるtokenはWebhookのtokenとは違いパーソナルなものです。このコマンドを使って投稿した際には、 `BOT` ではなく自分自身として記録されます。

# コマンドをラップする

分報を投稿する際にはこのようなコマンドを実行します。

```console
$ echo -e "山田さんのレビューを始めマックス" | slackcat --channel "times_artifactsauce" --tee --stream
```

`slackcat` はテキストの投稿はもちろんファイルをアップロードしたりもできるのですが、分報の投稿を簡略化したいというのが今回の目的ですので、むしろテキストの投稿しかできないように制限してしまいましょう。また、分報を投稿するチャンネルは固定されているはずですので、これも制限してしまいましょう。これらの条件を考慮したラップスクリプトが下のようになります。

```bash:~/local/bin/slack
#!/usr/bin/env bash

set -eu

: ${POST_CHANNEL:="times_artifactsauce"}

if [[ $# -eq 0 ]]; then
    echo "[ERROR] Nothing has been entered." >&2
    exit 1
fi

echo -e $1 | slackcat --channel $POST_CHANNEL --stream
```

こんな感じで実行します。簡単ですね。

```console
$ slack "山田さんのレビューを始めマックス"
slackcat connected to HOGE-TEAM as artifactsauce
slackcat starting stream
slackcat flushing remaining messages to Slack...
slackcat flushing remaining messages to Slack...
slackcat posted 1 message lines to times_artifactsauce
```

`slackcat` は実行結果をsnippetにして投稿したり、出力されたファイルを投稿したりすることが、主目的なんじゃないでしょうか？オプションを眺めている限りはそのように感じます。

# 終わりに

コマンドラインから簡単に分報を投稿できるようになったのは良かったのですが、簡単になったせいで分報の内容がだんだんTwitter化してきて、それはそれでどうなのかなと思っています。

また注意点として、コマンドラインから投稿しているだけでは他の人が自分のチャンネルに投稿してくれたことに気づけないので、SlackアプリのDesktop notificationsを必ず "Activity of any kind" にしておきましょう。
Amazon EC2 F1について調べた

[Amazon EC2 F1](https://aws.amazon.com/jp/ec2/instance-types/f1/)についての情報たち。随時更新する予定。


公式情報
-------

### プレスリリース
#### [Xilinx](https://www.xilinx.com/)

- [Xilinx FPGAs to be Deployed in New Amazon EC2 F1 Instances...](http://press.xilinx.com/2016-12-07-Xilinx-FPGAs-to-be-Deployed-in-New-Amazon-EC2-F1-Instances-Accelerating-Genomics-Financial-Analytics-Video-Processing-Big-Data-Security-and-Machine-Learning-Inference) - 2016-12-07

- [ザイリンクスの FPGA、Amazon EC2 の新しい F1 インスタンスに採用...](https://japan.xilinx.com/japan/j_prs_rls/2016/deployed-in-new-amazon-ec2-f1-instances.html) - 2016-12-13

### Blog/Forums

- [Amazon picks Xilinx UltraScale+ FPGAs to accelerate AWS,...](https://forums.xilinx.com/t5/Xcell-Daily-Blog/Amazon-picks-Xilinx-UltraScale-FPGAs-to-accelerate-AWS-launches/ba-p/735873) - 2016-11-30
- [Developer Preview – EC2 Instances (F1) with Programmable Hardware](https://aws.amazon.com/jp/blogs/aws/developer-preview-ec2-instances-f1-with-programmable-hardware/) - 2016-11-30

### Slide

- [Announcing Amazon EC2 F1 Instances with Custom FPGAs](http://www.slideshare.net/AmazonWebServices/announcing-amazon-ec2-f1-instances-with-custom-fpgas)

以下，ほとんど公式情報からの引用。

Specs
------

AWSの[公式ページ](https://aws.amazon.com/jp/ec2/instance-types/f1/)とBlogから。

インスタンスは`f1.2xlarge`と`f1.16xlarge`の2種類

| インスタンスタイプ | FPGA | vCPU | メモリ(GiB) | SSD (GB) |
|------------------|------|------|-------------|----------|
| f1.2xlarge       | 1    | 8    | 122         | 480      |
| f1.16xlarge      | 8    | 64   | 976         | 4 x 960  |


### F1 Instance

- CPU: Intel Broadwell E5 2686 v4 processors (2.3 GHz base speed, 2.7 GHz Turbo mode on all cores, and 3.0 GHz Turbo mode on one core)
- Memory: up to 976 GiB
- Strage: up to 4 TB of NVMe SSD

### FPGA

- Up to eight
- [Xilinx UltraScale+ VU9P](https://www.xilinx.com/products/silicon-devices/fpga/virtex-ultrascale-plus.html#productTable) fabricated using a 16 nm process.
- 64 GiB of ECC-protected memory on a 288-bit wide bus (four DDR4 channels).
- Dedicated PCIe x16 interface to the CPU.
- Virtual JTAG interface for debugging.

FPGA間は双方向リングバス。

開発環境
--------

基本的にXilinxの[Vivado](https://www.xilinx.com/products/design-tools/vivado.html)だが AmazonからF1 Hardware Development Kit (HDK)が提供される。
だけど現在リンク切れ。（member only）

- https://github.com/aws/aws-fpga

host-to-FPGA，FPGA-to-memoryとFPGA-to-FPGA通信についてはサンプルアプリケーションが提供される。


設計データ
---------

- Amazon FPGA Image (AFI)
- Amazon Machine Image (AMI) 

AFIというのがFPGAコンフィグレーションデータ。AFIは[AWS Marketplace](https://aws.amazon.com/marketplace/)で販売できる。
AMIはFPGAの開発環境が入ったLinux?のようだ。


価格
-----

不明


その他
-----

疑問点，不明点など。

- PCIeはGEN2？
- FPGA間通信はXilinx Auroraかな？もしくはInfiniBand？
- PCIeのデバイスドライバはどうなっているのだろう？
- FPGAのコンフィグレーションどうやるんだろう？
- XilinxのFPGAデータは通常bitstream（bitファイル）だけど，AFIというのはAmazon専用のフォーマットなんだろうか？
- Virtual JTAGって何だろう。
- FPGAにバグがあってPCIeがフリーズしたらどうするんだろう？
swiftのguardを使ってみる

#guardとは
guardは条件に一致なかった場合に、処理を中断させるための構文です。
条件に一致ってifと一緒じゃんと最初は思いがちですが、
ifの場合は条件に一致したら何かしらの処理を行うことに対して、
guardの場合は処理を中断させるということがポイントになります。

つまり、条件に一致せず処理を中断させる場合は、if文で処理を中断させるのではなくて、guardで処理を中断させましょうということです。

```swift
func guardTest(status: Int) {
    guard status == 0 else { return } // 引数が0でなかったらreturn
    
    print("guardしません")
}
```

#ifでも書けるのにguardを使うメリットは？
これからguardを覚える場合には、ifでできることをわざわざ覚える必要あるのかよと思いがちですが、それでもguardを使う理由は、可読性が上がることだと思います。

guardが出てきた時点で、処理から抜けるんだなということがわかるので、慣れてくると読みやすいです。


```swift
func guardTest(num: Int) {
    guard num == 5 else { print("guardしました") } 
    // 'guard' body may not fall through, consider using 'return' or 'break' to exit the scope
    
    print("guardしてないよ")
}

```

このようにif文と同じように条件に一致したら処理を行わせようとすると、エラーが発生します。
returnかbreakを使ってスコープから抜けてくださいねと言ったようなことを言われちゃいます。
if文と同じような処理を行うことができないので、guardが出てきたら処理を途中で抜けるんだなーということがわかると思います。


##アンラップするときにも使える

```swift
func guardTest(num: Int?) {
    guard let unwrappedNum = num else { return }
    
    print(num) // Optional(5)
    print(unwrappedNum) // 5
}

guardTest(num: 5)
```

if文と同じようにnilチェックを行えます。
こちらもnilだったら処理を中断させたいので、処理を中断させる構文であるguardを使用した方が読みやすくなりますね。
Rubyとmime-typesを使ってファイルの種類をフィルタリングする

## やりたい事

動画ファイルの拡張子をまとめた正規表現を作って、
その正規表現で`grep`すると、動画ファイルの名前だけの配列が取得できるようにしたい。

### 例

```ruby
Dir.glob('*')
# => ["hoge.mp4", "huga.png", "homu.mov"]

Dir.glob('*').grep(video_extensions_regexp)
# => ["hoge.mp4", "homu.mov"]
```

## とりあえず、手動で拡張子を登録してみる
動画ファイルの拡張子を思いつくだけ配列に格納して、正規表現として展開する

```ruby
extensions = %w(mp4 m4v avi mov)

joined_extensions = extensions.join('|')
#=> "mp4|m4v|avi|mov"

video_extensions_regexp = /\.(#{joined_extensions})$/
#=> /\.(mp4|m4v|avi|mov)$/
```

一応これで出来ますが、絶対漏れがありそうですよね…。
そこで、mime-typesを導入してみます。

## mime-typesを使って拡張子を登録する

[`mime-types`](https://github.com/mime-types/ruby-mime-types)には、 MIMEのタイプが網羅されているだけでなく、各タイプに該当する拡張子も登録されています。便利！

実際に試してみたい方は、`gem install mime-types`して、
irbやpryなどから`require 'mime/types'`して、下記の例を実行してみてください。

### mime-typesの例

```ruby

MIME::Types['video/mp4']
#=> [#<MIME::Type: video/mp4>] 
# 配列が返ってくる

MIME::Types['video/mp4'].first.extensions
#=> ["mp4", "mpg4", "f4v", "f4p", "mp4v"] 
# この拡張子一覧を使う

MIME::Types[/^video/]
#=> [#<MIME::Type: video/1d-interleaved-parityfec>,
 #<MIME::Type: video/3gpp>,
 #<MIME::Type: video/3gpp-tt>,
 #<MIME::Type: video/3gpp2>,
#...
# 正規表現を渡すと、該当するMIME Typesが全部返ってくる
```

これを使えば、全てのvideoファイルの拡張子一覧が作れそうですね！

### 完成形

```ruby
extensions = MIME::Types[/^video/].flat_map(&:extensions)
#=> ["3gp", "3gpp", "3g2", "3gpp2", "dl", "dv", "gl"...]

joined_extensions = extensions.join('|')
#=> "3gp|3gpp|3g2|3gpp2|dl|dv|gl..."

video_extensions_regexp = /\.(#{joined_extensions})$/
#=> /\.(3gp|3gpp|3g2|3gpp2|dl|dv|gl...)$/
```

といった感じで、ほとんど全ての動画ファイル形式をカバーした正規表現が作れました。

ついでに、method_missingを使って、動画以外(画像とか)にも使えるようにしたModuleを作ってみました。

### 複数形式に対応したModule

```ruby
require 'mime/types'

module ExtReg
  def self.method_missing(name, *args)
    if instance_variable_defined?("@#{name}")
      instance_variable_get("@#{name}") # インスタンス変数に保存されていればそれを取ってくる
    elsif !(types = MIME::Types[/^#{name}/]).empty? # 該当のMIMEタイプが存在するか確認する
      extensions = types.flat_map(&:extensions)
      joined_extensions = extensions.join('|')
      extensions_regexp = /\.(#{joined_extensions})$/
      instance_variable_set("@#{name}", extensions_regexp) # @videoなどに保存しておく
      extensions_regexp
    else
      super
    end
  end
end

ExtReg.video
#=> /\.(3gp|3gpp|3g2|3gpp2|dl|dv|...)$/

ExtReg.image
#=> /\.(bmp|cgm|g3|gif|ief|jp2|...)$/
```

これを使うと、頭の例がこうなります。

```ruby
Dir.glob('*')
# => ["hoge.mp4", "huga.png", "homu.mov"]

Dir.glob('*').grep(ExtReg.video)
# => ["hoge.mp4", "homu.mov"]
```

簡単に目的達成できました！
これでもう、拡張子を自力で列挙しなくて済む…。
homestead upした後No input file specified.と表示されました

`homestead up`したらLaravelが表示されなくて困りました。

# homestead が表示されない
http://192.168.10.10/ にアクセスしたとこ表示がうまくされませんでした。

```
No input file specified.
```
<img width="258" alt="No input file specified." src="https://qiita-image-store.s3.amazonaws.com/0/1624/ef73e502-5aa7-9b51-3a2f-d172914818e0.png">

困りました｡ﾟ(ﾟ´Д｀ﾟ)ﾟ｡

# 環境
環境はMacのHomesteadです。

# nginxのログを見る
`homestead up`はできているようなので、sshログインします。

```
homestead ssh
```

nginxのログを見ます。

```
sudo tail -f /var/log/nginx/homestead.app-error.log

[error] 1782#0: *4 FastCGI sent in stderr: "Unable to open primary script: /home/vagrant/Code/Laravel/public/index.php (No such file or directory)" while reading response header from upstream, client: 192.168.10.1, server: homestead.app, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "192.168.10.10"

・・・
```
index.phpが見つからないようです。
実際のindex.phpファイルを調べてみると、`/home/vagrant/Code/public/`にsyncされていることがわかりました。

# Homestead.yamlの確認
foldersのtoが不完全だったようです。

```diff
vim ~/.homestead/Homestead.yaml

folders:
    - map: /Users/pugiemonn/Documents/workspace/laravel-project
-      to: /home/vagrant/Code
+      to: /home/vagrant/Code/Laravel
```
Codeの後ろに`/Laravel`を足しました。

# ブラウザを確認
今度は表示がされました。

<img width="633" alt="Laravel初期画面" src="https://qiita-image-store.s3.amazonaws.com/0/1624/89e996ff-a043-982a-5912-d381c29b6d29.png">


# 参考

- http://qiita.com/YU81/items/d1b2100aae53d2088a2c
- http://qiita.com/pugiemonn/items/44b8bac1fd57688e853b
- http://qiita.com/pugiemonn/items/3d000ac0486987dd92df
Gitでリモートのリポジトリをローカルに作成する


GitやGitHubのコマンドを学習中に、他人に迷惑をかけずにおもいきりいろいろためしてみたいときがありますよね。また、ネットにつながらない環境でも git push とかリモート系のコマンドをいろいろためしてみたいとかもあります。
そんなとき、下記のようにするとリモートのリポジトリをネット上にもつのではなく、ローカルのディレクトリ上に作成して作業することができます。


## リモートのリポジトリを作成

```bash
$ mkdir gitserver && cd $_
$ git init --bare --shared ./hello.git
Initialized empty shared Git repository in /Users/xxxxxx/gitserver/hello.git/
```

## ローカルにクローンする

```bash
$ cd ../git/
$ git clone ../gitserver/hello.git/
Cloning into 'hello'...
warning: You appear to have cloned an empty repository.
done.
```


## 中身を見てみる

```bash
$ cd hello
$ git config --list
remote.origin.url=/Users/xxxxxx/git/../gitserver/hello.git/
$
```

所定のローカルのディレクトリをoriginとして参照している環境が構築できたっぽいです。一応 pushまでやってみます。


```bash
$ touch README.md && git add README.md && git commit -m 'first commit'
[master (root-commit) 324f171] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 216 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /Users/xxxxxx/git/../gitserver/hello.git/
 * [new branch]      master -> master

$ git branch -vv
* master 324f171 [origin/master] first commit
$ git branch
* master
$
```

OKそうですね。。


## 参考にさせていただいたサイト。感謝します!
- [Gitでやらかした時に使える19個の奥義](http://qiita.com/muran001/items/dea2bbbaea1260098051)
AzureFunctions で開発するときにハマったこと

## 外部の `.csx` ファイルが更新されない 
Function 内のコードを共通化したいとき、外部の `.csx` に置き、 `#load` で読み込むという方法がある。  
[Azure Functions C# developer reference](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#reusing-csx-code)

GitHub 連携によるデプロイを行っているが、外部の `.csx` ファイルのみ更新した場合に影響する Function が更新されない。  
無意味に Function を更新するという方法によって回避できる。
(他にもっといい方法があれば教えてほしい)
Gitgraph.js をラップしてコマンドっぽく使えるようにした

Git のコミットグラフを簡単に作成できる [Gitgraph.js](https://github.com/nicoespeon/gitgraph.js) を使っていて、「git のコマンドを入力している感じで実装したいなぁ」と思ったので作ってみた。

https://github.com/opengl-8080/gitgraphwrapper.js


![gitgraph.png](https://qiita-image-store.s3.amazonaws.com/0/28302/3651d33e-0c42-c9f0-9ced-917b96f81c4f.png)

こんなのを描こうと思った場合、 Gitgraph.js をそのまま使うと

```js
var gitGraph = new GitGraph({orientation: 'vertical-reverse'});

// master ブランチ作成
var master = gitGraph.branch({
    name: 'master',
    color: 'red',
    commitDefaultOptions: {
        color: 'red'
    }
});
master.commit().tag('v0.0.0');

// develop ブランチ作成
var develop = gitGraph.branch({
    name: 'develop',
    color: 'deepskyblue',
    commitDefaultOptions: {
        color: 'deepskyblue'
    }
});
develop.commit();

// topic1 ブランチ作成
var topic1 = develop.branch('topic1');
topic1.commit().commit();

// topic2 ブランチ作成
var topic2 = develop.branch('topic2');
topic2.commit();

// topic1 を develop にマージ
topic1.merge(develop);

// develop を topic2 にマージ
develop.merge(topic2);
// topic2 を develop にマージ
topic2.commit().merge(develop);

// develop を master にマージ
develop.merge(master);
master.tag('v1.0.0')

// 孤立ブランチを作成して master にマージ
var orphan = gitGraph.orphanBranch({
    name: 'orphan',
    color: 'purple',
    commitDefaultOptions: {
        color: 'purple'
    }
});
orphan.commit().commit().merge(master);
master.tag('v2.0.0');
```

こんな感じになる。

これが、

```js
new GitGraphWrapperExtention({orientation: 'vertical-reverse', elementId: 'gitGraphWrapperExtention'})
    .defaultOptions({
        branch: {
            master: {
                color: 'red',
                commitDefaultOptions: {
                    color: 'red'
                }
            },
            develop: {
                color: 'deepskyblue',
                commitDefaultOptions: {
                    color: 'deepskyblue'
                }
            },
            orphan: {
                color: 'purple',
                commitDefaultOptions: {
                    color: 'purple'
                }
            }
        }
    })

    // master ブランチを作成
    .branch('master')
    .commit()
    .tag('v0.0.0')
    
    // develop ブランチを作成
    .branch('develop')
    .commit()

    // topic1 ブランチを作成
    .branch('topic1')
    .commit()
    .commit()

    // develop ブランチから topic2 ブランチを作成
    .branch('topic2', 'develop')
    .commit()

    // develop に移動して topic1 をマージ
    .checkout('develop')
    .merge('topic1')

    // topic2 に移動して develop をマージ
    .checkout('topic2')
    .merge('develop')
    .commit()
    // topic2 を develop にマージ
    .checkout('develop')
    .merge('topic2')

    // develop を master にマージ
    .checkout('master')
    .merge('develop')
    .tag('v1.0.0')

    // 孤立ブランチを作成して master にマージ
    .orphanBranch('orphan')
    .commit()
    .commit()
    .checkout('master')
    .merge('orphan')
    .tag('v2.0.0')
;
```

こんな感じで書けるようになる。
複数のサイトからNode.jsとcheerio-httpcliを使用してのスクレイピングのメモ

# やりたいこと
楽天証券の投資信託の各商品ページから基準価額や純資産といった情報を取得して何らかのテキストファイルに出力する。という方法を自分で試してみる。
[例]https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C0009VE0
**※ただし必要以上にサイトにアクセスしないこと、私用目的以外に使用しないことを心がけましょう。**

##使用した言語 > Node.js

Node.jsを使用したスクレイピングということで「cheerio-httpcli」を使用。
参考にしたサイトは↓こちらです。
[Node.jsのスクレイピングモジュール「cheerio-httpcli」が大規模アップデートして帰ってきた]http://qiita.com/ktty1220/items/64168e8d416d6d8ffb45


##大まかな流れ
１．アクセスしたいURLを記述したファイルを外部モジュールとして用意しておく。
（単純なテキストファイルでも別に可）

```exports.js
exports.url1 = "https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C00080J9"
exports.url2 = "https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C0009VE0"
```

２．「cheerio-httpcli」のfetchメソッドを使用して必要なデータの抽出を行う。
実はここ嵌りました。実際のサイトのソースを見てもらうとわかるのですが、取りたい情報はこんな構造でした。

```サイト
<table class="tbl-fund-summary">
<tbody>
<tr>
<th>基準価額</th>
<td class="br0"><span class="value-01">8,398</span> 円 （2/3）</td>
<td>
```

で、初めはこんな書き方をしていました。

```scraping.js
for(var i=0; i < urllist.length; i++){
client.fetch(urllist[i], {}, function(err, $, res, body) {
     var title = $("title").text();
     // // ファンド情報
     var target = $("table[class='tbl-fund-summary']");
     // 基準価額
     var baseCost = target.find("td[class='br0'] > span").eq(0).text();
（省略）
```

かなりはしょってますが、やろうとしたことは

*・テキストファイルに書いたURLをリスト化して繰り返し処理の中でサイトにアクセスし、データを取得。いったん配列に追加して最後にテキストファイルに書き出す。*

でした。
が、上記はうまくいきませんでした。まあfetchメソッドが非同期のメソッドだからでしょうね。
最後にファイルに書き出すタイミングではまったくデータがありませんでした。（null,nullとか）

なので、プロミス形式に方法を転換。こんな感じ。

```scraping.js
var array = [];
// プロミスによる制御
client.fetch(exports.url1)
    .then(function(result) {
        var data = getFoundData(result);
        array.push(data);
        return client.fetch(exports.url2);
    })
    .then(function(result) {
        var data = getFoundData(result);
        array.push(data);
    })
    .catch(function(err) {
        console.log(err);
    })
    .finally(function() {
        fs.writeFile(exports.json, JSON.stringify(array, null, '    '));
    });
```

getFoundDataはこんな感じ

```scraping.js
function getFoundData(result) {
    var $ = result.$;
    var title = $(exports.titile).text();
    // ファンド情報
    var target = $(exports.foundtable);
    // 基準価額
    var baseCost = target.find(exports.foundbasedata).eq(0).text();
    // 純資産額
    var assets = target.find(exports.foundbasedata).eq(1).text();
    // 直近分配金
    var dividend = target.find(exports.foundbasedata).eq(2).text();

    var data = {
        "商品名": title,
        "基準価額": baseCost,
        "純資産額": assets,
        "直近分配金": dividend
    };
    return data;
}
```

各商品のサイト構造はどれも同じなので現状、(2017/2/4）ごり押しで取得できる。
取得した結果を返却して配列にどんどん詰めていって、最後にJSONで書き出してる。

取得したいサイト（商品）が増えたら.thenをどんどんつなげればいいはず。
取り急ぎやったことの覚書でした。

#感想
javascriptの知識もNode.jsの知識も全然ないので苦労した。C#ならもう少し楽に書けたとは思うけれど、どうしてもNode.jsを使ってやってみたかったのであえて不慣れな方を選んだのです。

ちなみにこの機能、実際に使うかいうとと使う予定はまったくない。普通に自分の口座にアクセスすれば必要な情報はとりあえず見れるので。
bundlerのBUNDLE_DISABLE_SHARED_GEMS: "true"はいらない

以前からRubyのプロジェクトは`bundle install --path vendor/bundle`をつけるようにしていたが、自分の中でこんなことはしなくてよくて、システムのgemを利用してしまえばよい、という結論に至った。

ちなみに`--path vendor/bundle`をつけると`.bundle/config`に以下のように記録される。

```
$ cat .bundle/config
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_DISABLE_SHARED_GEMS: "true"
```

というのもこちらのドキュメントを読んで
http://bundler.io/v1.14/man/bundle-install.1.html#DEPLOYMENT-MODE

`vendor/bundle`にインストールするのは本番にデプロイする時だけでいいよ、
開発環境ならシステムに入っているのを使えると便利だよ、
と書いてあったから。
確かにバージョン固定はGemfile.lockでされるから十分なのかな。
本番にデプロイする際に忘れずに`--deployment`をつける、と。

逆にnpmは`-g`をつけないとデフォルトでローカルになる。
bundlerも一緒にして考えてしまっていた。

（異論があれば教えてもらえると幸いです）

## 環境

* Ruby 2.3.1 on rbenv 1.1.0 in macOS Sierra 10.12.3
* bundler 1.14.3
SBCL + ASDF3でカレントディレクトリ以下のsystemを読み込む

# 概要

ASDF3でSBCL起動時のディレクトリ（カレントディレクトリ）以下にあるsystemを読み込む際の設定です。

# .sbclrcを書き換える

```cl:.sbclrc
(require :asdf) ; quicklispの設定が既にある場合はこの行は不要です。
(asdf:initialize-source-registry 
  `(:source-registry (:tree ,*default-pathname-defaults*) :inherit-configuration))
```

# 試してみる

```cl:./stab/stab.asd
(in-package :cl-user)
(defpackage stab-asd
  (:use :cl :asdf))
(in-package :stab-asd)

(defsystem stab
  :depends-on ()
  :components ((:module "src" 
                :components ((:file "stab")))))
```

```cl:./stab/src/stab.lisp
(defpackage stab
  (:use :cl)
  (:export :foo))
(in-package :stab)
(defun foo () (print "stab loaded"))
(in-package :cl-user)
```

sbclを.asdファイルがあるより上の階層のディレクトリで起動。

```shell-session
* (asdf:load-system :stab)

T
* (stab:foo)

"stab loaded"
"stab loaded"
*
```

# 補足

以前、[SBCL ＋ ASDF3 ＋QuickLispでプロジェクトの作り方](http://qiita.com/singy/items/bca1a601fa4c35d81580)
でカレントディレクトリのプロジェクトを見に行く方法を書きましたが、
これは[ASDF Manual](https://common-lisp.net/project/asdf/asdf.html#Configuring-ASDF-to-find-your-systems)によるとold styleなやり方なんだそうです。

本来は~/.config/common-lisp/source-registry.confに以下のように書けばいいらしいのですが

[設定ファイルを利用した設定](http://cl.cddddr.org/index.cgi?ASDF)

```cl:~/.config/common-lisp/source-registry.conf
(:source-registry
 (:tree (:home "lisp")) ; ~/lisp/に展開される
 :inherit-configuration)
```

これはなぜかASDFがsystemを見つけてくれず、うまくいきませんでした。
ショートカットキーで通知に飛ぶ for Mac

# 通知がピョコっとくるよね

![notification_test.gif](https://qiita-image-store.s3.amazonaws.com/0/69140/b8acf0b2-b863-ab75-ea4e-1e1081370cf7.gif)

# いちいちクリックしてアクセスするのがめんどくさい

「mac 通知　ショートカット」とかでググったが良いのが見つからず。

# ではどうするか

- cliclickコマンドで指定の場所をクリックする
- BetterTouchToolでショートカットキーにそのコマンドを割り当てる

まずは

```
brew install cliclick
```

BetterTouchToolを開く。

<img width="1014" alt="bbt_ss.png" src="https://qiita-image-store.s3.amazonaws.com/0/69140/970e0447-2887-ccfd-36a6-e45967712750.png">

Keyboardショートカットキーを割り当てる。Trigger Predefined Action を Execute Terminal Commandにして、下記を実行するコマンドに設定すれば良い。

```
/usr/local/bin/cliclick c:1300,70
```

> ## 追記
> コメント欄で教えていただきました。下記のコマンドにするとカーソルが元の位置に戻ってくれます。
> 
> ```
> pos=`/usr/local/bin/cliclick p:. | /usr/bin/perl -pe 's/.*?(\d+,\d+)/$1/'`;/usr/local/bin/cliclick c:1300,70 m:$pos;
> ```

x座標1300, y座標70にしていれば大体成功すると思う。
ディスプレイ上の座標を確認したければ、⌘ + Shift + 4で範囲選択スクリーンショットのモードになり座標を確認できるという小技を使うと良い。

割り当てるショートカットキー（またはトラックパッドのアクションなど）は自由だが、ここではshift二度押しにしている。

#終わり
これで通知が来たらShift二度押しでSlackやLineが開けるようになった。
cliclickとBetterTouchToolの組み合わせってわりと汎用性ありそう。
Node.jsのpassport-twitterで認証時にメールアドレスを取得する

[passport](http://passportjs.org/)を使ってtwitterアカウントでの認証を実装しようと思ったら３時間ほどハマりました。日本語の情報があまり出てこなかったので自分用にメモ。尚、Node.jsのExpressを使って開発中です。

## ライブラリ
- express
- passport
- passport-twitter
- express-session

ます必要なライブラリ・モジュールをインストール。passportは手軽にSNS認証を実装できるのですが、各サービスごとのモジュールが必要です。

## Twitter Appsに登録
認証にはkeyとaccess tokenが必要なので[ここ](https://apps.twitter.com/)から登録します。開発用であれば、URLとcallback URLに http://localhost:8000 などと書きたいところですが、これだと弾かれます。http://127.0.0.1:8000/ と書きましょう。その後、ローカルで認証を試すときは、localhostではなく、127.0.0.1を使うようにしてください。私は前者でやっていたらエラーが出続けて苦しみました。

### Additional Permissions
アプリケーションを登録したら、Permissionタブをクリックし、Additional Permissionsのリクエストを送りましょう。その際、Privacy Policy URLとTerms of Service URLを設定しておく必要がありますが、これはURL先の中身は精査されません（おそらく）。僕の場合はすぐにリクエストが承認されました。

## コード
準備が出来たら実装していきましょう。コードの解説は特にしません。

```app.js
// モジュールを読み込む
var session = require('express-session');
var passport = require('passport');
var TwitterStrategy = require('passport-twitter').Strategy;

// セッションへの保存と読み出し
passport.serializeUser(function (user, done) {
  done(null, user);
});

passport.deserializeUser(function (obj, done) {
  done(null, obj);
});

// 認証の設定
passport.use(new TwitterStrategy({
  consumerKey: info.TWITTER_API_KEY,
  consumerSecret: info.TWITTER_API_SECRET,
  callbackURL: "http://127.0.0.1:8000/auth/twitter/callback",
  includeEmail: true // これ大事！これがないとEmailは出力されない！
},
// 認証後のアクション
function(accessToken, refreshToken, profile, done){
  process.nextTick(function(){
    console.log(profile); //必要に応じて変更
    return done(null, profile);
  });
}
));

// セッションの設定
app.use(session({
  secret: info.SESSION_SECRET,
  resave: false,
  saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

// 指定のpathで認証
app.get('/auth/twitter',
  passport.authenticate('twitter'));

// callback後の設定
app.get('/auth/twitter/callback',
  passport.authenticate('twitter', {failureRedirect: '/login' }),
  function(req, res) {
    res.redirect('/'); 
  });

```

new TwitterStrategyで "includeEmail: true"とするのが重要です。Githubとか他のサービスで認証を作るときは、サクッとemailが取れるのですが、Twitterでは記載したような面倒な手順が要ります。Twitter Developerでアプリの登録だけでなく、additional requestの申請とincludeEmailをtrueにすること、僕はここで３時間ハマりました。同じような人の参考になれば幸いです。

## 参考
1. [jaredhanson/passport-twitter](https://github.com/jaredhanson/passport-twitter)
2. [Get user email #67](https://github.com/jaredhanson/passport-twitter/issues/67)
3. [Twitter Developer Documentation/GET account/verify_credentials] (https://dev.twitter.com/rest/reference/get/account/verify_credentials)
javascriptのFormDataは、ajaxで飛ばすまで中身を見ることができないっぽい。

javascriptのメソッド、FormDataを使った時に
値が入らない？？？となって困ったのでシェアします。

結果的には**入っていました**。

```javaScript:messages.js
  $('.message_form').on('submit', function(e) {
    e.preventDefault();
    var group_id = $('.group_id').val();

    var fd = new FormData($('.message_form').get(0))
    fd.append('body', $('.form').val())
    // $('.form').val() => "aaa"
    console.log(fd);
    // ここではfdを見ると FormData = {} となり、一見何も入っていないように見える
    $.ajax({
      type: 'POST',
      url: '/groups/' + group_id + '/messages.json',
      data: fd,
      processData: false,
      contentType: false,
      dataType: 'json'
    })
    .done(function(data) {
      console.log(data.body);
      // => "aaa"
      // なのに、ここで見るとfd.appendの部分で入れたbodyを見ることができる。
      data.name = $('.current_user_name').val();
      $('div.right__content').append(build_message(data));
      textField.val('');
    })
    .fail(function(data) {
      alert('送信に失敗しました。');
    });
  });
```
Oracle JDKをインストールしたDockerイメージを作る（yum

環境

```bash
# Docker for Mac
$ docker -v
Docker version 1.13.0, build 49bf474
```

---

JDKが置いてあるURLの形式が昔から変わっていたので、URL自体とファイル名をパラメータとして渡せるようにした。
それ以外は、ライセンス同意のCookieを付けているくらい。

```
http://download.oracle.com/otn-pub/java/jdk/{8u121-b13:version}/{e9e7ea248e2c4826b92b3f075a80e441:ランダムっぽい文字列}/{jdk-8u121-linux-x64.rpm:ファイル名}
```

URLとファイル名はOracleのダウンロードページでライセンスに同意して取得。

<img width="907" alt="スクリーンショット 2017-02-04 18.50.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/51910/b4b38815-3e06-9b0d-e4f2-0466efe6f9de.png">



```bash:Dockerfile
FROM amazonlinux

ARG jdk_url
ARG jdk_rpm_name

RUN \
  yum install -y wget findutils which

RUN \
  wget -q \
    --no-check-certificate \
    --no-cookies \
    --header "Cookie: oraclelicense=accept-securebackup-cookie" \
    ${jdk_url}

RUN \
  rpm -ivh ${jdk_rpm_name}
```

ビルド

```bash
$ docker build . --build-arg jdk_url=http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-x64.rpm --build-arg jdk_rpm_name=jdk-8u121-linux-x64.rpm
```

`--build-arg`は指定するパラメータ分必要なことに地味にハマった。

### 参考

- http://d.hatena.ne.jp/Kazuhira/20150905/1441426361
- https://docs.docker.com/engine/reference/builder/#arg
docker のコンテナを名前指定してまとめて削除する

docker を勉強しはじめてすぐのぼくは、image を作ったり消したり、container を作ったり消したりします。

そして、気づいたら、用もないコンテナの残骸が溜まっていました。:kissing:

（こんなことはめったに起こることじゃないかもしれないのですが。...）

`docker ps -a` で、コンテナ一覧を出すと以下のようになっていました。

![スクリーンショット 2017-02-04 18.30.54.png](https://qiita-image-store.s3.amazonaws.com/0/45822/e5d960c6-e2f3-5f60-8d93-e3b7d852abd8.png)

このコンテナのうち、NAMES のプレフィックスが dockerstudy_ のものだけまとめて削除したくなりました。

`--filter` を使います。以下のように絞り込めます。

```zsh
$ docker ps -a --filter name=dockerstudy_
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
5c8a1e50795d        08cd3696b3ea        "rails s"                28 minutes ago      Exited (1) 28 minutes ago                          dockerstudy_web_run_7
1ba5d18092a1        08cd3696b3ea        "rails db:create"        29 minutes ago      Exited (0) 29 minutes ago                          dockerstudy_web_run_6
a65e6d3bf762        08cd3696b3ea        "bundle exec rails..."   29 minutes ago      Exited (1) 29 minutes ago                          dockerstudy_web_run_5
e98a77eba0b8        08cd3696b3ea        "rails db:create"        About an hour ago   Exited (0) About an hour ago                       dockerstudy_web_run_4
7b6d813ff696        08cd3696b3ea        "bundle exec rails..."   About an hour ago   Exited (1) 30 minutes ago                          dockerstudy_web_1
8b7e95531148        dff0928dc81a        "rails db:create"        About an hour ago   Exited (1) About an hour ago                       dockerstudy_web_run_3
d5f4b576a22e        6049a99885c0        "rails db:create"        About an hour ago   Exited (7) About an hour ago                       dockerstudy_web_run_2
d749860ac076        6049a99885c0        "rails new . --for..."   About an hour ago   Exited (0) About an hour ago                       dockerstudy_web_run_1
c28f1ce26c08        postgres            "/docker-entrypoin..."   About an hour ago   Exited (0) 26 minutes ago                          dockerstudy_db_1
```

よって、`-q` を用いて、以下のコマンドで満たされました。


```zsh:name指定でまとめて削除
$ docker rm `docker ps -aq --filter name=dockerstudy_`
```


以上、ありがとうございました。:slight_smile:
Gradleの設定フェーズと実行フェーズについて

Gradleでのビルドは、初期化、設定、実行の３つのフェーズに分けられ、その順にビルドが行われる。

※詳細はドキュメントを参照してほしい。
http://gradle.monochromeroad.com/docs/userguide/build_lifecycle.html

特に設定フェーズと実行フェーズは混同しやすいが、
その区別を意識しないと、自分で書いたbuild.gradleの設定が意図したとおりに動かなかったりする。


## 例
build.gradleに下記ののように記述し、`gradle myTask`を実行したら、どのように出力されるだろうか。

```
println name + ": " + "FIRST"

task myTask {
  println name + ": " + "First"

  doFirst {
    println name + ": " + "doFirst block"
  }
  doLast {
    println name + ": " + "doLast block"
  }

  println name + ": " + "Last"
}

println name + ": " + "LAST"

```

結果は以下の通り。

```
gradle-test2: FIRST
myTask: First
myTask: Last
gradle-test2: LAST
:myTask
myTask: doFirst block
myTask: doLast block

BUILD SUCCESSFUL
```

## なぜか
上記の例では、doFirst、doLastは実行フェーズで評価され、それ以外は設定フェーズで評価されたため。
別のTaskの記述方法である`myTask << {}`はdoLastと同等だが、gradle3.3の環境では将来的に廃止予定という警告がでる。
Unityエンジニアが3DプリントでiPhoneゲームをボードゲーム化してみる

#はじめに

年末年始に「DORASURE（ドラスレ）」や「枯山水」というボードゲームで遊んでいました。
普段デジタルなゲームで遊んでいる自身にとって、アナログゲームというものは、とても新鮮で、普段iPhone上で動かしているゲームたちもボードゲームにしたら面白そうだなと思いました。
....ということで、今回は自作の戦車ゲーム(アプリ）のボードゲーム化に挑戦です！

#そうだ3Dプリントしてみよう！
ボードゲームってやっぱり重要なのは、駒！
DORASURE(ドラスレ)も重量感あるメタルフィギュアが、枯山水も庭石をリアルに表現したフィギュアがいい味出してるんですよね。
で、ゲーム内でも普段3Dのデータ扱ってるんだから、そのままプリントできるんじゃね？ということで、初めての3Dプリントに挑戦です。
...と、この時は、後にいくつか苦労することになるとは思ってもみませんでした...(笑)

#3Dプリントのサービスは？
DMMの3Dプリントサービスを使いました。
http://make.dmm.com/print/

#どうやって納品するのか？
ここが最初の難関だったわけですが、どうやら納品にはSTLという拡張子が使われているとのこと。
https://ja.wikipedia.org/wiki/Standard_Triangulated_Language
主な3Dモデリングソフトであれば、書き出しにSTLを指定するだけで楽々に書き出しすることができます。

#GithubでSTLをレンダリングできるっぽい
全く知らなかったのですが、GithubはSTLデータに対応していて、モデリングデータを回転させてレンダリングすることができます。バージョン管理として、githubにuploadすると便利ですね。(下記は今回作ったデータ)![github-screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/43766/be5ce401-276d-8ffc-1615-3ba4185e4877.png)

https://github.com/oggata/3d_data_demo/blob/master/tankdata.STL

#うう、、、データ不備による受注キャンセル
DMMプリントへのデータのアップロードはブログに写真を貼り付けるようにとても簡単。アップロード後にデータの判定が走ってデータ不備がなければそのまま決済となり注文ができるようになります。今回は、最初のデータ判定ではOKだったのですが、翌日、データ不備により、注文確定後にキャンセル通知が飛んできました。

##不備1:厚みが小さい箇所が複数あり造形できません。(石膏フルカラーの厚みは2mm程度必要です。)
あまりにも細かいモデリング箇所は造形できないとのこと。足回りなどだいぶ細く作っていたのですが、泣く泣くモデリングを変更することになりました。。
全体的にだいぶぽっちゃり(デフォルメ）化することになりました(泣)
![tank-beforeafter.png](https://qiita-image-store.s3.amazonaws.com/0/43766/10f239c0-60a9-5e81-56be-0319af9c9a3f.png)

##不備2:データにエラー（面が裏返っている）が有るため造形が出来ません
モデリングソフトで左右反転している部分についての指摘でした。あまり詳しくないのでよく分からなかったのですが、とにかくXYZ軸に対して反転したポリンゴンデータを使用した箇所がダメなようでしたので、反転箇所については作り直しました。(使用するソフトによっては大丈夫なのかもしれません。)

#データ修正後、見積もり金額が増加？
どうやら、不備1を修正するために、いくつか穴が空いていたところを塞ぐなど、もろもろ修正をした影響で
全体の体積が増えていたようです。中を空洞にするなどの措置をとればよさそうですが、今回は面倒だったので、そのままで注文をかけました。

After
X：16.0432mm x Y： 40.4472mm x Z： 18.1271mm
7056.81mm3

Before
X：15.8207mm x Y： 38.3855mm x Z： 18.8939mm
742.434mm3

#注文
3Dデータのアップロードに成功すると、あとは素材などを選ぶことができます。
石膏以外はめちゃ高いので、石膏の1択に。
![スクリーンショット 2017-02-02 16.31.28.png](https://qiita-image-store.s3.amazonaws.com/0/43766/8c60b7d5-b950-774c-b504-190aab4b362d.png)

#出来上がってきた！
素材によっては1か月近くかかるものもありそうでしたが、石膏の場合は、わずか2~7日程度完成となります。
![tankimage.jpg](https://qiita-image-store.s3.amazonaws.com/0/43766/a31f5b4d-9911-eeda-757d-b9195ae9828e.jpeg)

#いよいよボードゲーム化
簡易的なボードの作成と、着色をして、ボードゲーム化しました。
![Image uploaded from iOS-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/43766/af6eda0e-cb2f-0129-26e9-48224c070098.jpeg)

#おしまい
データの不備などはありつつも、思っていたよりも簡単に3Dプリントを試すことができました。
そして、自分がモデリングしたデータが実際に手に取れるという感動は、最初にゲームをプログラムで動かした時に近いものがあります。
ぜひ、ゲーム制作に関わってるみなさんも、たまにはモニタから離れて、ワイワイとアナログゲームをやるのも良いのでは？
ということで今回の記事はおしまいです^^。

#参考
3DデータとSTL ～3Dプリンタ使用の大前提～
http://3d-printer.stratasys.co.jp/jpn/lab_value11/

ぞくぞく登場！3Dプリンター用データ共有サイトがアツい
https://matome.naver.jp/odai/2137545703957098101
Angular2でhtmlにstyle属性を埋め込む方法

#備忘録として残しておきます
##こんな感じのHTMLを
```html:test.html
<div class="img-responsive" style="{'background-image': 'url('test/img.png')'}">
</div>
```

##angular2で書く場合は下記のように書けば同じことを実現できる。

```html:test.html
<div class="img-responsive" [ngStyle]="{'background-image': 'url(' + test.img  + ')'}">
</div>
```
###```test.img```の部分はangular2のmodelの値を入れればいい。
Rustで外部コマンド実行

一行ずつであれば stdout を read_line して stdin に write するコードを書けば良いけど、シェルスクリプトみたいにその辺を気にしたくなければ unsafe を使ってつなげることができる。

```rust
use std::process::{Child, Command, Stdio};
use std::os::unix::io::{AsRawFd, FromRawFd};

fn stdout_to_stdin(process: &Child) -> Option<Stdio> {
  if let Some(ref stdout) = process.stdout {
    return Some(unsafe { Stdio::from_raw_fd(stdout.as_raw_fd()) });
  }
  None
}

fn main() {
  let mut process1 = Command::new("bash")
      .arg("-c")
      .arg("while (( i < 100 )); do echo $((i+=1)); done")
      .stdout(Stdio::piped())
      .spawn().expect("failed to run");
  let mut process2 = Command::new("grep")
      .arg("1")
      .stdin(stdout_to_stdin(&process1).expect("broken pipe"))
      .spawn().expect("failed to run");
  process1.wait();
  process2.wait();
}
```
メモ: DBでrollbackしてもauto_incrementが戻らない理由

## 背景

Rspecでテストを書いていて、sqliteで通っていたがMySQLにすると通らない
エラーを見てみるとidを指定してDBから値を取って来ている処理で、データがが無いと怒られている
テストとして、auto_increment指定しているidが1に戻っている事を期待しているが、戻っていない
しっかりとそこを考えた事がなかったが、ググってみると以下の内容がしっくり来たのでメモとして残す

> もしシーケンスがロールバックされうるとしたら、シーケンスを使ってINSERTしているトランザクションが実行中だった場合、それが終了するまではシーケンスが次に何の数字を吐き出すか確定できません。すると、他のトランザクションが単に連番を生成するためだけにブロックされてしまうのです。
RDBの世界で主キーに期待されていることはユニークなことだけであり、連続であることは期待されていません（どうせDELETEで抜け番が発生しますから）。期待されてもいない連続性のためにブロックが発生するのはあり得ないというのがRDB製品共通の解釈だというわけです。
> http://cs.hatenablog.jp/entry/2014/03/14/103358

## あとがき

こうやって理解しやすい文章にしてもらって、読んでみるとそりゃそうだと腹落ちした
auto_incrementな値は勝手に連番になっている、という思い込みは非常に恐ろしい
なので、思い込みはなるべく捨てたい
Packer で作る<br />インフラのCI環境

第25回【フリースタイル】PORTもくもく会 の資料

https://freestyle-mokumoku.connpass.com/event/49338/

---

## 自己紹介

名前: sinsoku
会社: 株式会社grooves
できる: Ruby, Rails :heart: 
できない: Clojure :cry:
github: [sinsoku](https://github.com/sinsoku)
twitter: [@sinsoku_listy](https://twitter.com/sinsoku_listy)

---

https://jobs.forkwell.com/

![jobs.png](https://qiita-image-store.s3.amazonaws.com/0/30459/256462b2-6e92-721d-5dcb-f6deca2499cc.png)

---

https://jobs.forkwell.com/about/scout

![Forkwell_Scout_001.jpg](https://qiita-image-store.s3.amazonaws.com/0/30459/63c6eff2-8dc9-5f43-5f0c-d660fc100d28.jpeg)

---

## 宣伝おわり

---

## Packer 知ってます？

---

## Packer by HashiCorp

- Vagrant の会社
- json からイメージを作成できる
  - AMI
  - Docker container
  - VirtualBox

---

## こんな感じ

![packer.png](https://qiita-image-store.s3.amazonaws.com/0/30459/93079460-994a-70e0-5345-fbe1cb043b90.png)

---

## 実例の紹介

---

## Git on AWS Lambda

- Lambda と同じ AMI でビルド
  - [amzn-ami-hvm-2016.03.3.x86_64-gp2](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/current-supported-versions.html)
  - インストール先を /tmp にする
- ビルドしたディレクトリを圧縮
- Lambda 実行時に /tmp に解凍

---

## template.json

- builders
  - docker
  - amazon-ebs
- provisioners
  - **ansible**
  - file(amazon-ebs)
- post-processors
  - docker-tag(docker)

---

## スクリプト

```bash:bin/ci.sh
#!/bin/bash
set -ev

if [[ "${TRAVIS_BRANCH}" = "master" || -n "${TRAVIS_TAG}" ]]; then
  packer build template.json
else
  packer build -only=docker template.json
fi
```

---

## ブランチと実行される処理

![branches.png](https://qiita-image-store.s3.amazonaws.com/0/30459/0eb05f93-e40e-6278-573d-954422f53473.png)

---

## まとめ

- プロビジョニングのテストが可能
- CI できる
- README は少ないけど OSS です
  - [aws-lambda-bins/git](https://github.com/aws-lambda-bins/git)
- master へのマージは約10円
  - m3.medium($0.096/h)

---

# ご清聴ありがとうございました
javascriptのcoffeescript、cssとscssの変換ならこのサービスで

# javascript <--> coffeescript、css <--> scssの変換はツールを使おう

## javascript <--> coffeescript

js2coffeeというサービスがオススメ
http://js2.coffee/

<img width="1224" alt="スクリーンショット 2017-02-04 18.13.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/163591/9b46d205-1a3f-589c-c564-97535df61989.png">

## css <--> scss

css2sassというサービスがオススメ
http://css2sass.herokuapp.com/

<img width="1438" alt="スクリーンショット 2017-02-04 18.17.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/163591/8aae41de-c3a7-9586-2d4a-b2e61e61738a.png">
技術英語 > first, second, and so on [down to the last]. / to the bitter end

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 1100 / 12833)

> Most computer languages can represent a sequence of items indexed by their integer position: first, second, and so on **<font color=red>down to the last</font>**.

http://eow.alc.co.jp/search?q=down+to

<hr>
http://qiita.com/7of9/items/c96eda06447e283ca2eb

> Down to the millisecond, if possible.

技術英語として始めた記事の最初の投稿。

<hr>
関連して思い出したのは

http://ejje.weblio.jp/content/to+the+bitter+end
> to the bitter end

> 《口語》 (不快・困難にもかかわらず)あくまで; 死ぬまで.


MaxIntを使うと配列の「最後まで」というルールがあるが、ソースリーディング時に「？」になりそうで使いたくない。
http://qiita.com/7of9/items/049a9970653505151148