快適1コマンド: 雛形プロジェクトからGitHubリポジトリを作りTravisCIを回せるようにする

## TL;DR
- 多くの言語で `rails new` などの雛形を作る機能があるが、自分独自の雛形を使いたい場合も多い
- そんなとき、「昔作ったプロジェクトから `cp` して...」とやると案外時間がかる
- 雛形プロジェクトをGitHubで管理しておき、1コマンドで新しいプロジェクトを作成できるようにしておくと便利
- 新しいプロジェクトをGitHubにpushしてTravisCIと連携するのも1コマンドに含められる
- 汎用的なアプローチではないので、自分でやる際は下記掲載のシェルスクリプトを適宜修正

## 動機: 新しいプロジェクトをクイックに作りたい
新規プロジェクトを作るときに便利な `rails new` などのコマンド、多くの場合はここから始めれば良いでしょう。

ただし、こだわりのプロジェクト構成を持っていたり、そもそも言語やフレームワークがプロジェクトの雛形を作成するツールを提供していない場合は、自分独自のプロジェクト雛形から新しいプロジェクトを作りたくなります。

そんなとき、

```bash:真心こもった新規プロジェクト作成
cp -r prev-my-proj new-my-proj
cd new-my-proj

ls  # 要らないファイルを探す
rm -rf ... # 要らないファイルを消す

ls abc/  # 更にいらないファイルを探す
...

git ls-files |xargs sed -i 's/prevSymbol/newSymbol/g'  # 以前のプロジェクトのシンボル名を変換
...
```

などとやっていると、意外と時間がかかってしまうし、ひどいときには以前のプロジェクトの痕跡が残ってしまったりします。

なので、GitHubにプロジェクトの雛形を1個作ってしまい、そこから新しいプロジェクトを作成するためのコマンドを作成したらかなり快適になったという（泥臭い）お話です。

## 成果物

```bash:新規プロジェクトを作るコマンド
finatra-app new finatra-app-sample4qiita sample4qiita
```

この1コマンドで https://github.com/laysakura/finatra-app-sample4qiita のリポジトリができました。
Scalaのシンプルなアプリケーションサーバのプロジェクトになっていて、新しいプラグインなど思いついたときのサンドボックスとして使えます。

TravisCIと連携してbuild passingしている状態からスタートできる点も嬉しいです。

## やったこと
下記のシェルスクリプトを書いて、 `finatra-app` という名前でPATHの通ったところに置いています。
シェルスクリプトはやっつけ仕事で汎用性がないので、お使いの際は適宜修正してください。

ポイントは、

- 雛形プロジェクトを `git clone`
- 雛形プロジェクト中のファイルの中身のシンボル名を、新しいプロジェクト用に置換
- 雛形プロジェクト中のファイルの中身を、新しいプロジェクト用に置換
- `hub create` でGitHubリポジトリを作成
- `travis enable` でTravisCIとの連携

といったところです。

```bash:finatra-app
#!/bin/sh -eu

# =========================================================
# Functions
# =========================================================
## Functions: app specific
function showHelpAndDie() {
    local progName=$1

    cat 1>&2 <<EOF
Create template project copied from https://github.com/laysakura/finatra-thrift-simple-sample

# Usage example

$progName new finatra-great-filter greatfilter

# Parameters

## $progName new

$progName new GITHUB_REPO_NAME SCALA_PACKAGE_NAME
EOF
    exit 1
}

## =========================================================
## Main process
## =========================================================
function run() {
    local progName=$0

    [ $# -eq 3 ] || showHelpAndDie $progName

    local subCmd=$1
    local githubRepoName=$2
    local scalaPkgName=$3

    ## Check arguments
    [ "$subCmd" = "new" ] || showHelpAndDie

    # Clone finatra-thrift-simple-sample from GitHub
    git clone git@github.com:laysakura/finatra-thrift-simple-sample.git $githubRepoName
    cd $githubRepoName

    # Replace everything...
    git ls-files |xargs gsed -i "s/finatra-thrift-simple-sample/$githubRepoName/g"
    git ls-files |xargs gsed -i "s/simplesample/$scalaPkgName/g"
    for f in $(git ls-files |grep simplesample); do
        f_to=$(echo $f |gsed -e "s/simplesample/$scalaPkgName/")
        mkdir -p $(dirname $f_to)
        mv $f $f_to
    done

    # new git repo
    rm -rf .git/
    git init
    git add .
    git commit -m 'initial commit: copied from https://github.com/laysakura/finatra-thrift-simple-sample'

    # push to your GitHub
    hub create

    # enable travis
    travis enable

    # push initial commit and run test
    git push origin master
}
run $@
```

## 広告
[株式会社FOLIO](https://folio-sec.com/)では、日々の作業効率を追求しながら、次世代オンライン証券を構築する[エンジニアを募集中](https://www.wantedly.com/projects/79013)です。