はじめてGitHub x CircleCIでPython製のテキストチェックツールを公開した話

# 前置き
- Githubのアカウント持ってるけど、何も公開したことなかった
    - 汎用的なテキストチェックツールをたまに欲しくなるが、求めてるのが中々なかったので作ってみて公開してみよう！
- 次の会社でCircleCI使ってると聞いた
    - 無料プランもあるので使ってみよう！
- 以上を実行する際に色々苦悩したポイントを書いていきます

# Pythonで日付のフォーマットと妥当性チェックを行うツールを作ってみました
- GitHub：https://github.com/nir-takemi/text_verifier
- こんな雰囲気（YYYY/MM/DD（w）hh:mmが正しいフォーマットで定義）

```
[Err file path]/Users/xxxx/Documents/test.txt
[Err]Date format does't conform to rules: ２０１６/2/29（月）23:59
[Err]Date format does't conform to rules: 2016/2/29 (月) 23：59
[Err]Date format does't conform to rules(NG list): \n2/29（月）23:59
[Err]2016/2/30 isn't exist: 2016/2/30（火）23:59
```

- 将来的には色んなテキストに対するチェックをしたいと思って、 `text_` と広めに命名してみた


# ツール作成で苦悩した点
## Pythonの命名規則について
- 参考にさせていただきました！：[Python命名規則一覧](https://qiita.com/naomi7325/items/4eb1d2a40277361e898b)


## testコードって入れるもん？
- 結論は入れちゃう
    - 天下のGoogle様が公開している[TensorFlow](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/python)にもtestコード含まれているから入れて良いもんと判断
    - それと以降で記載してますが、CircleCIでテスト回したい時に、プロジェクト内にないと面倒そうなので入れるしかない

## test書くライブラリって何が良いの？
- pytestを選定。
    - unittestと悩んでたが、Python経験者に聞いてみたら直感的に分かりやすいとのことで、pytestにした。シンプルなツールなので、特にこの時点で迷う必要もないし、長いものには巻かれる。
- 参考にさせていただきました！：[pytestに入門してみたメモ](https://qiita.com/everylittle/items/1a2748e443d8282c94b2)


## そもそもPythonのファイル階層ってどんな感じ？
- 結論こんな感じにしました

```
tree .
.
├── tests # テスト関連
│   ├── conftest.py
│   └── test_text_verifier.py
├── textverifier # メインモジュール関連
│   ├── config.yaml
│   ├── pattern.yaml
│   └── text_verifier.py
└── verify_text.py # 実行するだけの存在
```

- unittestですが参考にさせていただきました！：[Python 3 標準の unittest でテストを書く際のディレクトリ構成](https://qiita.com/hoto17296/items/fa0166728177e676cd36)

## pytestがmodule loadできずに実行できないんですけど……
- 結論は、 `conftest.py` （テスト全体の前処理として実行される）を作成して、そこに、 moduleのディレクトリの相対パスを通す処理を記載した
    - 参考
        - [ディレクトリパスを直接指定してimport](https://qiita.com/ta_ta_ta_miya/items/e107ca64aae87c2bce1d)
        - [pytest入門 - 闘うITエンジニアの覚え書き](https://www.magata.net/memo/index.php?Python%B3%D0%A4%A8%BD%F1%A4%AD)
- 上記のファイル階層で、以下のようにmoduleをimportしてた

```
from text_verifier import TextVerifier
```

けど、こんなエラー

```
ImportError while importing test module 'xxx'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_text_verifier.py:5: in <module>
    from text_verifier import TextVerifier
E   ModuleNotFoundError: No module named 'text_verifier'
```

- なので、testディレクトリ配下の `conftest.py` を以下のように記載した

```python:conftest.py
import sys 
import os

sys.path.append(os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../textverifier/"))
```

# CircleCIについて
## 入門
- 参考にさせていただきました！：[いまさらだけどCircleCIに入門したので分かりやすくまとめてみた](https://qiita.com/gold-kou/items/4c7e62434af455e977c2)
- 基本的にはテストを実行するために以下のことをした
    - CircleCI登録
    - GitHubと連携
    - `config.yml` をGitHub側のプロジェクトで作成
    - ローカルにDocker＆CicleCIをinstallして、作成した `config.yml` の確認テストを繰り返し実行
    - GitHubに `config.yml` をpush
    - pushするとCicleCI側で勝手に実行される
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/f9b5626f-d7fa-7d04-3f19-726779f4020a.png)

- ちなみに最終的な `config.yml` はこうなりました

```
version: 2
jobs:
  build:
    docker:
      - image: circleci/python:latest
    steps:
      - checkout

      - run:
          command: |
            sudo pip install pipenv
            pipenv install
            pipenv run pip install pyyaml
            pipenv run pip install pytest
            pipenv run pytest
```


## せっかくだからCircleCIのバッチを表示したい
- GitHubのreadmeのとこでこんなの
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/19581140-832c-9c15-8033-40aeb696b49f.png)

- 参考にさせていただきました！：[githubでREADME.mdにCircleCIのバッジを表示する](https://qiita.com/Hanocha/items/8ad74258eb43d0959590)


## テストの結果でエラーにちゃんとなるの？
- 一旦ローカルのtestでエラーになる状態を作る
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/870233f0-91b5-b701-baad-73f57e519f05.png)
- push!&run!（ちゃんと失敗になった！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/1d41f94d-ab57-b1f2-45ff-23714fd156d5.png)
- ちゃんとローカルのエラーと同様のエラーとなり、そこでFAILEDになってた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/98a76012-9363-ce23-ccbe-868f736ff33b.png)
- バッチもしっかりFAILEDだった  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/07a3104f-3832-497d-7495-9371d4e6a36b.png)



# 感想
- ツールに関しては、作った後に気づいてしまったが、[textlint](https://github.com/textlint/textlint)という便利ものもあった……今回のツールはフォーマットのパターン一致チェックをしたかったので、まぁ良いのだが妥当性チェックはtextlintで良い気がした
- ずっとJenkinsおじさんだったので、CircleCIのノリが知れただけでもかなり有意義だった！ サーバ側に設定ファイル（実行shellとか）を置くのに慣れていたので、リポジトリ側に置いとくってのが新鮮だった（GitHub Actionsも同じ感じ？）
- まだまだスタートラインなので、特にCircleCIはもっと色々いじってみたい所存……
- 次はPyPIに公開しても大丈夫な何かが作りたいなー