プロジェクトディレクトリのコンフィグファイルをひとまとめにできるライブラリ「cdp」を作った

CDPはClean Desk Policyの略で、要は机の上をキレイにしましょうという運動のことです。
この考えをフロントエンド開発環境にも導入したかったので、今回cdpというライブラリを開発しました。
100% TypeScriptで開発しました！

Githubで公開中です。
https://github.com/kuluna/cdp

Windows10でしか動作確認しておりませんが、MacやLinuxでも動作するはずです。

# フロントエンド開発環境はコンフィグファイルが散らかっている！
試しにAngularの新規プロジェクトを作ってみましょう。

```
$ npm install -g @angular/cli
$ ng new newproject --skip-install
```

できあがったものがこちらです。

```
./
│  .angular-cli.json    <- config file
│  .editorconfig        <- config file
│  .gitignore
│  karma.conf.js        <- config file
│  package.json
│  protractor.conf.js   <- config file
│  README.md
│  tslint.json          <- config file
│  
├─e2e
│      app.e2e-spec.ts
│      app.po.ts
│      tsconfig.json    <- config file
│      
└─src
    │  favicon.ico
    │  index.html
    │  main.ts
    │  polyfills.ts
    │  styles.css
    │  test.ts
    │  tsconfig.json    <- config file
    │  
    ├─app
    │      app.component.css
    │      app.component.html
    │      app.component.spec.ts
    │      app.component.ts
    │      app.module.ts
    │      
    ├─assets
    │      .gitkeep
    │      
    └─environments
            environment.prod.ts
            environment.ts
```

__あまりにもコンフィグファイルが多い！__
これでもかなり少ないほうだと思います。

ライブラリ毎にコンフィグファイルが出来上がっていくので、開発していくうちにどんどんコンフィグファイルが増えていきます。
これをGit pushするとたくさんルートにファイルが出てきて__ウッ・・・__ってなったのが今回の開発の動機です。

# cdpを使うと
```
$ npm install -g cdp
$ cdp --in --gitignore --afterdelete .angular-cli.json .editorconfig karma.conf.js protractor.conf.js tslint.json e2e/tsconfig.json src/tsconfig.json
```

```
./
│  .gitignore
│  configs.json     <- one config file!
│  package.json
│  README.md
│  
├─e2e
│      app.e2e-spec.ts
│      app.po.ts
│      
└─src
    │  favicon.ico
    │  index.html
    │  main.ts
    │  polyfills.ts
    │  styles.css
    │  test.ts
    │  
    ├─app
    │      app.component.css
    │      app.component.html
    │      app.component.spec.ts
    │      app.component.ts
    │      app.module.ts
    │      
    ├─assets
    │      .gitkeep
    │      
    └─environments
            environment.prod.ts
            environment.ts
```

かなりスッキリしましたね！これならウッってならなさそうです。
かわりに`configs.json`というファイルができています。この中にすべてのコンフィグファイルの情報がまとめられています。

# いやそれらのファイルないと困るんだけど
そっすね(直球)

cdpの目的はgit pushされるときにClean Deskのようにきれいなリポジトリになるようにという意味を込めています。なのでリポジトリをクローンしてきたあと、

`$ cdp --out`

を実行すると`configs.json`にまとめられたファイルたちが元の場所に戻ります。
なので、cdpを使った開発フローとして

1. リポジトリをクローンまたはチェックアウト
2. `$ cdp --out`
3. Develop!
4. コンフィグファイルを変更したら `$ cdp --in xxx`
5. `git push`



# configs.jsonの中はどうなってるの？
先ほどのAngularプロジェクトで作った`configs.json`の一部を抜粋してみます。

```configs.json
[
  {
    "path": "src/tsconfig.json",
    "format": "json",
    "body": {
      "compilerOptions": {
        "baseUrl": "",
        "declaration": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "lib": [
          "es2016",
          "dom"
        ],
        "mapRoot": "./",
        "module": "es2015",
        "moduleResolution": "node",
        "outDir": "../dist/out-tsc",
        "sourceMap": true,
        "target": "es5",
        "typeRoots": [
          "../node_modules/@types"
        ]
      }
    }
  },
  {
    "path": ".editorconfig",
    "format": "plain",
    "body": [
      "# Editor configuration, see http://editorconfig.org",
      "root = true",
      "",
      "[*]",
      "charset = utf-8",
      "indent_style = space",
      "indent_size = 2",
      "insert_final_newline = true",
      "trim_trailing_whitespace = true",
      "",
      "[*.md]",
      "max_line_length = off",
      "trim_trailing_whitespace = false",
      ""
    ]
  }
]
```

はじめの`src/tsconfig.json`のようにjsonタイプのファイルは`"format": "json"`として分類され、`body`配下にそのままコピーされます。
次の`.editorconfig`のようなテキストタイプのファイルは`"format": "plain"`として分類され、改行で区切られたstring配列としてコピーされます。

jsonをそのままツリーに取り込んだのも、テキストを改行して配列として取り込んだのも一応は可読性を高めてこのような構造にしています。また`configs.json`のbody配下を直接編集するのもOKです。ただ普通は元のコンフィグファイルを変更して都度`$ cdp --in xxx`としたほうが良いと思います。同じバスであれば上書きされます。

# cdp --inのオプション

`$ cdp --in`するときにオプションとして`--gitignore`と`--afterdelete`を用意しています。

## --gitignore
--inで指定したファイルを`.gitignore`に追加するオプションです。

## --afterdelete
--inで指定したファイルを`configs.json`に追加したあと、ファイルを削除します。

## --outについて
--outについては特にオプションはありません。`configs.json`にある登録したすべてのファイルに作成・上書きしていきます。

# さいごに
初めてNode.jsを使ったコマンドラインツールを開発してみましたが、そこまで手こずらずにできた感じです。特にTypeScriptによる安心感は非常に良かったです。
ただコマンドラインツールとしてnpm publishするときはいくつかのルールがあり、最初それに気づかずに出した結果0.0.1は全く起動できないというやらかしをしてしまいました(泣)
開発時の所感などは別の記事でまとめられればと思います。