OmniAICreator/Qiita-1.07M huggingface dataset:
iOSアプリのライセンス一覧のplistを半自動生成して設定画面にキレイに表示するプログラムをGo言語で作った

## 【追記】Swift版の [mono0926/LicensePlist](https://github.com/mono0926/LicensePlist) を作ったのでそちらがオススメです

以下、 [mono0926/ios-license-generator](https://github.com/mono0926/ios-license-generator) の紹介記事ですが、Swiftで作り直した [mono0926/LicensePlist](https://github.com/mono0926/LicensePlist) を使うことをオススメします。
移植ではなく、手法自体がらりと変えました。
(生成物の形式はほぼ一緒です。)

---

しばらく前ですが、[今開発中のPlayer!](https://itunes.apple.com/jp/app/id897872395)向けに、このようなキレイなライセンス一覧を半自動生成するプログラムをGo言語で書きました。
もちろんすでに何かやり方無いか調べたのですが、やりたいことを満たすものが見つからなかったので。

![ライセンス一覧・詳細](https://qiita-image-store.s3.amazonaws.com/0/19398/fc16825d-393e-6a88-c389-9ca31241f187.png)



## プログラムの置き場所など

- レポジトリ: [mono0926/ios-license-generator](https://github.com/mono0926/ios-license-generator)
- `go get -u github.com/mono0926/ios-license-generator` でインストール出来ます。
    - あるいは、[Releases · mono0926/ios-license-generator](https://github.com/mono0926/ios-license-generator/releases)からダウンロードしてください。

Go言語、実行ファイル作るの簡単で良いですねと改めて思いました。
plistのtemplateファイルも go-bindataを使って簡単に同梱出来ちゃいました。
参考: [go-bindata でコンパイル時にリソースを埋め込んじゃおう！ - Qiita](http://qiita.com/ikawaha/items/c02d84cfd00f8f442500)


Goのプログラム自体は初心者レベルなので、お手柔らかにお願いします(　´･‿･｀)

## 他のやり方の問題点

### カスタムで画面作る方法

これは、初めに画面組むのもその後のメンテナンスもけっこう手間なので、避けたかったです。

### CocoaPodsでライセンス表記を自動生成

これはけっこう有名な方法なので、やっている人多いと思います。

- [iOS - ライセンス表記の自動作成 - Qiita](http://qiita.com/mox2/items/545f1d39e4829907ac42)
- [CocoaPodsでライセンス表記を自動で作成する - jubilee](http://mzgk.github.io/blog/2014/cocoapods-license-auto-make/)

以下の問題があって選択肢から外れました。

- CocoaPods以外で導入しているライブラリに対応できない(ですよね？？)
    - Carthage経由
    - 何らかの事情でソースそのまま追加したり、Git Submoduleで導入している場合など
- あまりキレイじゃない
    - 全てのライセンスが単一のplistとして出力されて、ライセンス一覧としてキレイじゃない

## 今回やった方法

「CocoaPods以外で導入しているライブラリに対応」するためには、別途簡単なリストで管理しているライセンス一覧をソースにするしか無さそう、という判断の下、以下のような仕組みにしました。

- Markdownで簡単なライセンス一覧を記述
- プログラムでそれをパースして、ライセンス文章をダウンロードしてきて、Settings.bundle(設定アプリ内に表示するやつ)形式のplistとして出力
    - CocoaPodsからの自動生成と違って、冒頭に貼ったスクリーンショットのようにテーブルビュー + 詳細という構成

## 使い方

### ライセンス一覧のMarkdownファイルを用意

こんなファイルを用意します。(テキストで貼ってもちゃんと表示されないのでスクリーンショット)
多少ですが、面倒ではあります(　´･‿･｀)
一応OSS使うマナーとして、ライセンスなど確認した上で導入するはずなので、そのついでにやれば許容範囲じゃないでしょうか。

![Screen Shot 2015-06-29 at 4.05.58 PM.png](https://qiita-image-store.s3.amazonaws.com/0/19398/1de2ad77-1965-a8cd-8baa-9f8c5b82b1ff.png)

外部参照リンク形式で記述し、末尾のものがプログラムでパースする対象となります。
[`ライブラリ名`]:`ライセンスURL` となっているのが肝です(　´･‿･｀)

### プログラム実行

以下のコマンドで、`output_dir`にライセンスのplistファイル群が出力されます。

```
ios-license-generator generate [License.md] [output_dir] 
```

- 一覧: `LicenseList.plist`
- ライセンス詳細: `ライブラリ名.plist`
    - こちらはライブラリの数だけ生成されます

### iOSアプリソースに配置

`Settings.bundle`が無い場合は適当に用意してください。
そして、生成されたファイル群をSettings.bundleに放り込みます。
(上述の`[output_dir]`で直接指定すればこの手順不要です。)

初回のみ、以下の手順も必要です。

`Root.plist`に以下を追加してください。

```xml
<dict>
	<key>Type</key>
	<string>PSChildPaneSpecifier</string>
	<key>Title</key>
	<string>License</string>
	<key>File</key>
	<string>LicenseList</string>
</dict>
```

国際化必要な場合、`Root.strings`に以下を追加してください。

```
"License" = "ライセンス情報";
```
MacでGLUT+OGL＃3

 
記述の動機
GLUT+OGLがMacではサクッと環境構築できることを知りました。
使わない手はないので、少しづつまとめていきます。
今回はGL_LINE_LOOPによる直線描画です。

``` 03.cpp
#include <GLUT/glut.h>

#define WIDTH 640
#define HEIGHT 480

void display(void)
{
	double pointx = 0.8;
	double pointy = 0.8;

	glClear(GL_COLOR_BUFFER_BIT);
	//LINE START
	glBegin(GL_LINE_LOOP);
	glVertex2d(-1 * pointx, -1 * pointy);
	glVertex2d(pointx, -1 * pointy);
	glVertex2d(pointx, pointy);
	glVertex2d(-1 * pointx, pointy);	
	glEnd();
	//LINE END
	glFlush();
}

void init(void)
{
	glClearColor(0.0, 0.0, 0.0, 1.0);
}

int main(int argc, char *argv[])
{
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(WIDTH, HEIGHT);
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA);
	glutCreateWindow("GLUT+OGL Sample");
	glutDisplayFunc(display);
	init();
	glutMainLoop();
	return 0;
}
```

```コンパイルコマンド
g++ -o 03.out 03.cpp -framework GLUT -framework OpenGL
```
点の描画。簡単ですね。
![スクリーンショット 2015-06-30 2.24.32.png](https://qiita-image-store.s3.amazonaws.com/0/33317/ed0b4724-fee7-373f-f4fd-1b33bd78d24d.png "スクリーンショット 2015-06-30 2.24.32.png")
AngularJSの1.3.0以降の ng-true-value 利用時の注意

checkbox で使用する ng-true-value が 1.2.8 までは以下でOKだったが・・・

```js:1.2.8
<input type="checkbox" ng-model="status.complete" ng-true-value="yes" ng-false-value="no"/>
```

1.3.0 以降は、以下のように値をシングルコーテーションで囲わないとエラーになるので要注意。

```js:1.3.0
<input type="checkbox" ng-model="status.complete" ng-true-value="'yes'" ng-false-value="'no'"/>
```
Circle CIのdependenciesの設定ではまったこと(反省を込めて)

しょうもないミスだったので反省を込めてメモ。

#現象
Circle CIでなぜかbuild toolがないよ、と怒られるエラーが発生していました。

```yaml:こんなかんじのエラーメッセージ

pendencies ':modules:cl2/12 projects> Building 0% > :app:preBuildmodules:Aviary-SDK:compileLint:app:preBuild
> Building 0%:modules:Aviary-SDK:compileLint
> Building 0% > :modules:Aviary-SDK:copyReleaseLint:modules:Aviary-SDK:copyReleaseLint 
> Building 0%UP-TO-DATE
> Building 0%
> Building 0%1% > :modules:Aviary-SDK:mergeReleaseProguardFiles:modules:Aviary-SDK:mergeReleaseProguardFiles
> Building 1%2% > :modules:Aviary-SDK:preBuild:modules:Aviary-SDK:preBuild 
> Building 2%FAILED
> Building 2%
> Building 2%3%4%
> Building 4%FAILURE: 
> Building 4%Build failed with an exception.
> Building 4%
> Building 4%
> Building 4%* What went wrong:
> Building 4%Execution failed for task ':app:preBuild'.
> Building 4%> 
> Building 4%failed to find Build Tools revision 21.1.1
```

circle.ymlは以下のように設定していました。

```yaml:circle.yml

dependencies:
  override:
  - echo y | android update sdk --no-ui --filter "android-22,build-tools-21.1.1,extra-google-m2repository,extra-android-m2repository"
```

特にマズい所はなさそうなので、何か追加で設定が必要なのかと思い、カスタマーサポートに連絡するも、有意義な返答は得られず、エラーは出たままで、途方に暮れてしまいました。

#解決策

dependencies設定時のダブルクォートが不要でした。
Circle CIの実行結果をたどっていくと、`android update sdk`コマンドで、**Successになっているのに、以下のようなメッセージが出ていました。**

```
echo y | android update sdk --no-ui --filter "android-22,build-tools-21.1.1,extra-google-m2repository,extra-android-m2repository"
Refresh Sources:
  Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml
  (中略)
Error: Ignoring unknown package filter 'android-22'
Error: Ignoring unknown package filter 'build-tools-21.1.1'
Error: Ignoring unknown package filter 'extra-google-m2repository'
Error: Ignoring unknown package filter 'extra-android-m2repository'
Warning: The package filter removed all packages. There is nothing to install.
```

sdk updateできてないやないかーい

で、結局以下のようにしたらちゃんとbuild通りましたとさ。

```yaml:circle.yml

dependencies:
  override:
dependencies:
  override:
  - echo y | android update sdk --no-ui --all --filter extra-google-m2repository,extra-android-m2repository,build-tools-21.1.1
```
httpsからhttpへリファラーを渡す方法

リファラーを使って、ちょっとした処理を追加しようと思ったら、
httpsからhttpへはリファラーを渡せない
> [15.1.3 Encoding Sensitive Information in URI's](https://www.ietf.org/rfc/rfc2616.txt)。

そこで、HTMLのmetaで下記を指定すると、

`<meta name="referrer" content="unsafe-url">`

うまく言った。

[参考文献A](http://web-tan.forum.impressrd.jp/e/2015/04/14/19750)

でも、最新のブラウザ（Chrome、FF）しか対応していない。
（safariもダメでした）By 2015/06/30

なので、汎用的な方法として、
海外文献より、リダイレクトを使用してリファラーを渡す方法も合わせて載せておきます。

[参考文献B](http://webmasters.stackexchange.com/questions/47405/how-can-i-pass-referrer-header-from-my-https-domain-to-http-domains)
> I was able to set up a link from an HTTPS page to a HTTP page on another domain and still pass the first page's URL as a referrer using the following technique.
setFullScreenIntentを使っていてIntentが勝手に起動する

Heads Up Notificationを出すために、Notification.Builder#setFullScreenIntentしていて、
出てきたHeads Up Notificationを上フリックして消してから
Notification開いて起動して、もう一度同じNotificationを出すと
Intentが勝手に起動する現象が起きるようです。(コード読めばどうなっているのか分かりそうですが、時間があったら調べます)

Android 5.0では再現しませんでしたが
5.1やAndroid M Previewでは再現しました。
こういう点を注意して実装する必要がありそうです。

![fullscreenintent5.1.0.gif](https://qiita-image-store.s3.amazonaws.com/0/27388/a5625765-95f6-ce8f-a0b5-fec088e2ab00.gif)

```
        final Intent intent = new Intent(this, SubActivity.class);
        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        final Notification notification = new NotificationCompat
                .Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("title")
                .setContentText("text")
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .setFullScreenIntent(pendingIntent, true)
                .build();
        final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(10, notification);
```

再現したプロジェクト
https://github.com/takahirom/setFullScreenIntentBehavior/blob/master/app/src/main/java/com/kogitune/setfullscreenintentbehavior/MainActivity.java#L32

Android Developersにも

    On some platforms, the system UI may choose to display a heads-up notification, instead of launching this intent, while the user is using the device.

と書いてあるので、起動してしまうことは考慮に入れたほうが良いのかもしれません
http://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setFullScreenIntent(android.app.PendingIntent, boolean)
StoryBoardのViewControllerをインスタンス化する




```swift:swift

let mainVC = MainViewController()
```

上記の記載では、ストーリーボードで定義したボタンなどの配置まで紐付けることができないので、下記のようにストーリーボードをインスタンス化させる。


1. Storyboard上で、ViewControllerを定義する
<img src="https://qiita-image-store.s3.amazonaws.com/0/59560/821419f7-94c5-cb5e-6363-77707697e0b2.png" width=350> 

2. Storyboard上で、ViewControllerのStoryboardIDを定義する
<img src="https://qiita-image-store.s3.amazonaws.com/0/59560/95c03dc1-6f40-3cb1-13da-791cb433eaf4.png" width=350> 

3. 呼び出したいクラスで下記のコードを実行する

```swift:swift

var storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyboard.instantiateViewControllerWithIdentifier("MainViewController") as! MainViewController
```
Android: SQLiteインサート高速化で、パフォーマンスのイライラを解消する

# AndroidのSQLiteでバルクインサートする方法です。


## 普通にインサートする時

````java:通常のインサート処理
DatabaseHelper dbHelper = new DataBaseHelper();
SQLiteDatabase db = new dbHelper.getWritableDatabase();

//インサートするデータのArrayList
List<ContentValues> valueList = new ArrayList<ContentValues>();

//データ作成
ContentValues values = new ContentValues();
values.put("Name", "hoge");
values.put("Tel", "0000-1234-5678");
values.put("Age", 24);
valueList.add(values);
values = new ContentValues();
values.put("Name", "fuga");
values.put("Tel", "0000-1234-5678");
values.put("Age", 30);
valueList.add(values);

for (ContentValues val : valueList) {
    long ret = db.insert("MyTable", null, val);  
    if (ret < 0) {
        Log.d("ログのタグ", "インサート失敗！！！！！");
    }
}
db.close();

```

このようにArrayListをLoopで回して1件ずつインサートすると、SQLiteは1件ずつインサートするごとに
トランザクションのコミットを行います。
少量のデータのインサートなら1件ずつトランザクションコミットが走ることは気になりませんが、
大量データとなると、コミットのコストはバカになりません。
そこで、データを全部インサートしたあとに、コミットを行うことで、トランザクションコミットのコストを最小限にすることができます。

## バルクインサートする時

```java:バルクインサート処理
// トランザクション開始を宣言
db.beginTransaction();
try {
    for (ContentValues val : valueList) {
        long ret = db.insert("MyTable", null, val);  
        if (ret < 0) {
            Log.d("ログのタグ", "インサート失敗！！！！！");
        }
    }
    //トランザクション成功を宣言。
    db.setTransactionSuccessful();

} finally {
    // トランザクション終了
    db.endTransaction();
    db.close();
}



```

このように明示的にトランザクションの開始、成功、終了を宣言することで、トランザクションコミットのタイミングをコントロールすることができます。
`setTransactionSuccessful()`を呼び出すことで、データベースへの変更がコミットされ、呼び出さなければロールバックされます
そのためこの方法には、以下のメリットがあります。

* 高速化
* 途中で失敗した場合ロールバックができる

## パフォーマンス比較
以下のサイトに比較があったので、貼っつけておきます。約2倍ほど高速です。
> http://www.atmarkit.co.jp/ait/articles/0905/20/news111_2.html

![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/15448/8f56418d-5aa6-6df9-65f4-14ba69ea21a9.png)
SwiftでTrailing closure syntaxを使って、splitのisSeparatorを省略する

# splitで文字列を分割
```swift
let num = "one,two,three"
let array = split(num, maxSplit: Int.max, allowEmptySlices: false, isSeparator: { $0 == ","})
let array2 = split(num, isSeparator: { $0 == ","})
```
SwiftではcomponentsSeparatedByStringだけでなく、splitで文字列を分割することができる。

# Trailing closure syntax
またTrailing closure syntaxを使って、isSepalatorを省略することもできる。

```swift
let array3 = split(num, maxSplit: Int.max, allowEmptySlices: false){ $0 == ","} //["one", "two", "three"]
let array4 = split(num){ $0 == ","} //["one", "two", "three"]
```

・参考
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html
OSXキーロガー

なんか作業が捗らないので見える化のためにキーロガーを探してたらよさ気なやつを見つけたので改造．

61503891さんの [Cで作るOSXのキーロガー](http://qiita.com/61503891/items/4ae3ae64b2531b516321) を参考にさせて頂きました．

元のやつだとキー入力がある度に入力キーが出力されてたので10分ごとに押された数をカウントするように修正．
ついでにマウスのクリックもカウント（左クリックだけ）．
最後の10分間が出力されないけど気にしない．

### コード
```c:keylogger.c

// This program is a simple implementation of a key logger for OS X.
// This key loggger requires sudo and outputs key codes and a time stamp to standard output.
//
// build: cc keylogger.c -o keylogger -framework ApplicationServices
// usage: sudo keylogger > keylogger.log
// author: Masayuki Higashino
#include <stdio.h>
#include <time.h>
#include <ApplicationServices/ApplicationServices.h>

#define INTERVAL 600

CGEventRef on_tap(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
    //CGKeyCode key = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
    static int count = 0;
    static int mouse_count = 0;
    static time_t next_time = 0;
    time_t now; time(&now);
    if (next_time == 0) {
        next_time = ((int)now / INTERVAL) * INTERVAL + INTERVAL;
    }

    if (type == kCGEventKeyDown) {
        count++;
    } else {
        mouse_count++;
    }

    if (next_time <= now) {
        printf("%d - %d %d %d\n", (int)next_time - INTERVAL, (int)next_time, count, mouse_count); fflush(stdout);
        next_time = ((int)now / INTERVAL) * INTERVAL + INTERVAL;
        count = 0;
        mouse_count = 0;
    }
    return event;
}

int main(int argc, const char * argv[]) {
    CGEventFlags flags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
    //CGEventMask mask = CGEventMaskBit(kCGEventKeyDown);
    CGEventMask mask = CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventLeftMouseDown);
    CFMachPortRef tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, mask, on_tap, &flags);
    if (!tap) {
        fprintf(stderr, "This program requires sudo.");
        return -1;
    }
    CFRunLoopSourceRef runloop = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runloop, kCFRunLoopCommonModes);
    CGEventTapEnable(tap, true);
    CFRunLoopRun();
    return 0;
}
```

### コンパイル

```
$ cc keylogger.c -o keylogger -framework ApplicationServices
```

### 実行

```
$ sudo keylogger > keylogger.log
```

### 実行結果


```
1435589400 - 1435590000 443 18
1435590000 - 1435590600 473 31
```
\# 開始時刻 - 終了時刻 キー入力数 マウス左クリック数
ランタイム時にSSEのサポート情報を確認しとく

```cpp:main.cpp
#include <stdio.h>
#include <string.h>

#if defined(_MSC_VER)
#include <intrin.h>
#define CALL_CPUID( dst, paramID ) __cpuidex( dst, paramID, 0 )
#else
#define CALL_CPUID( dst, paramID ) XXX::cpuid( dst, paramID )
namespace XXX
{
    void cpuid( int dst[4], int paramID )
    {
        __asm__ __volatile__
        (
         "cpuid"
         : "=a" (dst[0]), "=b" (dst[1]), "=c" (dst[2]), "=d" (dst[3])
         : "a" (paramID), "c" (0)
        );
    }
}
#endif

int main()
{
    int cpuInfo[4];
    CALL_CPUID( cpuInfo, 0 );
    const int highestValidInfoID = cpuInfo[0];

	int info1_ECX = 0;
	int info1_EDX = 0;
	int info7_EBX = 0;
 
    if( highestValidInfoID >= 1 )
    {
        CALL_CPUID( cpuInfo, 1 );
        info1_ECX = cpuInfo[2];
        info1_EDX = cpuInfo[3];
	}
    
    if( highestValidInfoID >= 7 )
    {
        CALL_CPUID( cpuInfo, 7 );
        info7_EBX = cpuInfo[1];
	}
        
    if( (info1_EDX & (1 << 25)) != 0 ) printf( "SSE   supported\n" );
    if( (info1_EDX & (1 << 26)) != 0 ) printf( "SSE2  supported\n" );
    if( (info1_ECX & (1 <<  0)) != 0 ) printf( "SSE3  supported\n" );
    if( (info1_ECX & (1 << 19)) != 0 ) printf( "SSE41 supported\n" );
    if( (info1_ECX & (1 << 20)) != 0 ) printf( "SSE42 supported\n" );
    if( (info1_ECX & (1 << 28)) != 0 ) printf( "AVX   supported\n" );
    if( (info7_EBX & (1 <<  5)) != 0 ) printf( "AVX2  supported\n" );
}
```

参照：
https://msdn.microsoft.com/ja-jp/library/vstudio/hskdteyh%28v=vs.120%29.aspx
http://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/Processor_Identification_071405_i.pdf
Java Matcherを用いた文字列検索

仕事で便利だなと思ったことを書いていきます。

PatternとMatcherを用いた文字列の検索方法（完全一致）

```java:sample
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Sample {
	public static void main(String[] args) {

		String airlines = "JAL";

		String searchString = "ANA|JAL";
		Pattern pattern = Pattern.compile(searchString);
		Matcher matcher = pattern.matcher(airlines);

		if (matcher.matches()) {
			System.out.println("一致します。");
		} else {
			System.out.println("一致しません。");
		}
	}
}

```

```lang:結果
一致します。
```

文字列検索にはPatternとMatcherを用いれば簡単にできる。
NTP - 2015/7/1 8:59:60 のうるう秒対応について

時間調整のために世界一斉に、2015/6/30 23:59:59(UTC)から2015/7/1 0:00:00(UTC)に切り替わるタイミングで2015/6/30 23:59:60(UTC)が挿入される
これを日本時間に直すと、2015/7/1 8:59:59(UTC+9)から2015/7/1 9:00:00(UTC+9)に切り替わるタイミングで2015/7/1 8:59:60(UTC+9)が挿入される

#### 対応
- ntpdにはSTEPモードとSLEWモードがある
- STEPモードの場合、時間にズレが発生するとすぐに正しい時刻に調整するので時間が逆戻りしてしまう可能性がある
- SLEWモードにするには「ntpd -x」オプションを追加して起動する方法とntp.confに「tinker step 0」を追記して再起動する方法がある
- ntpdのオプションを追加する場合は起動スクリプトを修正しなくてはならないのでntp.confに追記する方法を選択

#### 設定手順
##### 1.「/etc/ntp.conf」の修正

```
tinker step 0
```

##### 2.ntpパッケージの更新

```
sudo apt-get update
sudo apt-get install ntp
```

##### ※参考URL

```
http://makaaso.hatenablog.com/entry/2015/06/29/231653
```
Ansible - ディレクトリ構成について

Ansibleのディレクトリ構成とその用途について纏めてみました  
各rolesについては必要なディレクトリのみ作成するのが良さそうです  

#### 推奨ディレクトリ構成

```
.
┣━ group_vars  # 各グループごとの変数設定用ディレクトリ
┃　　┣━ dbservers   # dbservers用変数ファイル
┃　　┗━ webservers  # webservers用変数ファイル
┃
┣━ host_vars   # 各ホストごとの変数設定用ディレクトリ
┃　　┣━ db01        # db01用変数ファイル
┃　　┣━ web01       # web01用変数ファイル
┃　　┗━ web02       # web02用変数ファイル
┃
┣━ production       # プロダクション用inventoryファイル
┣━ staging          # staging用inventoryファイル
┣━ site.yml         # site全体用playbookファイル
┣━ dbservers.yml    # db用playbookファイル
┣━ webservers.yml   # web用playbookファイル
┃
┗━ roles       # role用格納ディレクトリ
```

#### group_vars/

- グループ毎の変数を定義するのに使います、role ではありませ＃ん、role 毎の変数は roles/{role_name}/vars/ を使います。例えばロケーション毎に異なる変数など。ファイル名はインベントリファイルで設定するグループ名です。インベントリファイルにグループ変数を書くことも可能です

#### host_vars/
- ホスト毎の変数を定義するのに使います。group_vars と同じくファイル名はインベントリファイルに設定したホスト名です。インベントリファイルの中でホスト名の右に並べて書くこともできます

#### sites.yml
- ansible-playbook コマンドに渡す大元 (root) の playbook ファイルです

#### roles/

- 下記参照


#### rolesディレクトリ構成

```
roles  # role用格納ディレクトリ
┃
┣━ .sample  # role用サンプルディレクトリ
┃　　┃
┃　　┣━ defaults        # 変数のデフォルト設定ディレクトリ
┃　　┃　　━ main.yml
┃　　┣━ files           # fileモジュールで使用するファイル格納用ディレクトリ
┃　　┃　　━ init.conf
┃　　┣━ handlers        # ハンドラーtask用ディレクトリ
┃　　┃　　━ main.yml
┃　　┣━ meta            # メタ情報用ディレクトリ
┃　　┃　　━ main.yml
┃　　┣━ tasks           # task用ディレクトリ
┃　　┃　　━ main.yml
┃　　┣━ templates       # テンプレートファイル格納用ディレクトリ
┃　　┃　　━ ntp.conf.j2
┃　　┗━ vars            # 変数用ディレクトリ
┃　　　　　━ main.yml
┃
┣━ <各roleディレクトリ>
：
：
```

#### roles/

- このディレクトリの下に role (役割) 毎のディレクトリを作成し、それぞれの role にさらに files/, handlers/, tasks/, templates/, vars/, defaults/, meta/ というサブディレクトリを作成します (その role で使うもののみ)

#### roles/*/files/

- 当該 role の task で使うファイル関連モジュール (copy) が src として使うファイルの置き場所。任意のファイル名で置きます

#### roles/*/handlers/
- 設定変更後にサービスの再起動をさせたりする場合に、notify という定義で処理を呼び出しますが、その呼び出されるハンドラをここで定義します。main.yml というファイルで作成しますが、include という定義で複数ファイルをそこから読み込ませることが可能です

#### roles/*/tasks/
- 何かをインストールしたり、ユーザーを作成したりする task 定義のファイルをここに置きます。handlers と同じように main.yml というファイルが起点となります

#### roles/*/templates/
- template モジュールで利用するテンプレートファイルを置きます。このモジュールでは Jinja2 (神社) というテンプレートエンジンが使わ>れていて .j2 という拡張子を使います

#### roles/*/vars/
- role 毎に設定する変数を定義するファイルを置きます。handlers や tasks と同じく main.yml ファイルが起点となります

#### roles/*/defaults/
- 当該 role で使う変数の default 値を設定します。他で設定されていなければここで設定した値が使われます。main.yml に書きます。この>変数が一番低い優先度です 「Ansible の変数の優先順」

#### roles/*/meta/
- role の依存設定を書きます。A という role が B という role に依存しているなら roles/A/meta/main.yml に次のように書きます

```
---
dependencies:
  - role: B
    foo: "bar"
```

#### ※参考
http://makaaso.hatenablog.com/entry/2015/06/29/231415
本当にPHPのDoS脆弱性（CVE-2015-4024）キツかった

[PHPのDoS脆弱性(CVE-2015-4024)キツくない？](http://hakaikosen.hateblo.jp/entry/2015/05/30/204358)
[本当にPHPのDoS脆弱性(CVE-2015-4024)キツくない？](http://hatyuki.hatenablog.jp/entry/2015/06/05/152055)


上記のエントリを読み、さらに1ヶ月遅れだけど試してみた。
Macに入っていたPHP 5.5.20で実行。

こんな感じのファイルを用意して、

```text:CVE-2015-4024.txt
--boundary
Content-Disposition: form-data; name="file"; filename=a
--boundary
```

wgetでこう

```
$ wget http://localhost/test.php --header="Content-Type: multipart/form-data; boundary=boundary" --post-file=CVE-2015-4024.txt
```

curlだとこう

```text
$ curl http://localhost/test.php -H "Content-Type: multipart/form-data; boundary=boundary" -F "file=@CVE-2015-4024.txt"
```

ファイルは上記のままだと負荷はかからないので、一部をほむほむしてから実行する。
言及されているように、PHPファイルならなんでも良いので、結構キツいものがある。


以上
DeNAのキャリアコースを上司がバッサリ解説してくれたよ　〜上司がイケメンすぎる件〜

# 要約
上司とこの前キャリアの話をしていて、DeNAだとエンジニアのキャリアコースは４つあるよ、という説明をした。
そうしたら上司が要約してくれた。
DeNAのキャリアパスでは、エンジニアが考えたいものは４つあるとしている

# 私のキャリアパスの見解
何を成したいかは人それぞれだし適性があるので、ITゼネコンみたいなマネージャーになる一本道のキャリアとかどうかとおもうし、かといって技術を極めるというさらにもう一本のキャリアがあります、という以外にも道があって良いのではないかと私は思っていた。

# DeNAのキャリアパスの見解
DeNAの場合、エンジニアのキャリアパスは４つ分かれていて
・サービスリード(企画もする)
・エキスパート(技術特化型)
・マネジメント(マネージメントもする)
・ビジネスリード(経営もする)
がある。
http://next.rikunabi.com/tech/docs/ct_s03600.jsp?p=001684

# 上司の要約
「それってそのエンジニアが考えたいものが「サービス、技術、人、数字」のどれかによって分けているだけでしょ？」
って上司が超要約してくれた。
私はただ「Exactly(ほんとそれ)」としか返せなかった

# 私の結論
エンジニアの好みってこの４つのいずれかなんだろうな、って思った。
なお私の好み的に
(自分でやりたい)　サービス　＞　チーム　＞　数字　＞　技術　(任せられる人に任せたい)

技術に関してそこまで強い興味がないと思いました、まる。
Railsで汚いコード書いてサービス作ってヒットしたら稼いだお金で技術に強い人を雇って任せたいです。
cmder 1.2でgit bashを使う方法とPowershellスクリプトの許可方法

久しぶりにcmderを使おうと思ったら驚かされたので、忘れないうちに備忘録です

# cmder 1.2でpowershellをデフォルトで呼び出すようになった

cmder 1.2が公開されていまして、cmderを普段からお使いの方がバージョンアップした場合、いきなりpowershellが呼ばれて焦るかと思われますが（いないか）、そのような変更があったようです。

github側のリリースを見ると変更したと書かれています。同時に、powershellでなく以前のtask(タブ)を呼び出したい場合はcmdを使ってくれとのこと。

https://github.com/bliker/cmder/releases/tag/v1.2

> Major Changes
> PowerShell is run by default (You can change this back in Settings > Startup > Set to {cmd})

Powershellの変更の理由は未確認でわかりません（githubのissueでDiscussionされていると思います）が、githubで見れるREADMEではtodoにgit bashの対応を予定されているそうです。

以上の話は公式サイトでは確認できなかったのでご注意を。

# メモ:powershellタブを動かしてエラーが起こる場合の対処方法

cmder 1.2をそのまま起動し、powershellのタブが開くと以下のエラーが表示されます。

> . : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Apps\cmder\vendor\profile.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(http://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
> 発生場所 行:1 文字:3
> + . 'C:\Apps\cmder\vendor\conemu-maximus5\..\profile.ps1'
> +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
>     + FullyQualifiedErrorId : UnauthorizedAccess
> PS C:\Users\hiroshi> RestrictedRestricted

これは、powershellのスクリプトを利用した時に現れる（多分有名）なエラーで、Windows側のデフォルトでは、スクリプトの利用出来ない設定となっているようです。

利用できるようにするには、Set-ExecutionPolicyコマンドを利用します。

別途Powershellを管理者権限で起動して下さい。このコマンドでインターネット経由でダウンロードされたスクリプトは署名がないと動かなくて、ローカルに置かれているものは実行可能になります。

    Set-ExecutionPolicy RemoteSigned

参考:http://qiita.com/Fuhduki/items/8d065081d37de387ce4b

その後、cmderを起動させるとこうなりました。

> 警告: Missing git support, install posh-git with 'Install-Module posh-git' and restart cmder.
> C:\Users\hiroshi
> λ

現状はpowershellではgitコマンドは呼び出せず、posh-gitをインストールしろと言われます。実行してみますが、gitが見つからなくてPATH指定しろと言われます。

これ以上やっても余計なことになるので中断しました。powershellがデフォルトになったのでいきなり驚かされましたが、git bashのサポートも予定に入ってるようなのでゆるりと待つことにしています。
nightwatchjsをphantomjsで動かすときにHTTPヘッダーを指定する方法


phantomjsの場合は下のようにHTTPヘッダーを指定する。
複数指定するときは別のキーで登録する。
自分の場合はサーバーの環境によってブラウザの言語が日本語として認識されない問題を解決するためにAccept-Languageを指定した。

その他のcapabilitiesの設定は[Ghost DriverのREADME](https://github.com/detro/ghostdriver#what-extra-webdriver-capabilities-ghostdriver-offers)を参照

```json
"test_settings": {
    "default": {
      "desiredCapabilities": {
        "browserName": "phantomjs",
        "phantomjs.binary.path": "./bin/phantomjs",
        "phantomjs.page.customHeaders.Accept-Language": "ja",
        "phantomjs.page.customHeaders.X-TEST": "test",
      }
    }
  }
```
Gemfile.lock…できない

いまどきのRuby開発には欠かせないBundlerですが、Gemfile.lockの扱いを間違えると面倒なことになります。

# Gemfile.lockの役割
使うべきgemのバージョンを書くのが`Gemfile`ですが、たいていの場合はgemの特定のバージョンまで指定しないので、実際に使うものには変動の余地が生じます。そして、`bundle`を実行すると、`Gemfile.lock`へ、実際に使うこととなるgemのバージョンが書き込まれます。

別のマシンへプロジェクトを移動することになっても、`Gemfile.lock`があれば、全く同じGem環境を容易に再現することができます。

# Gemfile.lockが…ないとき〜
逆に、`Gemfile`だけで`Gemfile.lock`がないと、新規インストールとして作動します。システムインストールで、想定したのより古いgemがすでにあるとうまくインストールできなかったり、逆に勝手に最新版のGemが入って、思わぬバグとなってしまうこともありえます。バージョン管理をする場合、基本的には`Gemfile.lock`を含めたほうがいいでしょう。

# 身動きできなくなったパターン
ただし、ローカル環境がWindows、リモート環境がLinux、というようなシチュエーションでは、バイナリありのgemだと入れるバージョンが異なってきうること、さらには片方だけ入れるgemが発生することもあって、`Gemfile.lock`を共有することができず、それぞれ別個に生成せざるを得なくなってしまっています。

さらに悪いことに、リモートサーバをAWSのElastic Beanstalkで生成していたため、サーバの変動ごとに`Gemfile.lock`が生成されることとなり、`Gemfile`で指定しない場合、gemは常に最新版が呼ばれることとなってしまいました。そして、ちょうど[therubyracerがうまく動かない](https://github.com/cowboyd/therubyracer/issues/341)問題にぶち当たってしまうこととなりました。

リモート用の`Gemfile.lock`を別系統で管理するような仕組みが必要なのは間違いないところですが、どうしたものか検討中です。
Amazon SNS で APNs の証明書を食わせようとするとエラーが出る件について


## 前置き

とあるアプリの APNs Certificates が Expired になっていたので、「うわ、やべ」ってなって更新しようとしたら

> 1 validation error detected: Value null at 'attributes' failed to satisfy constraint: Member must not be null

的なメッセージが出て更新できなかったので、それの解決方法を記す。

## 原因

2015/06/29 現在、`Applications` の一覧画面からチェックボックスにチェック付けて `Actions` &gt; `Update Credentials` だと必ずエラーになるっぽい。

## 対策

チェックボックスの右の方にある ARN のリンクを押下して、詳細画面に入ればアップデートできる。
vimperatorのプラグイン管理を考えてみた



## 導入

皆さんは[vimperator](https://addons.mozilla.org/ja/firefox/addon/vimperator/)使ってますか?vimperatorはfirefoxの拡張機能で、Vim的なキーバインドでブラウザを操作できるだけでなく、プラグインを入れることによって、更に便利に使いこなすことができるようになります。(といっても、プラグインはあまり使ってこなかったのだけれど)


で、プラグインつかってみようかなーと思った時に、VimのNeoBundle的なvimperatorのプラグイン管理プラグインはないんか!ということでいろいろ調べて、ひとまず解決したと思うので書いておきます。

## どうするか

有名どころですが、[vimperator-plugins](https://github.com/vimpr/vimperator-plugins)の[plugin_loader.js](https://github.com/vimpr/vimperator-plugins/blob/master/plugin_loader.js)は、自分でどこかからかダウンロードしてきたプラグインのあるディレクトリを指定し、プラグイン名(jsファイル)を指定することによって`~/.vimperator/plugin/`以下にシンボリックリンクを貼らずともプラグインを有効にすることができます。

```
" set the root dir for loading plugins(you can set multiple directories)
let g:plugin_loader_roots = "~/.path/to/vimperator/plugins,~/path/to/another/plugins"

" specify the plugin you use (you can omit '.js')
let g:plugin_loader_plugins = "plugin1,plugin2"
```

ただ、NeoBundleのように、GitHubのリポジトリを指定するだけでインストールから何までやってくれるわけではないようです。



そこで、[vimppm](https://github.com/cd01/vimppm)というプラグインを使います。

* [Vimperator プラグインマネージャを作ってみた - cd01's blog](http://cd01.hatenablog.jp/entry/2013/10/17/233530)

~~作者さんの説明の通りに`vimppm.js`をダウンロードしてきて、`vimppm`というディレクトリを作り、先ほどの`plugin_loader.js`で管理する方法でもいいのですが、今回は面倒なので`vimppm.js`のソースを書き換えて、ダウンロードしてきたプラグインが直接`plugin`ディレクトリ以下に入るようにします。~~

**(追記:2015/07/04)**

上で言ったような操作は必要ないです。詳しくは下のコメントを参照してください。

**(追記ここまで)**

このプラグインの使い方ですが、先ほどのブログ記事やREADMEを読めば解ると思いますが、`~/.vimperatorrc`に

```vim
source ~/.vimperator/vimppm/vimppm/plugin/vimppm.js " vimppmを置いた場所

vimppm "plugin1.js"
vimppm "plugin2.js"
```

のように書いておき、firefoxを再起動してから`:vimppm install`とすると、ここに指定されたプラグインが`~/.vimperator/vimppm`~~(今回は`~/.vimperator/plugin`)~~内にプラグインがクローン(ソース見る限りはwget)されます。また、`:vimppm update`で最新版に更新することもできます。また、`vimpr/vimperator-plugins`の中のプラグインは、そのプラグイン名だけで指定することができます。このようにすれば、複数マシンを使っていてもvimperatorのプラグインを共有できるので良いですね!また、設定ファイルにどのプラグインを入れているかを直接書くことになるので、後から自分が見た時や、他の人が見た時にわかりやすくなっていいと思います。

## まとめ

~~plugin_loader.jsとvimppm.jsが合体すればさいつよなんだろうけど、自分にはJavaScriptの知識が無いので、ぜひ誰かに書いてほしい…です。~~現在vimppm.jsだけでうまく管理できてまず。感謝！
Raspberry Pi 2でUbuntu14.04を使う


Raspberry Pi 2でActivedirectoryの環境をつくろうと思ったけど、
RaspbianじゃなくてUbuntuを使ってみたかったので、やってみました。

間違いとかあったらごめんなさい。

__RaspbianだとSambaのバージョンが低いと思い込んで始めたとか言えない。__



0. Raspberry Pi 2を用意する
--------

そもそも本体が無いと始まりません！
適当なところから入手して下さい。

設定用PCにMacをつかってます。
Windowsについては特に書きません。頑張ってください。

RaspberryPi2用の`モニター`と`キーボード`は`なし`でやっていきます！
※途中必要になりました。ごめんなさい。



1. Macでubuntu-trustyイメージをSDに焼く
--------

Raspbianはsambaが古かったので、使いたくない。ソースからビルドは嫌だ
↑もしかしてUnuntu14.04のほうがsambaのバージョン低い？
Snappy Ubuntu Coreは入れてみたけど正直良くわからなかった（情報少ないよね？）

そんなわけで、
Ubuntu14.04がRaspberry Pi 2に入れれるらしいので、それでやってみる。

とりあえず、ここからイメージをDLしてくる

ARM/RaspberryPi - Ubuntu Wiki
https://wiki.ubuntu.com/ARM/RaspberryPi

Zip解凍して、SDに焼く

焼き方は下記のページに任せる

### 参考
>第2回 Ubuntu 14.04 の Raspberry Pi 2 へのインストール - Raspberry Pi 2 で自宅サーバー＆電子工作を
>http://raspi2.hateblo.jp/entry/2015/04/18/190427

>Mac OS X で Raspberry PiのOSイメージを焼く - @ledsun blog
>http://ledsun.hatenablog.com/entry/2014/10/26/174712



2. Raspberry Pi起動！
--------

先ほど作ったイメージSDをつかってRaspberry Piを起動してみる

画面をつけていないので、起動したかわからないです。

画面をつけてIPを確認するのは面倒....

DNSのIP払い出しを確認してIPをGET!
いざSSHで接続......

```
$ ssh 192.168.0.2 -l ubuntu
ssh: connect to host 192.168.0.2 port 22: Connection refused
```

###出来ない！

なんと、sshサーバーが入って無いらしい。

諦めて、モニターとキーボードを用意してログインします。

初期設定はユーザー名もパスワードも「ubuntu」になってます。

早速sshサーバーをインストール！

```
$ sudo apt-get -y update
$ sudo apt-get install -y openssh-server
```

これで、インストールは完了。

もうキーボードもモニターもいらないのでお片付けします。

いつものPCに戻り気を取り直して、SSH接続を試みます。

```
$ ssh 192.168.0.2 -l ubuntu
The authenticity of host '192.168.0.2 (192.168.0.2)' can't be established.
RSA key fingerprint is **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.2' (RSA) to the list of known hosts.
ubuntu@192.168.0.2's password: ※ここでパスワード入力
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.18.0-20-rpi2 armv7l)

 * Documentation:  https://help.ubuntu.com/
Last login: Mon Jun 29 06:20:57 2015
ubuntu@ubuntu:~$ 
```

ログイン成功！完璧です。

3. OSデータのバックアップを作成
--------

いじりまくってよくわからなくなることが容易に想像できるので、
元に戻せるようにバックアップを作っておきます。
不要な人は飛ばして下さい。

Macで以下のコマンドを実行し先ほど作ったSDカードを探します。

```
$ diskutil list
```

見つけたら、次のコマンドでバックアップ！
※ "/path/to/backup/RaspberryPi2_ubuntu_backup.img" はバックアップの保存場所を指定して下さい。

```
$ sudo dd if=/dev/disk2 of=/path/to/backup/RaspberryPi2_ubuntu_backup.img
```

### 参考
>ddコマンドでSDカードのクローンを作る | kanonjiのブログ
>http://kanonji.info/blog/2013/11/29/dd%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7sd%E3%82%AB%E3%83%BC%E3%83%89%E3%81%AE%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%B3%E3%82%92%E4%BD%9C%E3%82%8B/


3.5 パッケージ管理システムでaptitudeを使う
--------

何気なくapt-getを使ってきましたが、なんとなくaptitudeを使いたくなったのでインストールします。

```
$ sudo apt-get install -y aptitude
```

なんとなくなので、apt-getでもいいはずです。（多分）
インストールしたくない！って人は、`aptitude`を`apt-get`に読み替えて下さい。
※確認してないから動かないかも？

### 参考
>apt-get/apt-cacheとaptitudeの違い - MogLog
>http://sandragon.hatenablog.com/entry/2014/02/11/152752


まとめ
--------

思った以上に簡単だったけど、
sshdが最初にインストールされてないのは想定外でした（ちゃんとマニュアル嫁）

次からは今回作ったイメージを流用しまくります。
Rustによるダイナミックライブラリの作り方と他言語からの呼び出し


Rustは比較的簡単にCスタイルのダイナミックライブラリを作って
それを外部から呼び出すことが可能。

今回の検証では以下の言語の呼び出し例を挙げる

- Python
- C
- Haskell


## 検証環境

### OS
OSX Yosemiteで検証

### rustのバージョン
```bash
> rustc -V
rustc 1.2.0-dev (467e4a668 2015-06-16)
```


# ダイナミックライブラリの作成

以下がミニマルなサンプル

```
#![crate_type = "dylib"]

#[no_mangle]
pub extern fn repeat_hello(s:i32) {
    for _ in 0..s {
        println!("Hello");
    }
}
```

上記を `hello.rs` で保存し、
コンパイルは通常通り以下のように行う。特にオプションを指定する必要は無い

```sh
rustc hello.rs
```

結果ファイルとして`libhello.dylib`（OSXの場合）が出来上がる。

以下呼び出しに関してはlibhello.dylibが呼び出し元と同じディレクトリにあると仮定

# 他言語からの呼び出し例

基本的にはC製のダイナミックライブラリを使うやり方そのまま

## pythonからの呼び出し

上記の`dylib`をPythonから呼び出すことを考える
ctypesからの呼び出しは簡単

```python
#!/bin/env python3

import ctypes
import argparse

def hello(n):
    libhello = ctypes.CDLL("./libhello.dylib")
    libhello.repeat_hello.argtypes = (ctypes.c_int32,)
    libhello.repeat_hello(n)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("N",type=int)
    args = parser.parse_args()
    hello(args.N)

```

実行

```sh
> python call.py 5
Hello
Hello
Hello
Hello
Hello
```



## Cからの呼び出し

`call.c`を以下のように記述

```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

void repeat_hello(int32_t i);

int main(int argc, char const *argv[]) {
  if(argc<2) {
    printf("invalid arg.\n");
    exit(1);
  }
  int32_t i = atoi( argv[1] );
  repeat_hello(i);
  return 0;
}

```

以下のようにコンパイル

```sh
gcc -L. call.c -o call_from_c -lhello
```

実行

```sh
> ./call_from_c 5
Hello
Hello
Hello
Hello
Hello
```

## Haskellからの呼び出し

```haskell
import Foreign.C.Types
import System.Environment
import Control.Applicative

foreign import ccall "repeat_hello" repeatHello :: CInt -> IO ()

main :: IO ()
main = do
  n <- read.head <$> getArgs :: IO CInt
  repeatHello n
```

コンパイル

```sh
ghc -L. -lhello call.hs -o call_from_haskell
```

実行

```
> ./call_from_haskell 5
Hello
Hello
Hello
Hello
Hello
```



# cargoを使う場合

`cargo.toml`を以下のように記述する。

```toml
[lib]
name = "hello"
crate-type = ["dylib"]
```

`cargo build`を行うと`./target/debug/libhello.dylib`が出来る。

# まとめと今後の課題

rustでダイナミックライブラリの作り方と使い方についてまとめた。
今後の課題は構造体を受け渡す方法（出来るのか？）
docker log driverにfluentdが入った!

https://github.com/docker/docker/commit/b96f1093441a20678c9ff0e57528bbb780b34d10

https://github.com/docker/docker/commit/361a582ba0bccea04a8ea1799e68779fa66abb9f

わいわい

@tagmorisさんおつかれさまでした。
bash設定

# 個人的bash設定

* 随時更新していく予定。

# gitでブランチが表示されるように設定する

```
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/git/contrib/completion/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\n\$ '
```
* 上記を.bash_profileに追加(.bashrcでもいいかも？)

* ```__git_ps1: command not found```こんなエラーが出た場合
    * gitcomprication.bash を配置
        * 詳しくは[ここ](http://qiita.com/tanishi/items/2adb71024d675bc43177)参照しました


まだまだ、ターミナルが使い辛いので、設定していく予定。
ワードプレス　アイキャッチ画像に関する質問

ワードプレスにて、アイキャッチ画像の設定に関する質問です。

アイキャッチ画像を設定しようと思っています。
「表示オプション」にアイキャッチ画像を表示させることができず、
実際に使用することもできません。

そのためには、以下の手順で行いましたが、反映されませんでしたので、
どなたかご教授願いませんでしょうか。。。

-----------------------------------------
1.function.phpに直接ソースを書き込む
⇒入れても反映されてない
<?php
　　add_theme_support('post-thumbnails');
set_post_thumbnail_size(160, 120, true);
?>

2.アイキャッチ画像を設定できるプラグイン
⇒設定できない
プラグイン名：Auto Post Thumbnail、Default Thumbnail Plus
双方ともプラグインのインストールはが完了して、「有効化」にもしましたが、そこでの「設定」ボタンが存在しません。
-----------------------------------------


この理由もわかる方いましたら、教えていただきたいです。
プラグインの操作自体は一つずつ行い、両方同時に有効化とかはしていません。。。
シェルで再帰処理の落とし穴

Bashでも再帰処理は普通に動くものの、一見問題なさそうな↓の処理にはバグが有ります。

* code

```lang:saiki
#/bin/bash

function testFunc() {
    ARG1=${1}

    # 引数を表示
    echo "IN  ARG1= ${ARG1} VS 1= ${1}"
    # 一回ネストすると”GO->NEST”になって処理を終了する
    if [ ! `echo "${ARG1}" | grep "NEST"` ] ;
    then
        testFunc "${ARG1}->NEST"
    fi;
    # 引数を表示
    echo "OUT ARG1= ${ARG1} VS 1= ${1}"
}

testFunc "GO"
```

* 実行結果

再帰構造のfunctionを作った場合、処理から抜けた後も抜ける前の変数を保持し続けてしまいます。
本当の意味でのプライベート変数は引数で受け取った$1.2..だけのようです。

```lang:result
IN  ARG1= GO VS 1= GO
IN  ARG1= GO->NEST VS 1= GO->NEST
OUT ARG1= GO->NEST VS 1= GO->NEST  （ネストから出る
OUT ARG1= GO->NEST VS 1= GO　　　　（ネストから出たのにネスト側の変数保持
```

これに半日近くハマったことがあるので気をつけてみてください。
※そもそもShellで再帰構造とか作る機会無いかもしれいませんが。
bootstrapのmodalをブラウザの「戻る」で閉じる方法

便利だったのでメモします。

#方法

modalが表示された時
→ 履歴にmodalのid付きのurlを追加します

modalが閉じられた時
→ urlにmodalのidがあったら、ブラウザの「戻る」を起動します

「戻る」ボタンが押された時
→ modalを閉じます

````sample.js
$(function() {

  // modalが表示された時
  $(".modal").on("shown.bs.modal", function() {
    var urlReplace = "#" + $(this).attr('id')
    history.pushState(null, null, urlReplace)
  });

  // modalの閉じる機能が動作した時
  $(".modal").on("hidden.bs.modal", function () {
    if(location.hash == "#" + $(this).attr('id')) {
      history.back()
    }
  })

  // 「戻る」ボタンが押された時
  $(window).on('popstate', function() { 
    $(".modal").modal('hide')
  })

})
````

modalを重ねて使わないページでは、大体期待通り動作すると思います。
もっと良い書き方がありましたら、教えて頂けると嬉しいです。

以上です。

#参考
[backbutton close bootstrap modal]
(https://gist.github.com/thedamon/9276193)
[How to handle the modal closing event in Twitter Bootstrap?]
(http://stackoverflow.com/questions/12319171/how-to-handle-the-modal-closing-event-in-twitter-bootstrap)
[javascriptまとめ]
(http://www.red.oit-net.jp/tatsuya/js/location.htm)
rebar3でutility用のdepsを追加する

# rebar3でutility用のdepsを追加する

rebar.configにedown, reloader, meckなどtestでないしは開発用で使うライブラリを登録するケースがあると思う.
その方法について, 最近tsloughter氏に「こうしてくれ」とご指摘頂いたので, 紹介する.

## profilesを使用する

```erlang
{profiles, [{test, [{deps,
                     [
                      {meck,             ".*", {git, "git://github.com/eproxus/meck.git",            {tag, "0.8.2"}}},
                      {eunit_formatters, ".*", {git, "git://github.com/seancribbs/eunit_formatters", {branch, "master"}}}
                     ]}
                   ]},
            {dev, [{deps,
                    [
                     {reloader, ".*", {git, "git://github.com/mykook/reloader.git", {branch, "master"}}},
                     {edown,    ".*", {git, "git://github.com/uwiger/edown.git",    {branch, "master"}}}
                    ]}
                  ]}
           ]}.
```

こうしておくことで, ライブラリを使用される際に不要なライブラリを取得しないで済むようになる.

なお, `test`に関しては`rebar3 eunit` `rebar3 ct`を実行した際に取得され, `dev`は`rebar3 as dev *` (`rebar3 as dev compile`など)を実行した際に取得される.

詳細は下記ドキュメントを参照して欲しい.
http://www.rebar3.org/v3.0/docs/profiles
Windows で Haskell 環境構築(Stack)


###はじめに
Haskellと言えば、取っつきにくい言語の代表だと思われる方も多いかと思いますが、開発環境は日々改善されてきています。

今回は、改善されつつある開発環境の最右翼ともいえるStackのWindowsへの導入手順を紹介します。

本記事が、皆さまがHaskellに親しむ第一歩となればと思います。

###Stackとは
Stack <https://github.com/commercialhaskell/stack> は、プラットフォーム間の差異を吸収したHaskell開発環境を提供する意欲的なツールです。

StackはOS間の差異を吸収するだけではなく、LTS(Long Term Support) Haskellを利用することで、Cabal Hellと呼ばれる依存性問題を解決してくれます。

###Stackのインストール
1. 以下のURLからStackのバイナリを取得します。
<https://github.com/commercialhaskell/stack/releases/tag/v0.1.1.0>

2. バイナリを解凍し任意のディレクトリに配置し、パス環境変数を通します。

###GHCのインストール
Stackのsetupコマンドにて、Haskell実行ランタイムであるGHCをインストールします。

1．任意のディレクトリに以下の内容でstack.yamlを作成します。
resolverでは使用するLTS(Long Term Support) Haskellのバージョンを指定します。

    packages:
    - .
    resolver: lts-2.16

   ２．stack.yamlを配置したディレクトリで以下のコマンドプロンプトから以下のコマンドを実行しGHCをインストールします。
   GHCインストール後に表示された文字列を、パス環境変数に追加します。

    stack setup
   
   3．パス環境変数設定後、コマンドプロンプトを再起動し、
以下のコマンドを実行し、GHCのバージョンを確認します。

    ghc -v
 

###Cabalのインストール
 次に、Stackのbuildコマンドにて、プロジェクトビルドを実行するCabalをインストールします。
 
 1. 任意のディレクトリでnewコマンドを実行することで .cabal ファイルの雛形を取得します。
以下のコマンドをコマンドプロンプトから実行すると、new-template.cabalが作成されます
    
    stack new

２. 上記で作成されたファイルをstack.yamlを配置したディレクトリにコピーし、buildコマンドを実行すると、Cabalがインストールされます。
Cabalがインストールされることで、他のライブラリのインストールが円滑に進みます。

    stack build
    
###ghc-modのインストール
最後に、Haskellプログラムを開発する際、コンパイルエラーや補完をするghc-modをインストールします。

1. 任意のディレクトリでupdateコマンドを実行することで、
パッケージリストを更新します。

    stack update

2．任意のディレクトリでinstallコマンドを実行することで、ghc-modをインストールします。
インストール後に表示された文字列を、パス環境変数に追加します。

    stack install ghc-mod

以上が、Stackを使ったHaskell環境(の第一歩)となります。

###Stackを使って何が嬉しいのか?
これまでは、求めるバージョンのGHCのインストールのために、ソースからビルドする必要があったり、cabal-installのバージョンの衝突のためghc-modがインストールできないなど、Stack以前は、LTS Haskellを使用する開発環境の構築にはとても手間がかかりました。

Stackの登場により、ただでさえ色々めんどくさいWindowsで、上記の手順でghc-modのインストールまで完了できるようになったことは、非常に革新的なことだと私は思います。

###更に快適な開発環境を求めて
実行環境の構築の次は、エディタによる編集環境の構築を紹介したいと思います。
SublimeTextを使うことで、ghc-modの補完機能、ghciの対話実行環境サポートが受けられます。
SublimeTextもマルチプラットフォームをサポートしていますので、Stackと合わせて、OSによらないHaskell開発環境を構築することができます。
Eclipse macでpleiadesを入れると、EGitでコミットできない

#Eclipseをpleiadesで日本語化したら、(macで)EGitでコミット出来なかった

上に書いたとおり、Eclipseを日本語化したら、EGitがエラーで動かなくなったので対処法をメモ。

まず、pleiadesを消す。
次に、babelで日本語化をする。
luna環境で、Babelを全部インストールするとバグが起きるようなので、以下を参照してインストールする。
http://d.hatena.ne.jp/satoruyoshida/20140820/1408532610

簡単にやり方をメモ
helpからinstall new Softwareみたいなやつをクリック。

下記URLをはりつける
http://download.eclipse.org/technology/babel/update-site/R0.12.1/luna

表の中からBabel Language Pack for eclipse in Japaneseだけを選択してインストール
Androidの画面ロックを「なし」に設定する方法

# どんな状況？

ロック画面設定が「PIN」「パターン」「パスワード」しか選べなくなり、「なし」にできなくなる。

![画面ロック方法の選択.png](https://qiita-image-store.s3.amazonaws.com/0/3676/05ca75e2-1643-d96b-a91f-3bb5b328c324.png)

# なんで起こるの？

「管理機能、暗号化ポリシー、または認証情報ストレージにより、無効になりました」とある通り。
自分がよくやっちゃうのは、Charlesなどのプロキシ設定した際に証明書をインストールして認証情報ストレージを使っちゃった場合など。

# 解決方法

## 認証情報ストレージの問題

証明書を入れた場合は、全て削除するまでは解除できない。
[セキュリティ] → [認証情報ストレージ] → [証明書を消去] を選択して証明書を全て削除すればOK。

## 暗号化ポリシーの問題

[セキュリティ] → [端末を暗号化]
または
[セキュリティ] → [外部SDカードを暗号化]
を解除すればOK、だと思う。使ったことないｗ

## 管理機能の問題

これが原因になったことないので分からないです、すません。


# ご注意を

検証機をロックしちゃうとみんなで使うときに困るので、「なし」に設定するための備忘録です。
普段ご利用の端末ではくれぐれも「なし」には設定しないように・・・
Java8のラムダ式について少しだけ調べた（初心者向け）

どうも。[@Tsuji_Taku50](https://twitter.com/?lang=ja)です。
もう少しするとチームでもJava8を使うことになりそうなので、Java8について少し調べました。
まぁ主にラムダ式なんですが。色んなサイトを見ても「Java8はラムダ式！」みたいなことが書いてありますが、ぶっちゃけよく分かっていません。
ラムダ式ってなんだよって感じなので、少しでも書き方や考え方を知ろうと思って今回調べました。
# ラムダ式のメリット
+ 記述が簡潔になる  
色々なことが書かれていましたが、一番は記述が簡潔になることだと思われます。
+ 例   
Java7までの書き方
<pre>List<Integer> list = Arrays.asList(1, 3, 2);
Collections.sort(list, new Comparator<Integer>() {
  @Override
  public int compare(Integer o1, Integer o2) {
    return Integer.compare(o1, o2);
  }
});</pre>
↓　　
ラムダ式にすると・・・
<pre>List<Integer> list = Arrays.asList(1, 3, 2);
Collections.sort(list, (o1, o2) -> Integer.compare(o1, o2));</pre>


# ラムダ式の構文
ラムダ式は、<b>「引数部 -> 処理本体」</b>という形式で表します。
メソッド名と戻り型の宣言が無いメソッド定義となるようです。


+ 引数部分の書き方

| 引数部分の定義 |詳細|ラムダ式の例|
|---|---|---|
| 基本形(型1　引数名1)  |基本系の書き方はこれ|()->{}<br/>  (String s)->{}  <br/>(int x,int y)->{}|
| 省略形(引数名1,引数名2) | 複数の引数がある場合は、全ての引数について型を省略する必要がある。一部だけの省略は不可能。|()->{}<br/> (s)->{} <br/>(x,y)->{}|
| 括弧の省略(引数名)| 引数が1個しか無い場合は、引数を囲む丸括弧を省略することが出来る。この場合は、型も省略する必要がある。 |s->{}|
*ラムダ式の引数名には単一アンダースコア「_」を使うことが出来ないみたいです。

+ 処理本体の書き方

| 処理本体 |詳細|ラムダ式の例|
|---|---|---|
| 基本形<br/>{文1;<br/>文2;<br/>…<br/>return 戻り値;}  |基本系の書き方はこれ|(int x)->{sysout(x+1)<br/>return x}|
| 省略形(戻り値がvoid) | returnが省略可能|(int x)->{sysout(x+1)}|

#　最後に
これからこのラムダ式の書き方が増えてくるかどうかは分かりません。
ただラムダ式の書き方を知っているに越したことはないかなと個人的には思っています。
書けるまでいかなくても、読めるようになっておいた方が良いかと思います。

# おまけ(コード書いてみました)
<pre>	public static void main(String[] args) {
		// 基本形
		Function<Integer, Integer> f1 = (Integer i) -> {
			return i + 1;
		};

		// 引数の型を省略
		Function<Integer, Integer> f2 = (i) -> {
			return i + 1;
		};

		// returnを省略
		Function<Integer, Integer> f3 = (i) -> i + 1;

		// () の省略（引数がひとつの場合）
		Function<Integer, Integer> f4 = i -> {
			return i * i;
		};

		// 実行
		f1.apply(1);
		f2.apply(2);
		f3.apply(3);
		f4.apply(4);
	}</pre>
[翻訳]さらにもうひとつのスクラムのたとえ話


# はじめに
このエントリーは、Darren Laiの[Yet another analogy of Scrum](http://www.thejourneytomastery.com/blog/yet-another-analogy-of-scrum/)を許可を得て翻訳したものです。訳者は技術ブログの翻訳をしたことがあまりありませんので、誤訳等あればぜひ指摘してください。
また、Darrenさんはみんなの持ってるたとえ話を知りたがっていたので、ぜひみなさんのスクラムたとえ話をシェアしてください！

# さらにもうひとつのスクラムのたとえ話

私の同僚である[Bas Vodde](https://less.works/profiles/basvodde)が、ある認定LeSS実務家研修[^1]でプロダクトオーナーのロールについてどのように説明したかを教えてくれた。これが彼が言ったことで、いいたとえだな、と思う。

> プロダクトオーナーはレストランでディナーをしているお客さんみたいなものだ。お金も、胃袋のスペースも限られている。だから彼はなにを食べたいかを「優先順位付け」してオーダーする。そして、料理を待つ。彼はキッチンに行って、シェフにどうやって料理するかを伝えたりはしない。

つい最近、私はシンガポールでMichael Feathers[^2]の研修に参加した。彼はリファクタリングについて、こんなたとえ話を教えてくれた。

> 良いレストランのシェフは、使い終わった料理器具はすぐに綺麗にする。こうしなければ、将来料理器具を使おうと思った時に時間がかかってしまうからだ。これは開発するときの規律でもあり、習慣でもある。

最近Gordon Ramsay[^3]を見すぎたかもしれない、このおかげで、私はもうひとつの（すでにたくさんあるけれど）レストランのたとえ話を思いついた。

> 開発チームは、レストランで働くシェフみたいなものだ。もしお客さんのもとへ届かなければ、料理がどんな見た目で、どんな味かなんて問題じゃない。でも、タイトな期限があるからといって、まずい料理をお客に届けてもいいなんてことにはならない。

シンプルだけど習得が難しいスクラムのプロセスをうまく言い表すたとえ話はたくさんある。あなたが共鳴できるものを見つけだして、使おう。

[^1]: [訳注][Certified LeSS Practitioner](http://less.works/courses/less-practitioner.html)のこと。
[^2]: [訳注][レガシーコード改善ガイド](http://www.amazon.co.jp/%E3%83%AC%E3%82%AC%E3%82%B7%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E6%94%B9%E5%96%84%E3%82%AC%E3%82%A4%E3%83%89-Object-Oriented-SELECTION-%E3%83%9E%E3%82%A4%E3%82%B1%E3%83%AB%E3%83%BBC%E3%83%BB%E3%83%95%E3%82%A7%E3%82%B6%E3%83%BC%E3%82%BA/dp/4798116831)の著者です。
[^3]: [訳注][Kitchen Nightmares](http://www.fox.com/kitchen-nightmares)ってテレビ番組に登場する、マスターシェフだそうです。
Sandboxアカウントに残高を追加する方法

ペイパルのsandboxでアカウント作成時に金額を最大で$9,999を指定できますが、様々なテストを行っていると残高が減ってきます。

これをアカウント管理画面で追加させることはできませんが、もう一つのアカウントを作って送金して補充することができます。

また、JPアカウントですと１回あたりの送金額の制限がありますので、USビジネスアカウントを作成することをお勧めします。$10,000,000までは送金テストできました。
CentOS6.6にUpsourceを入れた

しおしおさんがUpsourceに関するブログを結構書いているので、現在所属しているPJで使えないかCentOS6.6にインストールしてみる。

* [Upsource カテゴリーの記事一覧 - しおしお](http://siosio.hatenablog.com/archive/category/Upsource)

## インストール要件
* メモリ8GB以上
* JDK 1.8がインストール済
* 以下のコマンドが通ること
  * `ping $(hostname -f)`

あとはIEなら10以上とか、開発にはGit, Mercurial, Subversion, Perforceを利用していること、など。
現在所属しているPJではGitBucket/Gitを利用しているけど、今後多数派なSubversionのPJに異動になっても対応しているので、コードレビューの環境を作れるのはありがたい。Freeで使うなら10 User(8 users + admin + guest) だし、使う場面は限られそうだけど…

## インストール

### リソース制限を調整しておく

リソース制限が不十分だとエラーが起こることがあるので調整しておくって感じかと。

/etc/security/limits.conf に以下を追加する。

```/etc/security/limits.conf
* - memlock unlimited
* - nofile 100000
* - nproc 32768
* - as unlimited
```
https://www.jetbrains.com/upsource/help/2.0/things_to_configure.html

### Zipをダウンロード
UpsourceのDownloadページでzipのURLを確認し、wgetで取得する。

```bash
$ wget http://download-cf.jetbrains.com/upsource/upsource-2.0.3542.zip
$ cp upsource-2.0.3542.zip /opt
$ unzip unzip upsource-2.0.3542.zip
$ chmod -R a+rwX /opt/Upsource
```

### Upsourceの起動

以下のコマンドで起動する。

```bash
$ /opt/Upsource/bin/upsource.sh start
```

portやbase-urlなどは `/opt/Upsource/conf/internal/bundle.properties` で変更できる。

`http://yourhost:yourport` にアクセスすると(変更していなければportは8082)、以下のセットアップ画面が表示される。

順番に、アドミンユーザのID,パスワードの入力
![setup.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/a4047ee7-23c3-4853-3270-3772046d5dad.jpeg)

ライセンスの登録(Free 10-user planであれば、そのままでOK)
![license.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/f6013abf-44eb-d05d-a3f3-8575dd31d3a6.jpeg)

ライセンスの登録が済むとそれぞれのサービスが起動し、
![starting.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/c72f864d-50eb-3717-fcf3-09c0a650074c.jpeg)

ログイン画面が表示される。
![login.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/7d16d8b9-a4be-3668-fc9c-eb2954d53703.jpeg)

ログインするとこんな感じの画面が表示される。まだプロジェクトを作成していないので寂しい感じ。

![top.jpg](https://qiita-image-store.s3.amazonaws.com/0/6092/c87396e4-e8ef-a081-443a-025fb8825f52.jpeg)

次は設定とか使い方について書く(たぶん)

### リバースプロキシ配下で動かすには

自分では試していないけど、NginxとかApacheの設定例が載っているので参考にすればよさそう。
https://www.jetbrains.com/upsource/help/2.0/proxy_configuration.html

### 参考
* [Installing and configuring](https://www.jetbrains.com/upsource/help/2.0/install_config.html)
PowerShellでNASにファイルをアップロードする

PowerShellからNASにファイルコピーするのにPowerShellのバージョン差分でハマったのでメモ。

# PowerShell3.0(Windows8)だけで動けば良い場合
SMBでコピーする場合はGuest認証でも認証フェーズが必要なので、自分でクレデンシャルを生成してNew-PSDriveに渡してやることでPSドライブにマウントができるようになるので、後はCopy-Itemとかでコピーすればよい。サンプルコードこんなかんじ。

```ps1
    # ローカルファイル
    $localFile = "test.log"

    # アップロード先 
    $uploadServer = "\\xxx.xxx.xxx.xxx\hoge"
    $uploadDir = "fuga"
    $uploadFile = "test.log"

    # アップロード用のゲスト認証Credentialを生成する
    $uploadUser = "Guest"
    $uploadPass = "Guest"
    $secStr = ConvertTo-SecureString $uploadPass -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PsCredential($uploadUser, $secStr)

    # PSドライブにマウントする
    $psDriveName = "TestDrive"
    if(Get-PSDrive | where {$_.Name -eq $psDriveName}){
        # エラー終了などで既に存在する場合は一旦アンマウントする
        Remove-PSDrive -Name $psDriveName
    }
    $uploadDrive = New-PSDrive -Name $psDriveName -PSProvider FileSystem -Root $uploadServer -Credential $cred

    # アップロードする
    $uploadUri = "" + $psDriveName + ":" + $uploadDir + "\" + $uploadFile
    Copy-Item $localFile $uploadUri

    # PSドライブをアンマウントする
    Remove-PSDrive -Name $psDriveName

```


# PowerShell2.0(Windows7)でも動かないといけない場合
PowerShell2.0だと、New-PSDriveにCredentialが渡せなくて同じ方法だと資格情報のエラーになってしまいます。調べたところBitsTransferというのを使えばPowerShell2.0でも3.0でも動いた。OSのキャッシュ状態によってネットワークドライブが見えなかったりすることがあるようなので、前後で明示的にnet use使うとよいっぽい。
サンプルコードこんなかんじ。

```ps1
    # ローカルファイル
    $localFile = "test.log"

    # アップロード先 
    $uploadServer = "\\xxx.xxx.xxx.xxx\hoge"
    $uploadDir = "fuga"
    $uploadFile = "test.log"
    $uploadUri = "" + $uploadServer + "\" + $uploadDir + "\" + $uploadFile

    # アップロード用のゲスト認証Credentialを生成する
    $uploadUser = "Guest"
    $uploadPass = "Guest"
    $secStr = ConvertTo-SecureString $uploadPass -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PsCredential($uploadUser, $secStr)

    # ネットワークドライブを登録する
    net use $uploadServer $uploadPass /user:$uploadUser

    # アップロードする
    Import-Module -Name BitsTransfer
    Start-BitsTransfer -Source $localFile -Destination $uploadUri -Credential $cred

    # ネットワークドライブを削除する
    net use /delete $uploadServer
```

# 参考
* https://social.technet.microsoft.com/Forums/ja-JP/04f35468-65b6-46ba-8d7c-0883486c8ca9/getcredential?forum=powershellja